Compare commits

..
Author SHA1 Message Date
Moonchild 3a4dc8de41 Issue #3020 - Clear currentScript after running microtasks
Per HTML spec:

`document.currentScript` Returns null if the Document is not currently
executing a script or SVG script element (e.g., because the running
script is an event handler, or a timeout), or if the currently executing
script or SVG script element represents a module script.

---

It's ambiguous about whether, for micro tasks, it should return null.
(This section is labelled as "non-normative", as well.)
However, mainstream browsers handle this differently and don't return
null after running microtasks, so we need to clear this and not assume
null persistently, and run the auto-updater for it, regardless if
it's a module or not.
2026-03-24 20:44:13 +01:00
Moonchild 18595b01b6 Issue #3020 - Update currentScript when dealing with shadow DOM.
`currentScript` should be null when evaluating scripts from shadow DOM.
2026-03-24 15:53:04 +01:00
Moonchild f7215fc685 Issue #3020 - document.currentScript should be null in modules
This is done correctly in `EvaluateScript`, but `CreateModuleScript` was
still setting currentScript to an element.
2026-03-24 15:50:34 +01:00
Moonchild 08521d4651 Merge pull request 'Remove Itanium/ia64 support from xpcom' (#3018) from Basilisk-Dev/UXP-contrib:xpcom-itanium-cleanup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3018
2026-03-24 11:18:04 +00:00
Moonchild 00b177d75f Merge pull request 'Fix Shadow DOM spellchecker crash' (#3014) from spellcheck-shadowdom-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3014
2026-03-23 23:48:49 +00:00
Moonchild a89a071049 Merge pull request 'implement TypedArray.prototype.with' (#3019) from Basilisk-Dev/UXP-contrib:typedarray-with into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3019
2026-03-23 15:18:47 +00:00
Basilisk-Dev f9dc8a091a Issue #2551 - implement TypedArray.prototype.with 2026-03-23 08:50:01 -04:00
Basilisk-Dev 944299ed6c Issue #3007 - Remove Itanium/ia64 support from xpcom 2026-03-23 08:15:51 -04:00
Moonchild 0e1441155c Merge pull request 'Issue #3016 - allow url.CanParse to use custom-scheme bases to match current spec' (#3017) from Basilisk-Dev/UXP-contrib:url-canparse-spec-compliance into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3017
2026-03-23 05:23:18 +00:00
Moonchild 7bf5dfe4e4 Merge pull request 'Modify valgrind logging in libavutil to require MOZ_VALGRIND' (#3010) from Basilisk-Dev/UXP-contrib:ffvpx-valgrind into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3010
Reviewed-by: Moonchild <moonchild@palemoon.org>
2026-03-22 21:23:00 +00:00
Basilisk-Dev d4c34fc9f7 Issue #3009 - updated libavutil to keep HAVE_VALGRIND_VALGRIND_H as the primary gate, with MOZ_VALGRIND added inside it 2026-03-22 16:57:34 -04:00
Basilisk-Dev 6811005551 Issue #3016 - allow url.CanParse to use custom-scheme bases to match current spec 2026-03-22 16:48:43 -04:00
Moonchild 464cefa127 Merge pull request 'Attempt to fix Cloudflare image resizing' (#3012) from wuggy/UXP:master into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3012
Reviewed-by: Moonchild <moonchild@palemoon.org>
2026-03-22 14:42:51 +00:00
Moonchild c94a1ab5d3 Merge pull request 'Issue #3007 - remove itanium support and references from webrtc' (#3015) from Basilisk-Dev/UXP-contrib:webrtc-itanium-cleanup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3015
2026-03-22 14:40:10 +00:00
Basilisk-Dev 8aa5b35605 Issue #3007 - remove itanium support and references from webrtc 2026-03-22 01:05:18 -04:00
Basilisk-Dev 25dd1fb31a Issue #3009 - restore valgrind functionality in libavutil and hide behind MOZ_VALGRIND instead 2026-03-21 22:52:25 -04:00
wuggy d8cf2c8b44 Cloudflare Image Resizing fix take 3 part 2 (all.js) 2026-03-21 13:28:57 +00:00
wuggy 938c5d08d4 Cloudflare Image Resizing fix take 3 part 1 (main fixup) 2026-03-21 13:26:34 +00:00
Moonchild 7fca2b8de3 Issue #2739 - Follow-up: remove missed configure bits.
We still accepted {en|dis}able-jxl as a valid old-configure option and
there were a few leftover pref conditionals.
2026-03-21 11:57:15 +01:00
wuggy ef19ad3ffd Cloudflare Image Resizing fix take 2
Better documentation and about:config pref controlled (network.url.cloudflare_image_resizing.enabled)
2026-03-20 19:02:52 +00:00
Moonchild ab88527fe6 Issue #3011 - Part 3: Handle edge case for spellchecking.
Make spellchecking work in Shadow DOM after anchor navigates away from it.
2026-03-20 17:07:55 +01:00
Moonchild 6c0ff1881a Issue #3011 - Part 2: Switch spellchecker root to Shadow DOM.
Set the root for spelling checker to shadow root if the contenteditable
nodes are in the shadow DOM. Bail if the position can't be set properly.
2026-03-20 14:45:11 +01:00
Moonchild 1e7f4c8474 Issue #3011 - Part 1: Add As{Text|Html}Editor() and AsEditorBase()
This adds helper functions to get specific types of content editors (if
possible) through the nsIEditor interface, as opposed to doing manual
casting and the ad hoc `GetHTMLEditor()` function.

Helper functions are spread out over multiple headers due to the
circular dependency issues that would be triggered otherwise.
2026-03-20 13:26:18 +01:00
wuggy fdf491d4ec Cloudflare Image Resizing fix 2026-03-20 10:18:45 +00:00
Basilisk-Dev 1f4cceca43 Issue #3009 - Remove valgrind logging in libavutil so that valgrind is no longer required at build time 2026-03-18 19:44:28 -04:00
Moonchild 542eaca577 Merge pull request 'LoongArch Support Followup - Do not hardcode jemalloc page size on LoongArch' (#3006) from Basilisk-Dev/UXP-contrib:loongarchpagesize into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3006
2026-03-18 23:02:13 +00:00
Basilisk-Dev 1cb6f56418 Issue #2897 followup - Do not hardcode jemalloc page size on LoongArch
Loongarch can run on either a 4k or 16k page size
2026-03-18 18:14:27 -04:00
Moonchild a503e883d9 Merge pull request 'Don't attempt on-stack replacement for TLA modules when interpreter loop encounters JSOP_LOOPENTRY' (#3002) from jobbautista9/UXP:2229-jsop_loopentry into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3002
2026-03-18 15:21:31 +00:00
Moonchild 347681c219 Merge pull request 'Implement array.prototype.toSpliced and array.prototype.with' (#3005) from Basilisk-Dev/UXP-contrib:arraybycopy into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3005
2026-03-17 20:31:34 +00:00
Basilisk-Dev 2984237f4f Issue #2551 - implement array.prototype.toSpliced 2026-03-16 14:33:50 -04:00
Basilisk-Dev 1c4a73de71 Issue #2551 - implement array.prototype.with 2026-03-16 14:27:02 -04:00
Job Bautista d27df4d88f Issue #2229 - Follow-up: Don't attempt on-stack replacement for TLA modules
When interpreter loop encounters JSOP_LOOPENTRY, we should not let TLA modules
enter baseline JIT.
2026-03-16 11:28:25 +08:00
Moonchild 9562888e77 Merge pull request 'Flatten nested CSS to standard CSS before parsing (fix sites using nested CSS)' (#2999) from Basilisk-Dev/UXP-contrib:nested-css into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2999
Reviewed-by: Moonchild <moonchild@palemoon.org>
2026-03-14 18:24:58 +00:00
Moonchild 5536b38401 Merge pull request 'Add AudioNode constructors' (#2988) from audionode-constructors-pr into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2988
2026-03-14 18:19:08 +00:00
Moonchild c011b271a1 Issue #3001 - Restore table reference frame call.
While the result value was only used for debug purposes, the function
`FindReferenceFrameFor` also updates the reference frame for use
outside of debug builds. The opaque double use of this function
was not clear from code inspection and it was erroneously removed.

Resolves #3001
2026-03-14 19:16:41 +01:00
Basilisk-Dev c21fb81d3e Issue #2862 - css nesting pref true by default 2026-03-14 13:23:54 -04:00
Basilisk-Dev 5a3dcf5939 Issue #2862 - Remove unused vars in CSS flattener 2026-03-14 13:22:59 -04:00
Moonchild 1d709fe942 Merge pull request 'Update expat source to 2.7.4 and apply local patches' (#2998) from jobbautista9/UXP:expat-2.7.4 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2998
2026-03-13 17:06:21 +00:00
Moonchild e55c16146f Issue #2993 - Follow-up: Clobber. 2026-03-13 16:19:56 +01:00
Basilisk-Dev 997a9a3e13 Issue #2862 - Change tests from lowering to flattening 2026-03-13 09:01:56 -04:00
Basilisk-Dev 008f38579c Issue #2862 - Change code references from CSS lowering to CSS flattening 2026-03-13 08:58:18 -04:00
Basilisk-Dev d943e86b28 Issue #2862 - handle more edge cases in css lowering 2026-03-12 08:44:03 -04:00
Basilisk-Dev 3f2d707a83 Issue #2862 - more tests files for nested css 2026-03-12 08:43:58 -04:00
Basilisk-Dev b145a93ad6 Issue #2862 - Split the css lowering functionality out to a separate file for easier maintenance 2026-03-12 08:43:53 -04:00
Basilisk-Dev 3056028db4 Issue #2862 - Fix a few nested selectors 2026-03-12 08:43:48 -04:00
Basilisk-Dev b4dac14720 Issue #2862 - Modify the css lowerer so that the lowering pass now recognizes bare type-selector nested rules and combinator-led cases 2026-03-12 08:43:42 -04:00
Basilisk-Dev 76694b956f Issue #2862 - add initial nested css test file 2026-03-12 08:43:33 -04:00
Basilisk-Dev 9fab5b3e3c Issue #2862 - Initial attempt at a css lowering 2026-03-12 08:43:23 -04:00
Job Bautista d54491fdd0 Issue #2997 - Update expat source to 2.7.4 and apply local patches. 2026-03-12 13:50:10 +08:00
Moonchild 00c3c3a546 Merge pull request 'Only use SVE instructions on Apple Silicon (disable on aarch64 Linux)' (#2994) from Basilisk-Dev/UXP-contrib:vpx-sve into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2994
2026-03-11 20:50:08 +00:00
Moonchild 1da5c344be Merge pull request 'Implement TypedArray.prototype.toReversed()' (#2996) from Basilisk-Dev/UXP-contrib:typed-toReversed into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2996
2026-03-11 20:28:21 +00:00
Moonchild 76d66b5dad Merge pull request 'Work around macOS WebGL crash on unconsumed vertex attrib arrays' (#2995) from Basilisk-Dev/UXP-contrib:webgl-crash into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2995
2026-03-11 20:23:20 +00:00
Basilisk-Dev e502735eb2 Issue #2993 - only use SVE instructions on Apple Silicon (disable on aarch64 Linux) 2026-03-11 15:07:09 -04:00
Basilisk-Dev edfebe1b99 Issue #2551 - Implement TypedArray.prototype.toReversed() 2026-03-11 15:04:16 -04:00
Moonchild 250e4f75da Merge pull request 'Avoid empty replacements in macro expansion.' (#2986) from 2978 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2986
2026-03-11 19:03:59 +00:00
Basilisk-Dev 53f1bdd9c2 Issue #2978 - Work around macOS WebGL crash on unconsumed vertex attrib arrays 2026-03-11 14:25:20 -04:00
Moonchild ade298d0a7 Merge pull request 'Issue #2990 - implement object.GroupBy' (#2991) from Basilisk-Dev/UXP-contrib:objectgroupby into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2991
2026-03-10 15:24:08 +00:00
Basilisk-Dev 387b01ce14 Issue #2990 - implement object.GroupBy 2026-03-10 10:45:54 -04:00
Moonchild 47d2094329 Merge pull request 'Issue #2926 - Tweak mimalloc performance tunables' (#2989) from Basilisk-Dev/UXP-contrib:mimalloc-tweaks into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2989
2026-03-10 13:48:48 +00:00
Basilisk-Dev 43f9a8e1f0 Issue #2926 - Tweak mimalloc performance tunables:
MI_DEFAULT_PURGE_DECOMMITS=0 - fewer costly kernel operations and fewer immediate recommit/zero-fill penalties on reuse.

MI_DEFAULT_PURGE_DELAY=500 - short-lived allocation bursts can reuse pages directly, avoiding purge/reclaim ping-pong.

MI_DEFAULT_GENERIC_COLLECT=50000 - lower background allocator housekeeping overhead on hot allocation paths.
2026-03-10 09:08:14 -04:00
Moonchild 30e287371f Issue #2987 - Part 19: Add MediaStreamAudioDestinationNode constructor. 2026-03-10 11:19:11 +01:00
Moonchild a9246d7b28 Issue #2987 - Part 18: Add MediaStreamAudioSourceNode constructor. 2026-03-10 11:19:05 +01:00
Moonchild db1d73f05d Issue #2987 - Part 17: Add MediaElementAudioSourceNode constructor. 2026-03-10 11:18:39 +01:00
Moonchild 72b14ea177 Issue #2987 - Part 16: Add AudioBuffer constructor. 2026-03-10 11:18:02 +01:00
Moonchild 430c4a3f79 Issue #2987 - Part 15: Add PeriodicWave constructor. 2026-03-10 11:17:57 +01:00
Moonchild 93ed92f63b Issue #2987 - Part 14: Add OscillatorNode constructor. 2026-03-10 11:17:53 +01:00
Moonchild 4a1312c060 Issue #2987 - Part 13: Add DynamicsCompressorNode constructor. 2026-03-10 11:17:47 +01:00
Moonchild 303e1ecf34 Issue #2987 - Part 12: Add ChannelMergerNode constructor. 2026-03-10 11:17:42 +01:00
Moonchild 57b0e4a65b Issue #2987 - Part 11: Add ChannelSplitterNode constructor. 2026-03-10 11:17:38 +01:00
Moonchild 804a301068 Issue #2987 - Part 10: Add ConvolverNode constructor. 2026-03-10 11:17:32 +01:00
Moonchild aedb8a4d08 Issue #2987 - Part 9: Add StereoPannerNode constructor. 2026-03-10 11:17:27 +01:00
Moonchild 93072ab51e Issue #2987 - Part 8: Add PannerNode constructor. 2026-03-10 11:17:22 +01:00
Moonchild ca11a325bd Issue #2987 - Part 7: Add WaveShaperNode constructor. 2026-03-10 11:17:17 +01:00
Moonchild 3b088af0b1 Issue #2987 - Part 6: Add IIRFilterNode constructor. 2026-03-10 11:17:12 +01:00
Moonchild 09e52646e9 Issue #2987 - Part 5: Add BiQuadFilterNode constructor. 2026-03-10 11:17:07 +01:00
Moonchild 26ca6f4fcc Issue #2987 - Part 4: Add DelayNode constructor. 2026-03-10 11:17:02 +01:00
Moonchild b467d710ac Issue #2987 - Part 3: Add GainNode constructor. 2026-03-10 11:16:56 +01:00
Moonchild f4f11fada8 Issue #2987 - Part 2: Add AudioBufferSourceNode constructor. 2026-03-10 11:16:49 +01:00
Moonchild 43b3b47426 Issue #2987 - Part 1: Add AnalyserNode constructor. 2026-03-10 11:16:43 +01:00
Moonchild 77f8cae06e Issue #2978 - Avoid empty replacements in macro expansion.
If the replacements array is empty, don't attempt to do any work on the
existing macro, and return. This should prevent infinite recursion in
some cases.
Order matters here: we're relying on the `if` statement shortcut so
`collectMacroArgs()` doesn't get called.
2026-03-09 16:04:57 +01:00
Moonchild daa31cfd59 No issue - Fix some fatal printing assertions.
- Turn a fatal assert into a warning if we can't guarantee a drawTarget.
  This should not be fatal since the DrawTarget is checked later.
- Remove a fatal assertion if a display table background is cross-document
  since non-display iframes may cause this situation without it being an
  error.
2026-03-09 11:30:38 +01:00
Moonchild b4ad4b7293 Issue #2981 - Add nullcheck in GetPointerCapabilities
Resolves #2981
2026-03-09 11:27:25 +01:00
Moonchild a2947909e8 Merge pull request 'Issue #2982 - Implement oklab/oklch' (#2983) from Basilisk-Dev/UXP-contrib:oklab-oklch into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2983
2026-03-08 07:27:26 +00:00
Moonchild bc2d0521e7 Merge pull request 'Implement ES2022 error.cause property' (#2984) from dbsoft/UXP:error-cause-2304 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2984
2026-03-07 21:17:22 +00:00
Moonchild 95ca42dd06 Merge pull request 'Handle special cases for certain MacOS system fonts.' (#2985) from dbsoft/UXP:mac-variation-fonts into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2985
2026-03-07 21:00:44 +00:00
Brian Smith 0c0dfca015 Issue #2304 - Part 5 - Add cause property when a cause is present.
I thought this was just to check whether it should be added, but is necessary.
2026-03-07 01:41:07 -06:00
Brian Smith 17cd2e4d07 Issue #2304 - Part 4 - Add xray support for the Error cause property.
https://bugzilla.mozilla.org/show_bug.cgi?id=1679653
2026-03-07 01:17:18 -06:00
Brian Smith f305547835 Issue #2304 - Part 3 - Implement the error cause proposal.
https://bugzilla.mozilla.org/show_bug.cgi?id=1679653
2026-03-07 00:41:42 -06:00
Brian Smith 5ee86104a8 Issue #2304 - Part 2 - Prerequisite: Teach GCPolicy about Maybe.
https://bugzilla.mozilla.org/show_bug.cgi?id=1377008
2026-03-06 23:47:55 -06:00
Basilisk-Dev 0ab247bee9 Issue #2982 - Fix regressions in the previous regression fix commit. 2026-03-06 16:27:12 -05:00
Basilisk-Dev 5370edc560 Issue #2982 - Fix regression in previous commit by handling possible floating point issues 2026-03-06 16:27:12 -05:00
Basilisk-Dev f27b6cbd21 Issue #2982 - clamp oklab/oklch to [0,1] before conversion to closer match spec 2026-03-06 16:27:12 -05:00
Basilisk-Dev de3485ed67 Issue #2982 - Make gradients work in oklch 2026-03-06 16:27:12 -05:00
Basilisk-Dev 7f8489bc11 Issue #2982 - Initial oklch test implementation 2026-03-06 16:27:07 -05:00
Brian Smith 8c1cf4cc02 Issue #2304 - Part 1 - Prerequisite: Make Handle<Maybe<>> more convenient.
This is required to implement JS::NothingHandleValue.
https://bugzilla.mozilla.org/show_bug.cgi?id=1631114
2026-03-06 13:13:21 -06:00
Moonchild b8fbac6365 Merge pull request 'Futureproof Internal ICU Whitespace' (#2980) from RealityRipple/UXP:alt-space-ex into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2980
2026-03-06 12:53:00 +00:00
Andy c7cc4ef650 Support All White Spaces in ICU Replacement from PR #2921
In case Unicode adds additional alternate spaces to formats in the future, the wsCompat argument will be ready.
I also switched over to the `u_isUWhiteSpace` alias, which is functionally identical to `UCHAR_WHITE_SPACE` at present, just in case the alias ever expands beyond the const.
2026-03-06 03:36:27 -08:00
Moonchild 9d1789b62f Merge pull request 'Stop exposing plugin preferences if support isn't built' (#2975) from 2879 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2975
2026-03-06 09:52:50 +00:00
Moonchild 9a1c99e1a2 Issue #2879 - Stop exposing additional prefs
This stops exposing some additional preferences that are NPAPI-only.
2026-03-06 09:44:41 +01:00
Moonchild abc435f18e Merge pull request 'Futureproof ParseDate Whitespace' (#2979) from RealityRipple/UXP:alt-space into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2979
2026-03-06 08:38:44 +00:00
Andy 2e6dab8672 Support Unicode White Spaces in ParseDate() 2026-03-05 17:32:10 -08:00
Moonchild e0b95b12da Merge pull request 'Implement ES2018 Proxy ownKeys duplicate-key invariant and update affected conformance tests.' (#2977) from Basilisk-Dev/UXP-contrib:es2018-proxy-updates into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2977
2026-03-04 17:19:08 +00:00
Basilisk-Dev 722ecd0d97 Issue #2976 - Implement ES2018 Proxy ownKeys duplicate-key invariant and update affected conformance tests. 2026-03-04 10:37:58 -05:00
Moonchild e72cc38641 Issue #2879 - Remove obsolete crash reporter prefs. 2026-03-04 15:31:41 +01:00
Moonchild ae227b8743 Issue #2879 - Do not expose plugin-specific prefs if support isn't built.
- Puts prefs behind conditional defines
- Removes obsolete plugin finder pref
- Removes obsolete unrestricted xpconnect plugin pref
2026-03-04 14:54:13 +01:00
Moonchild a268e57967 Merge pull request 'Issue #2957 - make WeakRefObject finalize on main thread (no background finalize)' (#2973) from Basilisk-Dev/UXP-contrib:weakref-crash into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2973
2026-03-04 11:11:57 +00:00
Moonchild 9f05dad78c Merge pull request 'Fix clang builds on 32-bit ARM Linux.' (#2972) from dbsoft/UXP:clang-arm-linux into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2972
2026-03-04 11:10:57 +00:00
Basilisk-Dev ba0112d574 Issue #2957 - make WeakRefObject finalize on main thread (no background finalize) 2026-03-02 00:01:39 -05:00
Moonchild 5b449bc031 Merge pull request 'Issue #2551 - toSorted followup to be 100% ECMA compliant' (#2971) from Basilisk-Dev/UXP-contrib:toSortedSpec into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2971
2026-03-01 21:54:23 +00:00
Basilisk-Dev b823c130c1 Issue #2551 - toSorted followup to be 100% ECMA compliant 2026-03-01 16:33:09 -05:00
Moonchild 437d9da605 Merge pull request 'Implement ES2023 array.Prototype.toReversed()' (#2970) from Basilisk-Dev/UXP-contrib:toReversed into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2970
2026-03-01 19:07:21 +00:00
Basilisk-Dev f49a57006f Issue #2551 - Implement ES2023 array.Prototype.toReversed() 2026-02-28 16:34:04 -05:00
Brian Smith 18096194f5 No Issue - Fix clang builds on 32-bit ARM Linux.
The clang integrated assembler can't handle these files.
2026-02-28 11:45:35 +00:00
Job Bautista 8ca0f22841 Issue #2903 - Follow-up: Make types consistent with method used.
Fixes inconsistent use of XML_Error, uint32_t and int32_t.
2026-02-27 18:48:06 +01:00
Brian Smith b4e9888d91 No Issue - Handle special cases for MacOS system fonts.
Work done by Jazzzny based on the following bugs:
https://bugzilla.mozilla.org/show_bug.cgi?id=1321031
https://bugzilla.mozilla.org/show_bug.cgi?id=1349308
Example page:
http://codepen.io/dangayle/pen/RpMVqY
2026-02-26 19:14:46 -06:00
Moonchild 30b01396b4 Merge pull request 'Update libtheora to 1.2.0' (#2966) from jobbautista9/UXP:theora-1.2.0 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2966
2026-02-26 21:29:17 +00:00
Moonchild 9343129fbb Merge pull request 'Follow up to address libvpx issues on older MacOS and PowerPC platforms.' (#2969) from dbsoft/UXP:libvpx-mac-fixes into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2969
2026-02-26 20:34:19 +00:00
Moonchild e79ddda9de No issue - Fix build issue.
Unified build deprot on some targets causing issues with the recently
added `mozilla:KnownNotNull` without this header.
2026-02-26 20:15:45 +01:00
Moonchild f84c92881d [parser] Account for some corner-case structural document issues. 2026-02-26 09:48:23 +01:00
Moonchild aeafa7fef8 [MFBT] Reduce size() calls in subspan. 2026-02-26 08:21:45 +01:00
Moonchild ff3db332fe [libjar] Throw when we know a file was truncated. 2026-02-26 07:51:57 +01:00
Brian Smith 68d53612af Issue #2925 - Follow-up: Fix Mac Intel and PowerPC 10.5-10.11 builds.
clock_gettime() is not available prior to 10.12, so use Mach's clock_get_time().
pthread_setname_np() is not available prior to MacOS 10.6, so guard that.
libvpx does not support big endian, so only use VPX acceleration on ppc64le.
2026-02-25 23:35:33 -06:00
Moonchild 0fb9b4abbf [WebAudio] Gracefully handle mid-stream audio changes. 2026-02-26 00:03:19 +01:00
Moonchild ab442f72b9 Merge pull request 'Issue #2925 followup 2 - Restore previous GlobalFree behavior from before SCTP upgrade in sctp_bsd_addr.c' (#2968) from Basilisk-Dev/UXP-contrib:sctp-followup-2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2968
2026-02-25 19:49:05 +00:00
Moonchild b85d16b615 [WebRTC] Ensure valid image size.
Extremely small encoded image sizes should be considered corrupt data.
Drive-by improvement: make sure to cast the encoded image data length
to uint32_t for use with `CreateEmptyFrame`
2026-02-25 20:01:52 +01:00
Moonchild cc7d9550bc No issue - Modernize nsWindowWatcher
Get rid of old hacky conditional code and use weak references.
2026-02-25 18:48:56 +01:00
Basilisk-Dev bc2d2edbef Issue #2925 followup 2 - Restore previous GlobalFree behavior from before SCTP upgrade in sctp_bsd_addr.c 2026-02-25 12:29:13 -05:00
Moonchild bc5c6c7563 [WASM] Make sure to assign module 2026-02-25 17:13:33 +01:00
Moonchild 0d971f0c5a [WASM] Improve WasmModuleObject handling in WasmJS.cpp 2026-02-25 16:45:20 +01:00
Moonchild 99d225ae7f Merge pull request 'Issue #2925 followup - Fix intermittent Windows crashes after SCTP upgrade' (#2967) from Basilisk-Dev/UXP-contrib:2925-sctp-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2967
2026-02-25 13:59:07 +00:00
Moonchild 4bb7951324 No issue - Don't assign non-live hash table entry.
The problem here is that we use move assignment on a hash table entry that
is not live. Although all entries are constructed by
`HashTable::createTable`, they may subsequently be destroyed by
`HashTableEntry::destroyStoredT()`.

Therefore it is not safe to call any methods on a non live entry.
This causes a problem for GC barrier wrappers which assume that the object
state is valid (and presumably anything that does more than just write the
assigned data into memory).

The fix is to construct a new entry in-place.

Based on work by Jon Coppeard <jcoppeard@mozilla.com> in Bug 2009608
2026-02-25 14:53:42 +01:00
Basilisk-Dev 20c29f74b4 Issue #2925 followup - Fix intermittent Windows crashes after SCTP upgrade 2026-02-25 08:30:18 -05:00
Job Bautista d9a4414ef0 Issue #2965 - Update libtheora to 1.2.0. 2026-02-25 20:55:00 +08:00
Moonchild 56be1ceaef Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2026-02-24 20:28:44 +01:00
Moonchild fd0ddefa03 Merge pull request 'Issue #2925 - Uprade libvpx to 1.16.0' (#2963) from Basilisk-Dev/UXP-contrib:libvpx-upgrade into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2963
2026-02-24 19:27:39 +00:00
Brad Werth 00e3d12e1d [gfx] Use gzip stream total_out for SVG document parsing.
With this change, the assert is no longer necessary, because the stream
tells us how many elements to process.
2026-02-24 19:15:41 +01:00
Basilisk-Dev 3a81d02c0f Issue #2925 - Fix Windows x64 2026-02-24 09:34:18 -05:00
Basilisk-Dev 5fbb929250 Issue #2925 - Work around x86 bug in libvpx 2026-02-24 09:33:16 -05:00
Moonchild 4cb28647fe Merge pull request 'Text Cluster Optimization' (#2962) from RealityRipple/UXP:better-grapheme into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2962
2026-02-24 09:45:51 +00:00
Basilisk-Dev 002240592a Issue #2925 - Upgrade libvpx to 1.16.0 2026-02-23 16:10:38 -05:00
Andy 8f95d938d5 Optimize ClusterIterator::Next
This is based on BZ 1820504, which notes that running `GetEmojiPresentation()` before checking `prevWasZwj` adds load time to all text, as opposed to more efficiently making `prevWasZwj` the precursor to categorizing the character.
The original patch uses an enum for `baseIsEmojiStatus`; I figured I'd simplify things with numeric values (0 = unset, 1 = yes, 2 = no).
2026-02-23 11:02:02 -08:00
Moonchild c66294c51a Merge pull request 'Issue #2925 - Upgrade usrsctp library to latest version' (#2948) from Basilisk-Dev/UXP-contrib:sctp-upgrade into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2948
2026-02-22 15:50:40 +00:00
Moonchild abc96cf444 No issue - Fix cairo warnings
This fixes warning spew because warnings are thrown in case of mixed use
of cairo_status_t and cairo_int_status_t, which is a hack in cairo
because C99 doesn't support real enums (it's mapped to uint8 internally).
The "register" storage type is no longer a thing in C++17, which would
also warn; just letting the compiler decide is best, so just removing
the keyword is the proper solution in cairoint.h
2026-02-22 14:20:37 +01:00
Moonchild a3019dddc1 Merge pull request 'Implement HTMLFormElement.requestSubmit(element)' (#2956) from 2955 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2956
2026-02-22 09:46:55 +00:00
Moonchild bd03f965a3 Issue #186 - Follow-up: Remove AIX references from moz.build.
This should not be kept around because AIX is not a valid OS_TARGET.
2026-02-22 07:06:12 +01:00
Moonchild 358d39d4bf Merge pull request 'Remove remaining AIX specific code' (#2960) from 186 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2960
2026-02-22 05:59:51 +00:00
Moonchild 77571794a3 Merge pull request 'Remove iOS support' (#2959) from 190 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2959
2026-02-22 05:58:29 +00:00
Jeremy Andrews a935ef810c Issue #186 - Remove AIX references from moz.build.
This should not be kept around because AIX is not a valid OS_TARGET and I've seen mach fail at least once because of these. Meant to clean them up years ago.
2026-02-21 15:43:48 -06:00
Moonchild eb731d1377 Issue #186 - Remove various AIX leftovers in 1st party code. 2026-02-21 21:30:08 +01:00
Moonchild c275325fbf Issue #186 - Remove an ancient workaround for AIX.
This was missed before in a rather typical "do it 3/4 of the way" fashion.
2026-02-21 21:11:38 +01:00
Moonchild 84da3d4817 Issue #190 - Fix incorrectly applied patch.
For some reason the rebase removed the endif in the wrong place...
2026-02-21 19:23:42 +01:00
Jeremy Andrews c868ea1f58 Issue #190 - Remove MOZ_IOS conditional code and ios.m4 2026-02-21 18:58:35 +01:00
Jeremy Andrews d5e385dc73 Issue #190 - Remove UIKit conditional code. 2026-02-21 18:55:44 +01:00
Moonchild d49758ace1 Issue #2955 - Implement form.requestSubmit(element) 2026-02-20 09:57:46 +01:00
Moonchild f3ee6e294f Merge pull request 'Ensure decoding the first frame of a video always succeeds' (#2954) from jobbautista9/UXP:mFirstFrameTime into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2954
Reviewed-by: Moonchild <moonchild@palemoon.org>
2026-02-19 16:54:03 +00:00
Job Bautista dea96fe9d3 Issue #2949 - Part 2 Follow-up: Check if first frame has been decoded for software fallback.
Now that we can check if the first frame has been decoded thanks to Issue #2953
we should ensure that the first frame actually has not been decoded before
checking if the media errored out.
2026-02-20 00:23:31 +08:00
Job Bautista 29a5e8df12 Issue #2953 - Part 4: Don't attempt to skip to next keyframe if there are none.
Demuxers don't typically return an error when they don't have a future
keyframe, they return infinity.
2026-02-20 00:23:27 +08:00
Job Bautista 51941fd085 Issue #2953 - Part 3: Assert that no error can occur while an internal seek is pending.
An internal seek occurs when we've reached a data gap, EOS or a previous error got skipped.

During this time, the decoder has been either flushed or shut down.
2026-02-20 00:23:21 +08:00
Job Bautista 64ea5dd93a Issue #2953 - Part 2: Don't attempt to continue decoding if no next keyframe.
When we have no future keyframe and an error occurred, we can't skip over
anything and we shouldn't try to simply decode the next video frame; so we
abort early.
2026-02-20 00:23:15 +08:00
Job Bautista a42d420ee5 Issue #2953 - Part 1: Attempt to decode the first frame again if error occurred. 2026-02-20 00:23:00 +08:00
Basilisk-Dev 060995dfff Issue #2925 - Incorporate FreeBSD patch from dbsoft after usrsctp upgrade 2026-02-19 07:46:37 -05:00
Moonchild 991bd7b460 Merge pull request 'Update libjxl to 0.11.2 for security fixes and spot fix for Big Endian issue.' (#2951) from dbsoft/UXP:jxl-updates into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2951
2026-02-19 12:00:19 +00:00
Moonchild db503078d0 Merge pull request 'Allow fallback to software decoding when WMF VP9 hardware decoding fails' (#2950) from jobbautista9/UXP:wmf-vp9-blank-hwa-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2950
2026-02-19 08:42:52 +00:00
Job Bautista 8ee58d2591 Issue #2949 - Part 4: Don't attempt to use WMF VP9 decoder for profiles 1 and 3.
The Windows VP9 hardware decoder currently does not support anything else than
profiles 0 and 2 (YUV420) and return garbage when decoding.

We error on those streams allowing to fall back on the ffvp9 software decoder.
2026-02-19 14:31:47 +08:00
Job Bautista c340a1dcd2 Issue #2949 - Part 3: Add method to read a VP9 profile from a VP9 bitstream
We haven't moved BitReader out of stagefright yet (BZ 1417011), but the reader
there works.
2026-02-19 14:27:10 +08:00
Job Bautista 774a6aa4dd Issue #2949 - Part 2: When hardware decoding fails, fall back to software
Unlike the original patch we don't have the infrastructure provided by Mozilla
BZ 1363668 yet to determine if we've decoded the first frame. This is not
required for checking whether we've errored out on hardware decoding though.
2026-02-19 14:22:39 +08:00
Job Bautista b2566429fc Issue #2949 - Part 1: Add option to disable hardware decoding. 2026-02-19 14:20:23 +08:00
Basilisk-Dev f66bcb4f23 Issue #2925 - Upgrade usrsctp library to latest version 2026-02-18 18:34:59 -05:00
Brian Smith 0e7430735e Issue #2697 & #2051 - Follow-up: Spot fix a JPEG-XL big endian issue.
Rewrote the patch from the main branch because it requires newer Highway versions.
Original patch needs Highway Endian and ARM64 MulOdd() Vec128<int32_t> support.
2026-02-18 17:08:33 -06:00
Brian Smith 905c7e8785 Issue #2697 - Follow-up: Update libjxl to 0.11.2 for security updates.
Fix tile dimension in low memory rendering pipeline.
CVE-2025-12474 - https://www.cve.org/cverecord?id=CVE-2025-12474
Fix number of channels for gray-to-gray color transform.
CVE-2026-1837 - https://www.cve.org/cverecord?id=CVE-2026-1837
And one security fix without a CVE.
2026-02-18 15:33:19 -06:00
Moonchild 9d91a43142 Merge pull request 'Fix WMF hardware decoding for VP9 and enable it by default' (#2947) from jobbautista9/UXP:wmf-vp9-videomft-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2947
2026-02-17 08:23:02 +00:00
Job Bautista 53bac56f36 Issue #2946 - Enable WMF VP9 decoder by default. 2026-02-17 16:07:14 +08:00
Job Bautista e85fff2f10 Issue #2946 - Override sample duration if unknown.
Based on Mozilla bug 1371290's part 2.

The VP9 decoder doesn't properly set the sample duration, leading to all
samples being marked as having a zero duration. The compositor drops those
frames incorrectly.
2026-02-17 16:03:44 +08:00
Moonchild 839236c912 Merge pull request 'Manual Tibetan Word Wrap' (#2945) from RealityRipple/UXP:tibetan-wrap into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2945
Reviewed-by: Moonchild <moonchild@palemoon.org>
2026-02-17 07:57:34 +00:00
Moonchild 1e3fddbe14 Merge pull request 'Add Special Lithuanian Casing' (#2943) from RealityRipple/UXP:lithuanian-1322992 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2943
2026-02-17 07:56:04 +00:00
Andy b5576d1485 Remove Android from Mozilla Import 2026-02-16 14:55:34 -08:00
Andy 524b466197 Nit: Drop clang-format 2026-02-16 14:49:47 -08:00
Moonchild 7d1b245754 Merge pull request 'CLDR Pluralities' (#2944) from RealityRipple/UXP:plural-forms into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2944
Reviewed-by: Moonchild <moonchild@palemoon.org>
2026-02-16 22:31:37 +00:00
Andy 64a0846a1c Add Manual Tibetan Line Breaking
https://bugzilla.mozilla.org/show_bug.cgi?id=1647377
and
https://bugzilla.mozilla.org/show_bug.cgi?id=1736393
2026-02-16 12:57:03 -08:00
Andy 118bd414d4 Add Special Lithuanian Casing
https://bugzilla.mozilla.org/show_bug.cgi?id=1322992
2026-02-16 11:10:31 -08:00
Andy 3f319c5f29 Update CLDR Plural Forms
Move Macedonian to 15 - https://bugzilla.mozilla.org/show_bug.cgi?id=1415906
Add Shuar (17) - https://bugzilla.mozilla.org/show_bug.cgi?id=1396724
Add Welsh (18) - https://bugzilla.mozilla.org/show_bug.cgi?id=1428366
Add Slavic (19) - https://bugzilla.mozilla.org/show_bug.cgi?id=1533435
2026-02-16 00:58:32 -08:00
Jazzzny 8b06eaa8fc Issue #2051 - Follow-up: Reverse filter channel order on big-endian. 2026-02-15 17:58:31 +01:00
Moonchild e62bd7c533 Merge pull request 'Fix for runtime problems with Pale Moon and others on FreeBSD 15.' (#2942) from dbsoft/UXP:freebsd15-rpath-fix3 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2942
2026-02-14 19:58:49 +00:00
Brian Smith 0839a82f80 Issue Pale-Moon#2009 - Add $ORIGIN to the runtime path on FreeBSD.
Following what we do on Solaris, add $ORIGIN using MOZ_FIX_LINK_PATHS.
Also change the mode to copy from symbolic links so it finds the libs.
2026-02-14 11:40:45 -06:00
Moonchild 4cbaf927d9 Bump goanna version 2026-02-14 12:14:29 +01:00
Moonchild b4f364c385 Merge pull request 'Issue #2229 - Fix assertions in top-level await on x86_64' (#2941) from Basilisk-Dev/UXP-contrib:2229-x86-assert-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2941
2026-02-13 14:50:21 +00:00
Basilisk-Dev 6ede629146 Issue #2229 - Fix assertions in top-level await on x86_64 2026-02-13 09:06:59 -05:00
Moonchild c684599599 Merge pull request 'Restore MacOS 10.6 32-bit support, WebRTC support on 10.5 and other (Snow) Leopard fixes.' (#2940) from dbsoft/UXP:mac-leopard-fixes2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2940
2026-02-13 11:15:22 +00:00
Moonchild c9bfd79ae0 Merge pull request 'Issue #2229 - Fix debug builds when visiting pages that utilize top-level await' (#2939) from Basilisk-Dev/UXP-contrib:2229-fix-debug into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2939
2026-02-12 19:52:44 +00:00
Basilisk-Dev 6d3f71d200 Issue #2229 - Fix debug builds when visiting pages that utilize top-level await
Fix JSOP_AWAIT stack modeling for top‑level await in modules.
Ensure yield/await offsets are emitted for TLA scripts.
Allow interpreter prologue for resumed TLA module frames.
Fix MediaQueryList invariant for onchange handler.
2026-02-12 14:38:25 -05:00
Brian Smith 620e391be7 Issue #1829 - Follow-up Part 8: Add a pref to enable the resize grip/thumb.
MacOS prior to Lion 10.7 had an area in the bottom right of the window used for resizing.
With the resize indicator enabled, a grip or thumb is drawn in the corner over the contents.
This may or may not be desirable based on the application. So this preference allows the
application to choose the default which the user can override in about:config using the pref:
ui.mouse.resize_grip
2026-02-11 23:58:12 -06:00
Brian Smith 532a1355ce Issue #1829 - Follow-up Part 7: Restore support for scrollbar arrows on Leopard and Snow Leopard. 2026-02-11 18:02:20 -06:00
Brian Smith 03367d9c41 Issue #2051 - Follow-up Part 3: Fix ycbcr display issues on Big Endian. 2026-02-11 15:35:55 -06:00
Brian Smith 6ebd205c8e Issue #1829 - Follow-up Part 6: Fix font recursion problems on Leopard and Snow Leopard. 2026-02-11 15:35:55 -06:00
Brian Smith 7276ea00a7 Issue #1829 - Follow-up Part 5b: Remove Radeon X1000 from the block list.
This is reported working.
2026-02-11 15:35:55 -06:00
Brian Smith 7a5c56bc58 Issue #1829 - Follow-up Part 5a: Add Getforce FX to the MacOS block list. 2026-02-11 15:35:55 -06:00
Brian Smith 9e064c7045 Issue #1829 - Follow-up Part 5: Update driver blocklist handling for Leopard.
Disable WebGL on 10.5.
2026-02-11 15:35:55 -06:00
Brian Smith 6933bfe783 Issue #1829 - Follow-up Part 4: Restore draw in titlebar support for Leopard. 2026-02-11 15:35:55 -06:00
Brian Smith 5e81fb065a Issue #1829 - Follow-up Part 3: Restore WebRTC support for Leopard.
Restore QTKit based video capture for 10.5 which does not have AVFoundation.
Add -fpermissive to CXXFLAGS in the build system for Mac 32-bit PowerPC.
This works around a type issue with Atomic32 and AtomicWord.
These two types should be interchangeable.
2026-02-11 15:35:54 -06:00
Brian Smith f08b4276ea Issue #1829 - Follow-up Part 2: Restore 32-bit Intel Mac builds.
Add ffvpx configuration for 32-bit Intel Mac.
Replace PPC checks with 10.5 or 10.6 checks.
2026-02-11 15:11:10 -06:00
Brian Smith 45d7dda330 Issue #1829 - Follow-up Part 1: Restore MacOS 10.6 support.
Also update Leopard and Snow Leopard scrollbar handling.
Fixes menu icon scaling.
Hide the resize thumb on Leopard and Snow Leopard so it looks the same as Lion.
Fixes from Jazzzny.
2026-02-11 15:11:10 -06:00
Moonchild a8f1878ff3 Merge pull request 'Issue #2229 Followup - Handle re-entrant module instantiation/evaluation during async module loads' (#2938) from Basilisk-Dev/UXP-contrib:2229-top-level-await-followup into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2938
2026-02-11 16:30:22 +00:00
Basilisk-Dev d0ec80aa86 Issue #2229 Followup - Handle re-entrant module instantiation/evaluation during async module loads 2026-02-11 09:46:46 -05:00
Moonchild a9257dea7d Merge pull request 'Implement pointer and hover @media queries' (#2935) from pointer-hover-mediaqueries into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2935
2026-02-10 21:19:31 +00:00
Moonchild af5d12a154 Merge pull request 'Implement top level await functionality' (#2937) from Basilisk-Dev/UXP-contrib:2229-top-level-await into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2937
2026-02-10 21:17:11 +00:00
Basilisk-Dev fb4ebd7838 Issue #2229 - Add top level await tests 2026-02-10 14:59:26 -05:00
Basilisk-Dev 7ace23060a Issue #2229 - Add comment regarding JIT to top level await code 2026-02-10 14:59:26 -05:00
Basilisk-Dev 19504eed91 Issue #2229 - add better comments on top level await code 2026-02-10 14:59:26 -05:00
Basilisk-Dev 7c72b41e2c Issue #2229 - Initial implementation of top level await functionality 2026-02-10 14:59:04 -05:00
Moonchild 6fc971d8c0 Issue #2909 - Fix build issues when targeting Windows 7.
Despite Windows 7 supporting Tablet Mode and screen orientation just fine
(I had a Win 7 tablet PC back when), Microsoft decided that starting with
the Windows SDK 10.0.22621.0, the enum and types for auto-rotation should
no longer be defined, so we have to define them ourselves.
2026-02-07 13:27:39 +01:00
Moonchild a410f9e553 Issue #2909 - Base implementation of media interaction features.
This implements `hover`, `pointer`, `any-hover` and `any-pointer` and
the values `course`/`fine` (pointer) and `hover`.
A best effort is made to get capabilities from the system but if unknown
always falls back to assuming a mouse is present.
2026-02-07 13:24:34 +01:00
2737 changed files with 338513 additions and 211291 deletions

No files matched your search

+1 -1
View File
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber for ICU 78.1
Clobber for libvpx changes
+1 -1
View File
@@ -112,5 +112,5 @@ function shutdownPromise(contentBrowser) {
*/
function forceGC() {
Cu.forceCC();
Cu.forceShrinkingGC();
Cu.forceGC();
}
-1
View File
@@ -127,7 +127,6 @@ def old_configure_options(*options):
'--enable-alsa',
'--enable-appcompat-guid',
'--enable-av1',
'--enable-jxl',
'--enable-b2g-bt',
'--enable-b2g-camera',
'--enable-b2g-ril',
-5
View File
@@ -33,12 +33,7 @@ EXPORTS.mozilla = [
]
SOURCES += [
# Compile this separately since nsExceptionHandler.h conflicts
# with something from nsNullPrincipal.cpp.
'BasePrincipal.cpp',
]
UNIFIED_SOURCES += [
'DomainPolicy.cpp',
'nsJSPrincipals.cpp',
'nsNullPrincipal.cpp',
+1 -1
View File
@@ -16,7 +16,7 @@ EXPORTS.mozilla.chrome += [
'RegistryMessageUtils.h',
]
UNIFIED_SOURCES += [
SOURCES += [
'nsChromeProtocolHandler.cpp',
'nsChromeRegistry.cpp',
'nsChromeRegistryChrome.cpp',
+1 -1
View File
@@ -8,4 +8,4 @@
# Referenced by milestone.py.
#--------------------------------------------------------
6.8.0
6.8.1
-4
View File
@@ -348,11 +348,7 @@ ifdef SHARED_LIBRARY
ifdef IS_COMPONENT
EXTRA_DSO_LDOPTS += -bundle
else
ifdef MOZ_IOS
_LOADER_PATH := @rpath
else
_LOADER_PATH := @executable_path
endif
EXTRA_DSO_LDOPTS += -dynamiclib -install_name $(_LOADER_PATH)/$(SHARED_LIBRARY) -compatibility_version 1 -current_version 1 -single_module
endif
endif
@@ -130,6 +130,7 @@ marker.gcreason.label.DOM_WORKER=Periodic Worker GC
marker.gcreason.label.INTER_SLICE_GC=Periodic Incremental GC Slice
marker.gcreason.label.FULL_GC_TIMER=Periodic Full GC
marker.gcreason.label.SHUTDOWN_CC=Shutdown
marker.gcreason.label.FINISH_LARGE_EVALUATE=Large Eval
marker.gcreason.label.DOM_WINDOW_UTILS=User Inactive
marker.gcreason.label.USER_INACTIVE=User Inactive
@@ -168,5 +169,6 @@ marker.gcreason.description.DOM_WORKER=The worker was idle for a relatively long
marker.gcreason.description.INTER_SLICE_GC=There has been a relatively long time since the last incremental GC slice.
marker.gcreason.description.FULL_GC_TIMER=JavaScript returned to the event loop, and it has been a relatively long time since we performed a garbage collection.
marker.gcreason.description.SHUTDOWN_CC=The browser destroyed a JavaScript runtime or context, and this was the final garbage collection before shutting down.
marker.gcreason.description.FINISH_LARGE_EVALUATE=The browser finished evaluating a large script, and performed a GC because the script will never be run again.
marker.gcreason.description.DOM_WINDOW_UTILS=The user was inactive for a long time. Took the opportunity to perform GC when it was unlikely to be noticed.
marker.gcreason.description.USER_INACTIVE=The user was inactive for a long time. The browser took the opportunity to perform GC when it was unlikely to be noticed.
+2 -2
View File
@@ -1113,9 +1113,9 @@ Animation::ResumeAt(const TimeDuration& aReadyTime)
// but it's currently not necessary.
MOZ_ASSERT(mPendingState == PendingState::PlayPending,
"Expected to resume a play-pending animation");
MOZ_ASSERT(!mHoldTime.IsNull() || !mStartTime.IsNull(),
MOZ_ASSERT(mHoldTime.IsNull() != mStartTime.IsNull(),
"An animation in the play-pending state should have either a"
" resolved hold time or resolved start time");
" resolved hold time or resolved start time (but not both)");
// If we aborted a pending pause operation we will already have a start time
// we should use. In all other cases, we resolve it from the ready time.
+9 -6
View File
@@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -36,12 +35,16 @@ NS_INTERFACE_MAP_END
void
AnimationTimeline::NotifyAnimationUpdated(Animation& aAnimation)
{
if (mAnimations.EnsureInserted(&aAnimation)) {
if (aAnimation.GetTimeline() && aAnimation.GetTimeline() != this) {
aAnimation.GetTimeline()->RemoveAnimation(&aAnimation);
}
mAnimationOrder.insertBack(&aAnimation);
if (mAnimations.Contains(&aAnimation)) {
return;
}
if (aAnimation.GetTimeline() && aAnimation.GetTimeline() != this) {
aAnimation.GetTimeline()->RemoveAnimation(&aAnimation);
}
mAnimations.PutEntry(&aAnimation);
mAnimationOrder.insertBack(&aAnimation);
}
void
+3 -1
View File
@@ -185,7 +185,9 @@ EffectCompositor::RequestRestyle(dom::Element* aElement,
PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
if (aRestyleType == RestyleType::Throttled) {
elementsToRestyle.LookupForAdd(key).OrInsert([]() { return false; });
if (!elementsToRestyle.Contains(key)) {
elementsToRestyle.Put(key, false);
}
mPresContext->Document()->SetNeedStyleFlush();
} else {
// Get() returns 0 if the element is not found. It will also return
+4 -2
View File
@@ -150,20 +150,22 @@ EffectSet::GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType)
void
EffectSet::AddEffect(dom::KeyframeEffectReadOnly& aEffect)
{
if (!mEffects.EnsureInserted(&aEffect)) {
if (mEffects.Contains(&aEffect)) {
return;
}
mEffects.PutEntry(&aEffect);
MarkCascadeNeedsUpdate();
}
void
EffectSet::RemoveEffect(dom::KeyframeEffectReadOnly& aEffect)
{
if (!mEffects.EnsureRemoved(&aEffect)) {
if (!mEffects.Contains(&aEffect)) {
return;
}
mEffects.RemoveEntry(&aEffect);
MarkCascadeNeedsUpdate();
}
+1 -1
View File
@@ -277,7 +277,7 @@ Attr::GetBaseURI(bool aTryUseXHRDocBaseURI) const
void
Attr::GetTextContentInternal(nsAString& aTextContent,
OOMReporter& aError)
ErrorResult& aError)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eTextContent);
+1 -1
View File
@@ -43,7 +43,7 @@ public:
// nsIDOMNode interface
NS_FORWARD_NSIDOMNODE_TO_NSINODE
virtual void GetTextContentInternal(nsAString& aTextContent,
OOMReporter& aError) override;
ErrorResult& aError) override;
virtual void SetTextContentInternal(const nsAString& aTextContent,
ErrorResult& aError) override;
virtual void GetNodeValueInternal(nsAString& aNodeValue) override;
+5 -9
View File
@@ -592,10 +592,7 @@ CustomElementRegistry::Define(const nsAString& aName,
}
JSContext *cx = jsapi.cx();
// Note: No calls that might run JS or trigger CC before this point, or
// there's a (vanishingly small) chance of our constructor being nulled
// before we access it.
JS::Rooted<JSObject*> constructor(cx, aFunctionConstructor.CallableOrNull());
JS::Rooted<JSObject*> constructor(cx, aFunctionConstructor.Callable());
/**
* 1. If IsConstructor(constructor) is false, then throw a TypeError and abort
@@ -928,7 +925,7 @@ CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
return;
}
aRetVal.setObject(*data->mConstructor->Callback(aCx));
aRetVal.setObjectOrNull(data->mConstructor->Callable());
return;
}
@@ -953,11 +950,10 @@ CustomElementRegistry::WhenDefined(const nsAString& aName, ErrorResult& aRv)
return promise.forget();
}
auto entry = mWhenDefinedPromiseMap.LookupForAdd(nameAtom);
if (entry) {
promise = entry.Data();
if (mWhenDefinedPromiseMap.Contains(nameAtom)) {
mWhenDefinedPromiseMap.Get(nameAtom, getter_AddRefs(promise));
} else {
entry.OrInsert([&promise](){ return promise; });
mWhenDefinedPromiseMap.Put(nameAtom, promise);
}
return promise.forget();
+28 -28
View File
@@ -307,15 +307,9 @@ void
Element::Focus(mozilla::ErrorResult& aError)
{
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(this);
nsFocusManager* fm = nsFocusManager::GetFocusManager();
// Also other browsers seem to have the hack to not re-focus (and flush) when
// the element is already focused.
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm && domElement) {
if (fm->CanSkipFocus(this)) {
fm->NeedsFlushBeforeEventHandling(this);
} else {
aError = fm->SetFocus(domElement, 0);
}
aError = fm->SetFocus(domElement, 0);
}
}
@@ -1581,9 +1575,6 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
if (aParent->HasFlag(NODE_CHROME_ONLY_ACCESS)) {
SetFlags(NODE_CHROME_ONLY_ACCESS);
}
if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) {
aParent->SetMayHaveAnonymousChildren();
}
if (aParent->IsInShadowTree()) {
ClearSubtreeRootPointer();
SetFlags(NODE_IS_IN_SHADOW_TREE);
@@ -4107,33 +4098,42 @@ enum nsPreviousIntersectionThreshold {
void
Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
{
RegisteredIntersectionObservers()->LookupForAdd(aObserver).OrInsert([]() {
// Value can be:
// -2: Makes sure next calculated threshold always differs, leading to a
// notification task being scheduled.
// -1: Non-intersecting.
// >= 0: Intersecting, valid index of aObserver->mThresholds.
return eUninitialized;
});
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
if (observers->Contains(aObserver)) {
return;
}
// Value can be:
// -2: Makes sure next calculated threshold always differs, leading to a
// notification task being scheduled.
// -1: Non-intersecting.
// >= 0: Intersecting, valid index of aObserver->mThresholds.
RegisteredIntersectionObservers()->Put(aObserver, eUninitialized);
}
void
Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver)
{
RegisteredIntersectionObservers()->Remove(aObserver);
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
observers->Remove(aObserver);
}
bool
Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold)
{
bool updated = false;
RegisteredIntersectionObservers()->LookupRemoveIf(aObserver,
[&updated, aThreshold] (int32_t& aValue) {
updated = aValue != aThreshold;
aValue = aThreshold;
return false; // don't remove the entry
});
return updated;
nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
if (!observers->Contains(aObserver)) {
return false;
}
int32_t previousThreshold = observers->Get(aObserver);
if (previousThreshold != aThreshold) {
observers->Put(aObserver, aThreshold);
return true;
}
return false;
}
void
+2 -2
View File
@@ -1295,10 +1295,10 @@ FragmentOrElement::RemoveChildAt(uint32_t aIndex, bool aNotify)
void
FragmentOrElement::GetTextContentInternal(nsAString& aTextContent,
OOMReporter& aError)
ErrorResult& aError)
{
if (!nsContentUtils::GetNodeTextContent(this, true, aTextContent, fallible)) {
aError.ReportOOM();
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
}
}
+1 -1
View File
@@ -129,7 +129,7 @@ public:
bool aNotify) override;
virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
virtual void GetTextContentInternal(nsAString& aTextContent,
mozilla::OOMReporter& aError) override;
mozilla::ErrorResult& aError) override;
virtual void SetTextContentInternal(const nsAString& aTextContent,
mozilla::ErrorResult& aError) override;
+1 -4
View File
@@ -275,12 +275,9 @@ const NativePropertyHooks sWindowNamedPropertiesNativePropertyHooks[] = { {
nullptr
} };
// Note that this class doesn't need any reserved slots, but SpiderMonkey
// asserts all proxy classes have at least one reserved slot.
static const DOMIfaceAndProtoJSClass WindowNamedPropertiesClass = {
PROXY_CLASS_DEF("WindowProperties",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS |
JSCLASS_HAS_RESERVED_SLOTS(1)),
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS),
eNamedPropertiesObject,
false,
prototypes::id::_ID_Count,
+1 -3
View File
@@ -1176,9 +1176,7 @@ nsLabelsNodeList::MaybeResetRoot(nsINode* aRootNode)
void
nsLabelsNodeList::PopulateSelf(uint32_t aNeededLength)
{
if (!mRootNode) {
return;
}
MOZ_ASSERT(mRootNode, "Must have root");
// Start searching at the root.
nsINode* cur = mRootNode;
+13 -10
View File
@@ -117,11 +117,14 @@ void
nsDOMAttributeMap::DropAttribute(int32_t aNamespaceID, nsIAtom* aLocalName)
{
nsAttrKey attr(aNamespaceID, aLocalName);
mAttributeCache.LookupRemoveIf(attr,
[] (Attr* aNode) {
aNode->SetMap(nullptr); // break link to map
return true; // remove from cache
});
Attr *node = mAttributeCache.GetWeak(attr);
if (node) {
// Break link to map
node->SetMap(nullptr);
// Remove from cache
mAttributeCache.Remove(attr);
}
}
Attr*
@@ -131,13 +134,13 @@ nsDOMAttributeMap::GetAttribute(mozilla::dom::NodeInfo* aNodeInfo)
nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom());
RefPtr<Attr>& entryValue = mAttributeCache.GetOrInsert(attr);
Attr* node = entryValue;
Attr* node = mAttributeCache.GetWeak(attr);
if (!node) {
// Newly inserted entry!
RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
entryValue = new Attr(this, ni.forget(), EmptyString());
node = entryValue;
RefPtr<Attr> newAttr =
new Attr(this, ni.forget(), EmptyString());
mAttributeCache.Put(attr, newAttr);
node = newAttr;
}
return node;
+20 -26
View File
@@ -118,7 +118,8 @@ using namespace mozilla::dom;
#define NS_DEFINE_CLASSINFO_DATA_HELPER(_class, _helper, _flags, \
_chromeOnly, _allowXBL) \
{ nullptr, \
{ #_class, \
nullptr, \
XPC_MAKE_CLASS_OPS(_flags), \
XPC_MAKE_CLASS(#_class, _flags, \
&sClassInfoData[eDOMClassInfo_##_class##_id].mClassOps), \
@@ -159,18 +160,18 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH,
DOM_BASE_SCRIPTABLE_FLAGS |
XPC_SCRIPTABLE_WANT_PRECREATE |
XPC_SCRIPTABLE_WANT_RESOLVE |
XPC_SCRIPTABLE_WANT_HASINSTANCE |
XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE)
nsIXPCScriptable::WANT_PRECREATE |
nsIXPCScriptable::WANT_RESOLVE |
nsIXPCScriptable::WANT_HASINSTANCE |
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
NS_DEFINE_CLASSINFO_DATA(DOMConstructor, nsDOMConstructorSH,
DOM_BASE_SCRIPTABLE_FLAGS |
XPC_SCRIPTABLE_WANT_PRECREATE |
XPC_SCRIPTABLE_WANT_RESOLVE |
XPC_SCRIPTABLE_WANT_HASINSTANCE |
XPC_SCRIPTABLE_WANT_CALL |
XPC_SCRIPTABLE_WANT_CONSTRUCT |
XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE)
nsIXPCScriptable::WANT_PRECREATE |
nsIXPCScriptable::WANT_RESOLVE |
nsIXPCScriptable::WANT_HASINSTANCE |
nsIXPCScriptable::WANT_CALL |
nsIXPCScriptable::WANT_CONSTRUCT |
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
// Misc Core related classes
@@ -193,13 +194,13 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentFrameMessageManager,
nsMessageManagerSH<nsEventTargetSH>,
DOM_DEFAULT_SCRIPTABLE_FLAGS |
XPC_SCRIPTABLE_WANT_ENUMERATE |
XPC_SCRIPTABLE_IS_GLOBAL_OBJECT)
nsIXPCScriptable::WANT_ENUMERATE |
nsIXPCScriptable::IS_GLOBAL_OBJECT)
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentProcessMessageManager,
nsMessageManagerSH<nsDOMGenericSH>,
DOM_DEFAULT_SCRIPTABLE_FLAGS |
XPC_SCRIPTABLE_WANT_ENUMERATE |
XPC_SCRIPTABLE_IS_GLOBAL_OBJECT)
nsIXPCScriptable::WANT_ENUMERATE |
nsIXPCScriptable::IS_GLOBAL_OBJECT)
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
@@ -568,7 +569,7 @@ nsDOMClassInfo::Init()
}
nsDOMClassInfoData& data = sClassInfoData[i];
nameSpaceManager->RegisterClassName(data.mClass.name, i, data.mChromeOnly,
nameSpaceManager->RegisterClassName(data.mName, i, data.mChromeOnly,
data.mAllowXBL, &data.mNameUTF16);
}
@@ -666,7 +667,7 @@ nsDOMClassInfo::GetFlags(uint32_t *aFlags)
NS_IMETHODIMP
nsDOMClassInfo::GetClassName(char **aClassName)
{
*aClassName = NS_strdup(mData->mClass.name);
*aClassName = NS_strdup(mData->mName);
return NS_OK;
}
@@ -685,13 +686,6 @@ nsDOMClassInfo::GetClass()
return &mData->mClass;
}
// virtual
const JSClass*
nsDOMClassInfo::GetJSClass()
{
return Jsvalify(&mData->mClass);
}
NS_IMETHODIMP
nsDOMClassInfo::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)
@@ -762,7 +756,7 @@ nsDOMClassInfo::Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalForObject(cx, obj));
JS::Rooted<JS::PropertyDescriptor> desc(cx);
if (!JS_GetPropertyDescriptor(cx, global, mData->mClass.name, &desc)) {
if (!JS_GetPropertyDescriptor(cx, global, mData->mName, &desc)) {
return NS_ERROR_UNEXPECTED;
}
@@ -865,7 +859,7 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto)
if (if_info) {
nsXPIDLCString name;
if_info->GetName(getter_Copies(name));
NS_ASSERTION(nsCRT::strcmp(CutPrefix(name), mData->mClass.name) == 0,
NS_ASSERTION(nsCRT::strcmp(CutPrefix(name), mData->mName) == 0,
"Class name and proto chain interface name mismatch!");
}
}
+3 -1
View File
@@ -30,7 +30,9 @@ typedef nsresult (*nsDOMConstructorFunc)(nsISupports** aNewObject);
struct nsDOMClassInfoData
{
// The ASCII name is available as mClass.name.
// XXX: mName is the same as the name gettable from the callback. This
// redundancy should be removed eventually.
const char *mName;
const char16_t *mNameUTF16;
const js::ClassOps mClassOps;
const js::Class mClass;
+11 -11
View File
@@ -337,14 +337,11 @@ nsMutationReceiver::ContentRemoved(nsIDocument* aDocument,
nsMutationReceiver* orig = GetParent() ? GetParent() : this;
if (Observer()->GetReceiverFor(aChild, false, false) != orig) {
bool transientExists = false;
bool isNewEntry = false;
nsCOMArray<nsMutationReceiver>* transientReceivers =
Observer()->mTransientReceivers.LookupForAdd(aChild).OrInsert(
[&isNewEntry] () {
isNewEntry = true;
return new nsCOMArray<nsMutationReceiver>();
});
if (!isNewEntry) {
nsCOMArray<nsMutationReceiver>* transientReceivers = nullptr;
Observer()->mTransientReceivers.Get(aChild, &transientReceivers);
if (!transientReceivers) {
transientReceivers = new nsCOMArray<nsMutationReceiver>();
Observer()->mTransientReceivers.Put(aChild, transientReceivers);
} else {
for (int32_t i = 0; i < transientReceivers->Count(); ++i) {
nsMutationReceiver* r = transientReceivers->ObjectAt(i);
@@ -1113,9 +1110,12 @@ nsAutoMutationBatch::Done()
}
if (allObservers.Length()) {
nsCOMArray<nsMutationReceiver>* transientReceivers =
ob->mTransientReceivers.LookupForAdd(removed).OrInsert(
[] () { return new nsCOMArray<nsMutationReceiver>(); });
nsCOMArray<nsMutationReceiver>* transientReceivers = nullptr;
ob->mTransientReceivers.Get(removed, &transientReceivers);
if (!transientReceivers) {
transientReceivers = new nsCOMArray<nsMutationReceiver>();
ob->mTransientReceivers.Put(removed, transientReceivers);
}
for (uint32_t k = 0; k < allObservers.Length(); ++k) {
nsMutationReceiver* r = allObservers[k];
nsMutationReceiver* orig = r->GetParent() ? r->GetParent() : r;
+8 -6
View File
@@ -691,15 +691,16 @@ nsExternalResourceMap::RequestResource(nsIURI* aURI,
return resource->mDocument;
}
RefPtr<PendingLoad>& loadEntry = mPendingLoads.GetOrInsert(clone);
if (loadEntry) {
RefPtr<PendingLoad> load(loadEntry);
RefPtr<PendingLoad> load;
mPendingLoads.Get(clone, getter_AddRefs(load));
if (load) {
load.forget(aPendingLoad);
return nullptr;
}
RefPtr<PendingLoad> load(new PendingLoad(aDisplayDocument));
loadEntry = load;
load = new PendingLoad(aDisplayDocument);
mPendingLoads.Put(clone, load);
if (NS_FAILED(load->StartLoad(clone, aRequestingNode))) {
// Make sure we don't thrash things by trying this load again, since
@@ -822,7 +823,8 @@ nsExternalResourceMap::AddExternalResource(nsIURI* aURI,
"Must have both or neither");
RefPtr<PendingLoad> load;
mPendingLoads.Remove(aURI, getter_AddRefs(load));
mPendingLoads.Get(aURI, getter_AddRefs(load));
mPendingLoads.Remove(aURI);
nsresult rv = NS_OK;
-9
View File
@@ -180,7 +180,6 @@ static const char* kObservedPrefs[] = {
};
nsFocusManager::nsFocusManager()
: mEventHandlingNeedsFlush(false)
{ }
nsFocusManager::~nsFocusManager()
@@ -1574,7 +1573,6 @@ nsFocusManager::CheckIfFocusable(nsIContent* aContent, uint32_t aFlags)
}
// Make sure that our frames are up to date
mEventHandlingNeedsFlush = false;
doc->FlushPendingNotifications(Flush_Layout);
nsIPresShell *shell = doc->GetShell();
@@ -4222,13 +4220,6 @@ nsFocusManager::MarkUncollectableForCCGeneration(uint32_t aGeneration)
}
}
bool
nsFocusManager::CanSkipFocus(nsIContent* aContent)
{
return mFocusedContent == aContent &&
(!aContent || !nsContentUtils::IsChromeDoc(aContent->OwnerDoc()));
}
nsresult
NS_NewFocusManager(nsIFocusManager** aResult)
{
-25
View File
@@ -7,7 +7,6 @@
#define nsFocusManager_h___
#include "nsCycleCollectionParticipant.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIFocusManager.h"
#include "nsIObserver.h"
@@ -93,26 +92,6 @@ public:
return handlingDocument.forget();
}
void NeedsFlushBeforeEventHandling(nsIContent* aContent)
{
if (mFocusedContent == aContent) {
mEventHandlingNeedsFlush = true;
}
}
bool CanSkipFocus(nsIContent* aContent);
void FlushBeforeEventHandlingIfNeeded(nsIContent* aContent)
{
if (mEventHandlingNeedsFlush) {
nsCOMPtr<nsIDocument> doc = aContent->GetComposedDoc();
if (doc) {
mEventHandlingNeedsFlush = false;
doc->FlushPendingNotifications(Flush_Layout);
}
}
}
/**
* Update the caret with current mode (whether in caret browsing mode or not).
*/
@@ -656,10 +635,6 @@ private:
// moving focus.
nsCOMPtr<nsIDocument> mMouseButtonEventHandlingDocument;
// If set to true, layout of the document of the event target should be
// flushed before handling focus depending events.
bool mEventHandlingNeedsFlush;
static bool sTestMode;
// the single focus manager
+1 -1
View File
@@ -1854,7 +1854,7 @@ nsMessageManagerScriptExecutor::InitChildGlobalInternal(
const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES;
JS::CompartmentOptions options;
options.creationOptions().setSystemZone();
options.creationOptions().setZone(JS::SystemZone);
options.behaviors().setVersion(JSVERSION_LATEST);
if (xpc::SharedMemoryEnabled()) {
-3
View File
@@ -503,9 +503,6 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
if (aParent->HasFlag(NODE_CHROME_ONLY_ACCESS)) {
SetFlags(NODE_CHROME_ONLY_ACCESS);
}
if (HasFlag(NODE_IS_ANONYMOUS_ROOT)) {
aParent->SetMayHaveAnonymousChildren();
}
if (aParent->IsInShadowTree()) {
ClearSubtreeRootPointer();
SetFlags(NODE_IS_IN_SHADOW_TREE);
+1 -1
View File
@@ -95,7 +95,7 @@ public:
bool aNotify) override;
virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
virtual void GetTextContentInternal(nsAString& aTextContent,
mozilla::OOMReporter& aError) override
mozilla::ErrorResult& aError) override
{
GetNodeValue(aTextContent);
}
+3
View File
@@ -101,6 +101,8 @@ GK_ATOM(animations, "animations")
GK_ATOM(anonid, "anonid")
GK_ATOM(anonlocation, "anonlocation")
GK_ATOM(any, "any")
GK_ATOM(any_hover, "any-hover")
GK_ATOM(any_pointer, "any-pointer")
GK_ATOM(applet, "applet")
GK_ATOM(applyImports, "apply-imports")
GK_ATOM(applyTemplates, "apply-templates")
@@ -1533,6 +1535,7 @@ GK_ATOM(patternContentUnits, "patternContentUnits")
GK_ATOM(patternTransform, "patternTransform")
GK_ATOM(patternUnits, "patternUnits")
GK_ATOM(pc, "pc")
GK_ATOM(pointer, "pointer")
GK_ATOM(pointer_events, "pointer-events")
GK_ATOM(points, "points")
GK_ATOM(pointsAtX, "pointsAtX")
+33 -52
View File
@@ -538,7 +538,7 @@ DialogValueHolder::Get(JSContext* aCx, JS::Handle<JSObject*> aScope,
class IdleRequestExecutor final : public nsIRunnable
, public nsICancelableRunnable
, public nsIIdleRunnable
, public nsIIncrementalRunnable
{
public:
explicit IdleRequestExecutor(nsGlobalWindow* aWindow)
@@ -582,7 +582,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequestExecutor)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_ENTRY(nsICancelableRunnable)
NS_INTERFACE_MAP_ENTRY(nsIIdleRunnable)
NS_INTERFACE_MAP_ENTRY(nsIIncrementalRunnable)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRunnable)
NS_INTERFACE_MAP_END
@@ -1026,7 +1026,7 @@ protected:
static nsGlobalWindow* GetOuterWindow(JSObject *proxy)
{
nsGlobalWindow* outerWindow = nsGlobalWindow::FromSupports(
static_cast<nsISupports*>(js::GetProxyReservedSlot(proxy, 0).toPrivate()));
static_cast<nsISupports*>(js::GetProxyExtra(proxy, 0).toPrivate()));
MOZ_ASSERT_IF(outerWindow, outerWindow->IsOuterWindow());
return outerWindow;
}
@@ -1053,12 +1053,9 @@ static const js::ClassExtension OuterWindowProxyClassExtension = PROXY_MAKE_EXT(
nsOuterWindowProxy::ObjectMoved
);
// Give OuterWindowProxyClass 2 reserved slots, like the other wrappers, so
// JSObject::swap can swap it with CrossCompartmentWrappers without requiring
// malloc.
const js::Class OuterWindowProxyClass = PROXY_CLASS_WITH_EXT(
"Proxy",
JSCLASS_HAS_RESERVED_SLOTS(2), /* additional class flags */
0, /* additional class flags */
&OuterWindowProxyClassExtension);
const char *
@@ -1074,7 +1071,7 @@ nsOuterWindowProxy::finalize(JSFreeOp *fop, JSObject *proxy) const
{
nsGlobalWindow* outerWindow = GetOuterWindow(proxy);
if (outerWindow) {
outerWindow->ClearWrapper(proxy);
outerWindow->ClearWrapper();
// Ideally we would use OnFinalize here, but it's possible that
// EnsureScriptEnvironment will later be called on the window, and we don't
@@ -1482,7 +1479,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
#endif
mNotifiedIDDestroyed(false),
mAllowScriptsToClose(false),
mTopLevelOuterContentWindow(false),
mTimeoutInsertionPoint(nullptr),
mTimeoutIdCounter(1),
mTimeoutFiringDepth(0),
@@ -1686,9 +1682,9 @@ nsGlobalWindow::~nsGlobalWindow()
("DOMWINDOW %p destroyed", this));
if (IsOuterWindow()) {
JSObject *proxy = GetWrapperMaybeDead();
JSObject *proxy = GetWrapperPreserveColor();
if (proxy) {
js::SetProxyReservedSlot(proxy, 0, js::PrivateValue(nullptr));
js::SetProxyExtra(proxy, 0, js::PrivateValue(nullptr));
}
// An outer window is destroyed with inner windows still possibly
@@ -2776,7 +2772,7 @@ CreateNativeGlobalForInner(JSContext* aCx,
}
if (top && top->GetGlobalJSObject()) {
options.creationOptions().setExistingZone(top->GetGlobalJSObject());
options.creationOptions().setSameZoneAs(top->GetGlobalJSObject());
}
options.creationOptions().setSecureContext(aIsSecureContext);
@@ -2861,7 +2857,9 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// transplanting code, since it has no good way to handle errors. This uses
// the untrusted script limit, which is not strictly necessary since no
// actual script should run.
if (!js::CheckRecursionLimitConservativeDontReport(cx)) {
bool overrecursed = false;
JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, overrecursed = true);
if (overrecursed) {
NS_WARNING("Overrecursion in SetNewDocument");
return NS_ERROR_FAILURE;
}
@@ -3049,7 +3047,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
NewOuterWindowProxy(cx, newInnerGlobal, thisChrome));
NS_ENSURE_TRUE(outer, NS_ERROR_FAILURE);
js::SetProxyReservedSlot(outer, 0, js::PrivateValue(ToSupports(this)));
js::SetProxyExtra(outer, 0, js::PrivateValue(ToSupports(this)));
// Inform the nsJSContext, which is the canonical holder of the outer.
mContext->SetWindowProxy(outer);
@@ -3067,8 +3065,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
JS::Rooted<JSObject*> obj(cx, GetWrapperPreserveColor());
js::SetProxyReservedSlot(obj, 0, js::PrivateValue(nullptr));
js::SetProxyReservedSlot(outerObject, 0, js::PrivateValue(nullptr));
js::SetProxyExtra(obj, 0, js::PrivateValue(nullptr));
js::SetProxyExtra(outerObject, 0, js::PrivateValue(nullptr));
outerObject = xpc::TransplantObject(cx, obj, outerObject);
if (!outerObject) {
@@ -3076,7 +3074,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
return NS_ERROR_FAILURE;
}
js::SetProxyReservedSlot(outerObject, 0, js::PrivateValue(ToSupports(this)));
js::SetProxyExtra(outerObject, 0, js::PrivateValue(ToSupports(this)));
SetWrapper(outerObject);
@@ -3193,7 +3191,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
newInnerWindow->mChromeEventHandler = mChromeEventHandler;
}
nsJSContext::PokeGC(JS::gcreason::SET_NEW_DOCUMENT, GetWrapperPreserveColor());
nsJSContext::PokeGC(JS::gcreason::SET_NEW_DOCUMENT);
kungFuDeathGrip->DidInitializeContext();
// We wait to fire the debugger hook until the window is all set up and hooked
@@ -3338,9 +3336,6 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = GetScriptableParentOrNull();
MOZ_RELEASE_ASSERT(!parentWindow || !mTabGroup || mTabGroup == Cast(parentWindow)->mTabGroup);
mTopLevelOuterContentWindow =
!mIsChrome && GetScriptableTopInternal() == this;
NS_ASSERTION(!mNavigator, "Non-null mNavigator in outer window!");
if (mFrames) {
@@ -3422,12 +3417,7 @@ nsGlobalWindow::DetachFromDocShell()
mChromeEventHandler = nullptr; // force release now
if (mContext) {
// When we're about to destroy a top level content window
// (for example a tab), we trigger a full GC by passing null as the last
// param. We also trigger a full GC for chrome windows.
nsJSContext::PokeGC(JS::gcreason::SET_DOC_SHELL,
(mTopLevelOuterContentWindow || mIsChrome) ?
nullptr : GetWrapperPreserveColor());
nsJSContext::PokeGC(JS::gcreason::SET_DOC_SHELL);
mContext = nullptr;
}
@@ -3821,7 +3811,7 @@ void
nsGlobalWindow::PoisonOuterWindowProxy(JSObject *aObject)
{
MOZ_ASSERT(IsOuterWindow());
if (aObject == GetWrapperMaybeDead()) {
if (aObject == GetWrapperPreserveColor()) {
PoisonWrapper();
}
}
@@ -9419,23 +9409,13 @@ public:
AutoSafeJSContext cx;
JS::Rooted<JSObject*> obj(cx, currentInner->FastGetGlobalJSObject());
// We only want to nuke wrappers for the chrome->content case
if (obj && !js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
JSCompartment* cpt = js::GetObjectCompartment(obj);
nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
nsAutoString addonId;
if (NS_SUCCEEDED(pc->GetAddonId(addonId)) && !addonId.IsEmpty()) {
// We want to nuke all references to the add-on compartment.
xpc::NukeAllWrappersForCompartment(cx, cpt,
win->IsInnerWindow() ? js::DontNukeWindowReferences
: js::NukeWindowReferences);
} else {
// We only want to nuke wrappers for the chrome->content case
js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt,
win->IsInnerWindow() ? js::DontNukeWindowReferences
: js::NukeWindowReferences,
js::NukeIncomingReferences);
}
js::NukeCrossCompartmentWrappers(cx,
BrowserCompartmentMatcher(),
js::SingleCompartment(js::GetObjectCompartment(obj)),
win->IsInnerWindow() ? js::DontNukeWindowReferences
: js::NukeWindowReferences);
}
}
@@ -14389,16 +14369,17 @@ nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup,
nsGlobalChromeWindow* myself = static_cast<nsGlobalChromeWindow*>(this);
nsCOMPtr<nsIMessageBroadcaster> messageManager =
myself->mGroupMessageManagers.Get(aGroup);
myself->mGroupMessageManagers.LookupForAdd(aGroup).OrInsert(
[this, &aError] () {
nsFrameMessageManager* parent =
static_cast<nsFrameMessageManager*>(GetMessageManager(aError));
if (!messageManager) {
nsFrameMessageManager* parent =
static_cast<nsFrameMessageManager*>(GetMessageManager(aError));
return new nsFrameMessageManager(nullptr,
parent,
MM_CHROME | MM_BROADCASTER);
});
messageManager = new nsFrameMessageManager(nullptr,
parent,
MM_CHROME | MM_BROADCASTER);
myself->mGroupMessageManagers.Put(aGroup, messageManager);
}
return messageManager;
}
-2
View File
@@ -1800,8 +1800,6 @@ protected:
// even if "dom.allow_scripts_to_close_windows" is false.
bool mAllowScriptsToClose : 1;
bool mTopLevelOuterContentWindow : 1;
nsCOMPtr<nsIScriptContext> mContext;
nsWeakPtr mOpener;
nsCOMPtr<nsIControllers> mControllers;
+10 -11
View File
@@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -10,21 +9,21 @@
#include "nsIXPCScriptable.h"
#define DOM_BASE_SCRIPTABLE_FLAGS \
(XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \
XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY | \
XPC_SCRIPTABLE_USE_JSSTUB_FOR_SETPROPERTY | \
XPC_SCRIPTABLE_ALLOW_PROP_MODS_TO_PROTOTYPE | \
XPC_SCRIPTABLE_DONT_ASK_INSTANCE_FOR_SCRIPTABLE | \
XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES)
(nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY | \
nsIXPCScriptable::USE_JSSTUB_FOR_DELPROPERTY | \
nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY | \
nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE | \
nsIXPCScriptable::DONT_ASK_INSTANCE_FOR_SCRIPTABLE | \
nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES)
#define DEFAULT_SCRIPTABLE_FLAGS \
(DOM_BASE_SCRIPTABLE_FLAGS | \
XPC_SCRIPTABLE_WANT_RESOLVE | \
XPC_SCRIPTABLE_WANT_PRECREATE)
nsIXPCScriptable::WANT_RESOLVE | \
nsIXPCScriptable::WANT_PRECREATE)
#define DOM_DEFAULT_SCRIPTABLE_FLAGS \
(DEFAULT_SCRIPTABLE_FLAGS | \
XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE | \
XPC_SCRIPTABLE_CLASSINFO_INTERFACES_ONLY)
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE | \
nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY)
#endif /* nsIDOMClassInfo_h___ */
+2 -1
View File
@@ -16,6 +16,7 @@
#include "mozilla/CORSMode.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/HTMLEditor.h"
#include "mozilla/InternalMutationEvent.h"
#include "mozilla/Likely.h"
#include "mozilla/MemoryReporting.h"
@@ -420,7 +421,7 @@ nsINode::ChildNodes()
}
void
nsINode::GetTextContentInternal(nsAString& aTextContent, OOMReporter& aError)
nsINode::GetTextContentInternal(nsAString& aTextContent, ErrorResult& aError)
{
SetDOMStringToNull(aTextContent);
}
+2 -8
View File
@@ -1335,7 +1335,7 @@ protected:
public:
void GetTextContent(nsAString& aTextContent,
mozilla::OOMReporter& aError)
mozilla::ErrorResult& aError)
{
GetTextContentInternal(aTextContent, aError);
}
@@ -1593,9 +1593,6 @@ private:
ParserHasNotified,
// Sets if the node is apz aware or we have apz aware listeners.
MayBeApzAware,
// Set if the element might have any kind of anonymous content children,
// which would not be found through the element's children list.
ElementMayHaveAnonymousChildren,
// Set if this node has at some point (and may still have)
// display:none or display:contents children.
NodeMayHaveChildrenWithLayoutBoxesDisabled,
@@ -1738,9 +1735,6 @@ public:
return GetBoolFlag(MayBeApzAware);
}
void SetMayHaveAnonymousChildren() { SetBoolFlag(ElementMayHaveAnonymousChildren); }
bool MayHaveAnonymousChildren() const { return GetBoolFlag(ElementMayHaveAnonymousChildren); }
void SetMayHaveChildrenWithLayoutBoxesDisabled()
{
SetBoolFlag(NodeMayHaveChildrenWithLayoutBoxesDisabled);
@@ -1977,7 +1971,7 @@ protected:
}
virtual void GetTextContentInternal(nsAString& aTextContent,
mozilla::OOMReporter& aError);
mozilla::ErrorResult& aError);
virtual void SetTextContentInternal(const nsAString& aTextContent,
mozilla::ErrorResult& aError)
{
File diff suppressed because it is too large. Load diff
+6 -7
View File
@@ -14,7 +14,6 @@
#include "nsIXPConnect.h"
#include "nsIArray.h"
#include "mozilla/Attributes.h"
#include "mozilla/TimeStamp.h"
#include "nsThreadUtils.h"
#include "xpcpublic.h"
@@ -91,7 +90,7 @@ public:
int32_t aExtraForgetSkippableCalls = 0);
// Run a cycle collector slice, using a heuristic to decide how long to run it.
static void RunCycleCollectorSlice(mozilla::TimeStamp aDeadline);
static void RunCycleCollectorSlice();
// Run a cycle collector slice, using the given work budget.
static void RunCycleCollectorWorkSlice(int64_t aWorkBudget);
@@ -105,18 +104,17 @@ public:
static void RunNextCollectorTimer();
// The GC should probably run soon, in the zone of object aObj (if given).
static void PokeGC(JS::gcreason::Reason aReason, JSObject* aObj, int aDelay = 0);
static void PokeGC(JS::gcreason::Reason aReason, int aDelay = 0);
static void KillGCTimer();
static void PokeShrinkingGC();
static void KillShrinkingGCTimer();
static void MaybePokeCC();
static void KillCCRunner();
static void KillICCRunner();
static void KillCCTimer();
static void KillICCTimer();
static void KillFullGCTimer();
static void KillInterSliceGCRunner();
static void KillInterSliceGCTimer();
// Calling LikelyShortLivingObjectCreated() makes a GC more likely.
static void LikelyShortLivingObjectCreated();
@@ -131,6 +129,7 @@ public:
return global ? mGlobalObjectRef.get() : nullptr;
}
static void NotifyDidPaint();
protected:
virtual ~nsJSContext();
+2 -2
View File
@@ -313,8 +313,8 @@ nsWindowRoot::GetEnabledDisabledCommandsForControllers(nsIControllers* aControll
// Use a hash to determine which commands have already been handled by
// earlier controllers, as the earlier controller's result should get
// priority.
if (aCommandsHandled.EnsureInserted(commands[e])) {
// We inserted a new entry into aCommandsHandled.
if (!aCommandsHandled.Contains(commands[e])) {
aCommandsHandled.PutEntry(commands[e]);
bool enabled = false;
controller->IsCommandEnabled(commands[e], &enabled);
+11 -28
View File
@@ -95,25 +95,12 @@ public:
* object returned is not guaranteed to be kept alive past the next CC.
*
* This should only be called if you are certain that the return value won't
* be passed into a JSAPI function and that it won't be stored without being
* be passed into a JS API function and that it won't be stored without being
* rooted (or otherwise signaling the stored value to the CC).
*/
JSObject* GetWrapperPreserveColor() const;
/**
* Get the cached wrapper.
*
* This getter does not check whether the wrapper is dead and in the process
* of being finalized.
*
* This should only be called if you really need to see the raw contents of
* this cache, for example as part of finalization. Don't store the result
* anywhere or pass it into JSAPI functions that may cause the value to
* escape.
*/
JSObject* GetWrapperMaybeDead() const
JSObject* GetWrapperPreserveColor() const
{
return mWrapper;
return GetWrapperJSObject();
}
#ifdef DEBUG
@@ -134,23 +121,14 @@ public:
}
/**
* Clear the cache.
* Clear the wrapper. This should be called from the finalizer for the
* wrapper.
*/
void ClearWrapper()
{
MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
SetWrapperJSObject(nullptr);
}
/**
* Clear the cache if it still contains a specific wrapper object. This should
* be called from the finalizer for the wrapper.
*/
void ClearWrapper(JSObject* obj)
{
if (obj == mWrapper) {
ClearWrapper();
}
SetWrapperJSObject(nullptr);
}
/**
@@ -310,6 +288,11 @@ private:
SetWrapperFlags(WRAPPER_IS_NOT_DOM_BINDING);
}
JSObject *GetWrapperJSObject() const
{
return mWrapper;
}
void SetWrapperJSObject(JSObject* aWrapper);
FlagsType GetWrapperFlags() const
-15
View File
@@ -10,21 +10,6 @@
#include "js/GCAPI.h"
#include "js/TracingAPI.h"
inline JSObject*
nsWrapperCache::GetWrapperPreserveColor() const
{
JSObject* obj = mWrapper;
if (obj && js::gc::EdgeNeedsSweepUnbarriered(&obj)) {
// The object has been found to be dead and is in the process of being
// finalized, so don't let the caller see it. As an optimisation, remove it
// from the cache so we don't have to do this check in future.
const_cast<nsWrapperCache*>(this)->ClearWrapper();
return nullptr;
}
MOZ_ASSERT(obj == mWrapper);
return obj;
}
inline JSObject*
nsWrapperCache::GetWrapper() const
{
+4 -7
View File
@@ -2118,10 +2118,7 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg, ErrorResult& aErr
// the untrusted script limit, which is not strictly necessary since no
// actual script should run.
// TODO: Make sure to retain 'onerror' if bug 1342439 lands.
if (!js::CheckRecursionLimitConservative(aCx)) {
aError.StealExceptionFromJSContext(aCx);
return;
}
JS_CHECK_RECURSION_CONSERVATIVE(aCx, aError.StealExceptionFromJSContext(aCx); return);
JS::Rooted<JSObject*> aObj(aCx, aObjArg);
const DOMJSClass* domClass = GetDOMClass(aObj);
@@ -2209,9 +2206,9 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg, ErrorResult& aErr
// NB: It's important to do this _after_ copying the properties to
// propertyHolder. Otherwise, an object with |foo.x === foo| will
// crash when JS_CopyPropertiesFrom tries to call wrap() on foo.x.
js::SetReservedSlot(newobj, DOM_OBJECT_SLOT,
js::GetReservedSlot(aObj, DOM_OBJECT_SLOT));
js::SetReservedSlot(aObj, DOM_OBJECT_SLOT, JS::PrivateValue(nullptr));
js::SetReservedOrProxyPrivateSlot(newobj, DOM_OBJECT_SLOT,
js::GetReservedOrProxyPrivateSlot(aObj, DOM_OBJECT_SLOT));
js::SetReservedOrProxyPrivateSlot(aObj, DOM_OBJECT_SLOT, JS::PrivateValue(nullptr));
aObj = xpc::TransplantObject(aCx, aObj, newobj);
if (!aObj) {
+50 -45
View File
@@ -153,7 +153,7 @@ UnwrapDOMObject(JSObject* obj)
MOZ_ASSERT(IsDOMClass(js::GetObjectClass(obj)),
"Don't pass non-DOM objects to this function");
JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
JS::Value val = js::GetReservedOrProxyPrivateSlot(obj, DOM_OBJECT_SLOT);
return static_cast<T*>(val.toPrivate());
}
@@ -168,7 +168,7 @@ UnwrapPossiblyNotInitializedDOMObject(JSObject* obj)
MOZ_ASSERT(IsDOMClass(js::GetObjectClass(obj)),
"Don't pass non-DOM objects to this function");
JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
JS::Value val = js::GetReservedOrProxyPrivateSlot(obj, DOM_OBJECT_SLOT);
if (val.isUndefined()) {
return nullptr;
}
@@ -1032,22 +1032,19 @@ MaybeWrapNonDOMObjectOrNullValue(JSContext* cx, JS::MutableHandle<JS::Value> rva
MOZ_ALWAYS_INLINE bool
MaybeWrapValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
{
if (rval.isGCThing()) {
if (rval.isString()) {
return MaybeWrapStringValue(cx, rval);
}
if (rval.isObject()) {
return MaybeWrapObjectValue(cx, rval);
}
// This could be optimized by checking the zone first, similar to
// the way strings are handled. At present, this is used primarily
// for structured cloning, so avoiding the overhead of JS_WrapValue
// calls is less important than for other types.
if (rval.isBigInt()) {
return JS_WrapValue(cx, rval);
}
MOZ_ASSERT(rval.isSymbol());
JS_MarkCrossZoneId(cx, SYMBOL_TO_JSID(rval.toSymbol()));
if (rval.isString()) {
return MaybeWrapStringValue(cx, rval);
}
if (rval.isObject()) {
return MaybeWrapObjectValue(cx, rval);
}
// This could be optimized by checking the zone first, similar to
// the way strings are handled. At present, this is used primarily
// for structured cloning, so avoiding the overhead of JS_WrapValue
// calls is less important than for other types.
if (rval.isBigInt()) {
return JS_WrapValue(cx, rval);
}
return true;
}
@@ -1541,27 +1538,25 @@ GetUseXBLScope(const ParentObject& aParentObject)
template<class T>
inline void
ClearWrapper(T* p, nsWrapperCache* cache, JSObject* obj)
ClearWrapper(T* p, nsWrapperCache* cache)
{
JS::AutoAssertGCCallback inCallback;
cache->ClearWrapper(obj);
cache->ClearWrapper();
}
template<class T>
inline void
ClearWrapper(T* p, void*, JSObject* obj)
ClearWrapper(T* p, void*)
{
JS::AutoAssertGCCallback inCallback;
nsWrapperCache* cache;
CallQueryInterface(p, &cache);
ClearWrapper(p, cache, obj);
ClearWrapper(p, cache);
}
template<class T>
inline void
UpdateWrapper(T* p, nsWrapperCache* cache, JSObject* obj, const JSObject* old)
{
JS::AutoAssertGCCallback inCallback;
JS::AutoAssertGCCallback inCallback(obj);
cache->UpdateWrapper(obj, old);
}
@@ -1569,7 +1564,7 @@ template<class T>
inline void
UpdateWrapper(T* p, void*, JSObject* obj, const JSObject* old)
{
JS::AutoAssertGCCallback inCallback;
JS::AutoAssertGCCallback inCallback(obj);
nsWrapperCache* cache;
CallQueryInterface(p, &cache);
UpdateWrapper(p, cache, obj, old);
@@ -1756,7 +1751,7 @@ struct WrapNativeHelper
JSObject* obj;
if ((obj = cache->GetWrapper())) {
// GetWrapper always unmarks gray.
MOZ_ASSERT(JS::ObjectIsNotGray(obj));
MOZ_ASSERT(!JS::ObjectIsMarkedGray(obj));
return obj;
}
@@ -1764,11 +1759,11 @@ struct WrapNativeHelper
if (!CouldBeDOMBinding(parent)) {
// WrapNativeFallback never returns a gray thing.
obj = WrapNativeFallback<T>::Wrap(cx, parent, cache);
MOZ_ASSERT(JS::ObjectIsNotGray(obj));
MOZ_ASSERT_IF(obj, !JS::ObjectIsMarkedGray(obj));
} else {
// WrapObject never returns a gray thing.
obj = parent->WrapObject(cx, nullptr);
MOZ_ASSERT(JS::ObjectIsNotGray(obj));
MOZ_ASSERT_IF(obj, !JS::ObjectIsMarkedGray(obj));
}
return obj;
@@ -1790,12 +1785,12 @@ struct WrapNativeHelper<T, false>
"Unexpected object in nsWrapperCache");
obj = rootedObj;
#endif
MOZ_ASSERT(JS::ObjectIsNotGray(obj));
MOZ_ASSERT(!JS::ObjectIsMarkedGray(obj));
return obj;
}
obj = WrapNativeISupports(cx, parent, cache);
MOZ_ASSERT(JS::ObjectIsNotGray(obj));
MOZ_ASSERT_IF(obj, !JS::ObjectIsMarkedGray(obj));
return obj;
}
};
@@ -1814,7 +1809,7 @@ FindAssociatedGlobal(JSContext* cx, T* p, nsWrapperCache* cache,
if (!obj) {
return nullptr;
}
MOZ_ASSERT(JS::ObjectIsNotGray(obj));
MOZ_ASSERT(!JS::ObjectIsMarkedGray(obj));
obj = js::GetGlobalForObjectCrossCompartment(obj);
@@ -1831,7 +1826,7 @@ FindAssociatedGlobal(JSContext* cx, T* p, nsWrapperCache* cache,
JS::Rooted<JSObject*> rootedObj(cx, obj);
JSObject* xblScope = xpc::GetXBLScope(cx, rootedObj);
MOZ_ASSERT_IF(xblScope, JS_IsGlobalObject(xblScope));
MOZ_ASSERT(JS::ObjectIsNotGray(xblScope));
MOZ_ASSERT_IF(xblScope, !JS::ObjectIsMarkedGray(xblScope));
return xblScope;
}
@@ -1956,9 +1951,9 @@ GetOrCreateDOMReflectorNoWrap(JSContext* cx, T& value,
template <class T>
inline JSObject*
GetCallbackFromCallbackObject(JSContext* aCx, T* aObj)
GetCallbackFromCallbackObject(T* aObj)
{
return aObj->Callback(aCx);
return aObj->Callback();
}
// Helper for getting the callback JSObject* of a smart ptr around a
@@ -1967,26 +1962,26 @@ GetCallbackFromCallbackObject(JSContext* aCx, T* aObj)
template <class T, bool isSmartPtr=IsSmartPtr<T>::value>
struct GetCallbackFromCallbackObjectHelper
{
static inline JSObject* Get(JSContext* aCx, const T& aObj)
static inline JSObject* Get(const T& aObj)
{
return GetCallbackFromCallbackObject(aCx, aObj.get());
return GetCallbackFromCallbackObject(aObj.get());
}
};
template <class T>
struct GetCallbackFromCallbackObjectHelper<T, false>
{
static inline JSObject* Get(JSContext* aCx, T& aObj)
static inline JSObject* Get(T& aObj)
{
return GetCallbackFromCallbackObject(aCx, &aObj);
return GetCallbackFromCallbackObject(&aObj);
}
};
template<class T>
inline JSObject*
GetCallbackFromCallbackObject(JSContext* aCx, T& aObj)
GetCallbackFromCallbackObject(T& aObj)
{
return GetCallbackFromCallbackObjectHelper<T>::Get(aCx, aObj);
return GetCallbackFromCallbackObjectHelper<T>::Get(aObj);
}
static inline bool
@@ -2079,6 +2074,16 @@ AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
nsTArray<nsString>& names,
bool shadowPrototypeProperties, JS::AutoIdVector& props);
namespace binding_detail {
class FastErrorResult :
public mozilla::binding_danger::TErrorResult<
mozilla::binding_danger::JustAssertCleanupPolicy>
{
};
} // namespace binding_detail
enum StringificationBehavior {
eStringify,
eEmpty,
@@ -2902,7 +2907,8 @@ public:
~BindingJSObjectCreator()
{
if (mReflector) {
js::SetReservedSlot(mReflector, DOM_OBJECT_SLOT, JS::UndefinedValue());
js::SetReservedOrProxyPrivateSlot(mReflector, DOM_OBJECT_SLOT,
JS::UndefinedValue());
}
}
@@ -2910,15 +2916,14 @@ public:
CreateProxyObject(JSContext* aCx, const js::Class* aClass,
const DOMProxyHandler* aHandler,
JS::Handle<JSObject*> aProto, T* aNative,
JS::Handle<JS::Value> aExpandoValue,
JS::MutableHandle<JSObject*> aReflector)
{
js::ProxyOptions options;
options.setClass(aClass);
aReflector.set(js::NewProxyObject(aCx, aHandler, aExpandoValue, aProto,
JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aNative));
aReflector.set(js::NewProxyObject(aCx, aHandler, proxyPrivateVal, aProto,
options));
if (aReflector) {
js::SetProxyReservedSlot(aReflector, DOM_OBJECT_SLOT, JS::PrivateValue(aNative));
mNative = aNative;
mReflector = aReflector;
}
+2 -2
View File
@@ -39,9 +39,9 @@ public:
{
}
JS::Handle<JSObject*> CallableOrNull() const
JS::Handle<JSObject*> Callable() const
{
return CallbackOrNull();
return Callback();
}
JS::Handle<JSObject*> CallablePreserveColor() const
+5 -65
View File
@@ -36,44 +36,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CallbackObject)
tmp->DropJSObjects();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncumbentGlobal)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(CallbackObject)
JSObject* callback = tmp->CallbackPreserveColor();
if (!aRemovingAllowed) {
// If our callback has been cleared, we can't be part of a garbage cycle.
return !callback;
}
// mCallback is always wrapped for the CallbackObject's incumbent global. In
// the case where the real callback is in a different compartment, we have a
// cross-compartment wrapper, and it will automatically be cut when its
// compartment is nuked. In the case where it is in the same compartment, we
// have a reference to the real function. Since that means there are no
// wrappers to cut, we need to check whether the compartment is still alive,
// and drop the references if it is not.
if (MOZ_UNLIKELY(!callback)) {
return true;
}
auto pvt = xpc::CompartmentPrivate::Get(callback);
if (MOZ_LIKELY(tmp->mIncumbentGlobal && pvt) && MOZ_UNLIKELY(pvt->wasNuked)) {
// It's not safe to release our global reference or drop our JS objects at
// this point, so defer their finalization until CC is finished.
AddForDeferredFinalization(new JSObjectsDropper(tmp));
DeferredFinalize(tmp->mIncumbentGlobal.forget().take());
return true;
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(CallbackObject)
return !tmp->mCallback;
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(CallbackObject)
return !tmp->mCallback;
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CallbackObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIncumbentGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -104,18 +66,6 @@ CallbackObject::HoldJSObjectsIfMoreThanOneOwner()
}
}
JSObject*
CallbackObject::Callback(JSContext* aCx)
{
JSObject* callback = CallbackOrNull();
if (!callback) {
callback = JS_NewDeadWrapper(aCx);
}
MOZ_DIAGNOSTIC_ASSERT(callback);
return callback;
}
CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
ErrorResult& aRv,
const char* aExecutionReason,
@@ -140,14 +90,8 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
webIDLCallerPrincipal = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
}
JSObject* wrappedCallback = aCallback->CallbackPreserveColor();
if (!wrappedCallback) {
aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("Cannot execute callback from a nuked compartment."));
return;
}
// First, find the real underlying callback.
JSObject* realCallback = js::UncheckedUnwrap(wrappedCallback);
JSObject* realCallback = js::UncheckedUnwrap(aCallback->CallbackPreserveColor());
nsIGlobalObject* globalObject = nullptr;
JSContext* cx;
@@ -210,14 +154,13 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
cx = mAutoEntryScript->cx();
// Unmark the callable (by invoking CallbackOrNull() and not the
// CallbackPreserveColor() variant), and stick it in a Rooted before it can
// go gray again.
// Unmark the callable (by invoking Callback() and not the CallbackPreserveColor()
// variant), and stick it in a Rooted before it can go gray again.
// Nothing before us in this function can trigger a CC, so it's safe to wait
// until here it do the unmark. This allows us to construct mRootedCallable
// with the cx from mAutoEntryScript, avoiding the cost of finding another
// JSContext. (Rooted<> does not care about requests or compartments.)
mRootedCallable.emplace(cx, aCallback->CallbackOrNull());
mRootedCallable.emplace(cx, aCallback->Callback());
}
// JS-implemented WebIDL is always OK to run, since it runs with Chrome
@@ -366,10 +309,7 @@ CallbackObjectHolderBase::ToXPCOMCallback(CallbackObject* aCallback,
jsapi.Init();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> callback(cx, aCallback->CallbackOrNull());
if (!callback) {
return nullptr;
}
JS::Rooted<JSObject*> callback(cx, aCallback->Callback());
JSAutoCompartment ac(cx, callback);
RefPtr<nsXPCWrappedJS> wrappedJS;
+14 -56
View File
@@ -45,7 +45,7 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(DOM_CALLBACKOBJECT_IID)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CallbackObject)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CallbackObject)
// The caller may pass a global object which will act as an override for the
// incumbent script settings object when the callback is invoked (overriding
@@ -78,24 +78,12 @@ public:
Init(aCallback, aAsyncStack, aIncumbentGlobal);
}
// This is guaranteed to be non-null from the time the CallbackObject is
// created until JavaScript has had a chance to run. It will only return null
// after a JavaScript caller has called nukeSandbox on a Sandbox object, and
// the cycle collector has had a chance to run.
//
// This means that any native callee which receives a CallbackObject as an
// argument can safely rely on the callback being non-null so long as it
// doesn't trigger any scripts before it accesses it.
JS::Handle<JSObject*> CallbackOrNull() const
JS::Handle<JSObject*> Callback() const
{
mCallback.exposeToActiveJS();
return CallbackPreserveColor();
}
// Like CallbackOrNull(), but will return a new dead proxy object in the
// caller's compartment if the callback is null.
JSObject* Callback(JSContext* aCx);
JSObject* GetCreationStack() const
{
return mCreationStack;
@@ -124,12 +112,12 @@ public:
/*
* If the callback is known to be non-gray, then this method can be
* used instead of CallbackOrNull() to avoid the overhead of
* used instead of Callback() to avoid the overhead of
* ExposeObjectToActiveJS().
*/
JS::Handle<JSObject*> CallbackKnownNotGray() const
{
MOZ_ASSERT(JS::ObjectIsNotGray(mCallback));
MOZ_ASSERT(!JS::ObjectIsMarkedGray(mCallback));
return CallbackPreserveColor();
}
@@ -171,33 +159,13 @@ protected:
bool operator==(const CallbackObject& aOther) const
{
JSObject* wrappedThis = CallbackPreserveColor();
JSObject* wrappedOther = aOther.CallbackPreserveColor();
if (!wrappedThis || !wrappedOther) {
return this == &aOther;
}
JSObject* thisObj = js::UncheckedUnwrap(wrappedThis);
JSObject* otherObj = js::UncheckedUnwrap(wrappedOther);
JSObject* thisObj =
js::UncheckedUnwrap(CallbackPreserveColor());
JSObject* otherObj =
js::UncheckedUnwrap(aOther.CallbackPreserveColor());
return thisObj == otherObj;
}
class JSObjectsDropper final
{
public:
explicit JSObjectsDropper(CallbackObject* aHolder)
: mHolder(aHolder)
{}
~JSObjectsDropper()
{
mHolder->DropJSObjects();
}
private:
RefPtr<CallbackObject> mHolder;
};
private:
inline void InitNoHold(JSObject* aCallback, JSObject* aCreationStack,
nsIGlobalObject* aIncumbentGlobal)
@@ -520,11 +488,8 @@ public:
nsCOMPtr<nsISupports> supp =
CallbackObjectHolderBase::ToXPCOMCallback(GetWebIDLCallback(),
NS_GET_TEMPLATE_IID(XPCOMCallbackT));
if (supp) {
// ToXPCOMCallback already did the right QI for us.
return supp.forget().downcast<XPCOMCallbackT>();
}
return nullptr;
// ToXPCOMCallback already did the right QI for us.
return supp.forget().downcast<XPCOMCallbackT>();
}
// Try to return a WebIDLCallbackT version of this object.
@@ -565,9 +530,7 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
const char* aName,
uint32_t aFlags = 0)
{
if (aField) {
CycleCollectionNoteChild(aCallback, aField.GetISupports(), aName, aFlags);
}
CycleCollectionNoteChild(aCallback, aField.GetISupports(), aName, aFlags);
}
template<class T, class U>
@@ -604,15 +567,10 @@ public:
this->get().operator=(arg);
}
// Codegen relies on being able to do CallbackOrNull() and Callback() on us.
JS::Handle<JSObject*> CallbackOrNull() const
// Codegen relies on being able to do Callback() on us.
JS::Handle<JSObject*> Callback() const
{
return this->get()->CallbackOrNull();
}
JSObject* Callback(JSContext* aCx) const
{
return this->get()->Callback(aCx);
return this->get()->Callback();
}
~RootedCallback()
+36 -105
View File
@@ -449,9 +449,6 @@ class CGDOMJSClass(CGThing):
traceHook = 'nullptr'
reservedSlots = slotCount
if self.descriptor.interface.isProbablyShortLivingObject():
if not self.descriptor.wrapperCache:
raise TypeError("Need a wrapper cache to support nursery "
"allocation of DOM objects")
classFlags += " | JSCLASS_SKIP_NURSERY_FINALIZE"
if self.descriptor.interface.getExtendedAttribute("NeedResolve"):
resolveHook = RESOLVE_HOOK_NAME
@@ -531,9 +528,7 @@ class CGDOMProxyJSClass(CGThing):
return ""
def define(self):
# We need one reserved slot (DOM_OBJECT_SLOT).
flags = ["JSCLASS_IS_DOMJSCLASS",
"JSCLASS_HAS_RESERVED_SLOTS(1)"]
flags = ["JSCLASS_IS_DOMJSCLASS"]
# We don't use an IDL annotation for JSCLASS_EMULATES_UNDEFINED because
# we don't want people ever adding that to any interface other than
# HTMLAllCollection. So just hardcode it here.
@@ -1676,14 +1671,14 @@ class CGAddPropertyHook(CGAbstractClassHook):
""")
def finalizeHook(descriptor, hookName, freeOp, obj):
def finalizeHook(descriptor, hookName, freeOp):
finalize = ""
if descriptor.wrapperCache:
finalize += "ClearWrapper(self, self, %s);\n" % obj
finalize += "ClearWrapper(self, self);\n"
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
if descriptor.isGlobal():
finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), %s);\n" % (freeOp, obj)
finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), obj);\n" % freeOp
finalize += ("AddForDeferredFinalization<%s>(self);\n" %
descriptor.nativeType)
return CGIfWrapper(CGGeneric(finalize), "self")
@@ -1699,8 +1694,7 @@ class CGClassFinalizeHook(CGAbstractClassHook):
'void', args)
def generate_code(self):
return finalizeHook(self.descriptor, self.name,
self.args[0].name, self.args[1].name).define()
return finalizeHook(self.descriptor, self.name, self.args[0].name).define()
class CGClassObjectMovedHook(CGAbstractClassHook):
@@ -3231,7 +3225,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
*/
const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(${id});
MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
MOZ_ASSERT_IF(entrySlot, !JS::ObjectIsMarkedGray(entrySlot));
return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
""",
id=self.id)
@@ -3477,21 +3471,21 @@ def CreateBindingJSObject(descriptor, properties):
# We don't always need to root obj, but there are a variety
# of cases where we do, so for simplicity, just always root it.
if descriptor.proxy:
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
expandoValue = "JS::PrivateValue(&aObject->mExpandoAndGeneration)"
else:
expandoValue = "JS::UndefinedValue()"
create = fill(
create = dedent(
"""
JS::Rooted<JS::Value> expandoValue(aCx, ${expandoValue});
creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
proto, aObject, expandoValue, aReflector);
proto, aObject, aReflector);
if (!aReflector) {
return false;
}
""",
expandoValue=expandoValue)
""")
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
create += dedent("""
js::SetProxyExtra(aReflector, JSPROXYSLOT_EXPANDO,
JS::PrivateValue(&aObject->mExpandoAndGeneration));
""")
else:
create = dedent(
"""
@@ -3736,7 +3730,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
MOZ_ASSERT(JS::ObjectIsNotGray(global));
MOZ_ASSERT(!JS::ObjectIsMarkedGray(global));
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
@@ -3952,15 +3946,11 @@ class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):
body += fill(
"""
static_assert(${slot} < js::shadow::Object::MAX_FIXED_SLOTS,
"Not enough fixed slots to fit '${interface}.${member}. Ion's visitGetDOMMemberV/visitGetDOMMemberT assume StoreInSlot things are all in fixed slots.");
if (!get_${member}(aCx, aWrapper, aObject, args)) {
return false;
}
// Getter handled setting our reserved slots
""",
slot=memberReservedSlot(m, self.descriptor),
interface=self.descriptor.interface.identifier.name,
member=m.identifier.name)
body += "\nreturn true;\n"
@@ -4262,9 +4252,7 @@ class CastableObjectUnwrapper():
// that already has a content reflection...
if (!IsDOMObject(js::UncheckedUnwrap(&${source}.toObject()))) {
nsCOMPtr<nsIGlobalObject> contentGlobal;
JS::Handle<JSObject*> callback = CallbackOrNull();
if (!callback ||
!GetContentGlobalForJSImplementedObject(cx, callback, getter_AddRefs(contentGlobal))) {
if (!GetContentGlobalForJSImplementedObject(cx, Callback(), getter_AddRefs(contentGlobal))) {
$*{exceptionCode}
}
JS::Rooted<JSObject*> jsImplSourceObj(cx, &${source}.toObject());
@@ -4936,7 +4924,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
}
${typeName}::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
if (idsSeen.Contains(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
@@ -4952,6 +4940,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
idsSeen.PutEntry(propName);
}
entry->mKey = propName;
${valueType}& slot = entry->mValue;
@@ -6739,10 +6728,8 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
return conversion, False
if type.isCallback() or type.isCallbackInterface():
# Callbacks can store null if we nuked the compartments their
# objects lived in.
wrapCode = setObjectOrNull(
"GetCallbackFromCallbackObject(cx, %(result)s)",
wrapCode = setObject(
"*GetCallbackFromCallbackObject(%(result)s)",
wrapAsType=type)
if type.nullable():
wrapCode = (
@@ -7192,8 +7179,7 @@ class CGCallGenerator(CGThing):
if needsCallerType:
args.append(CGGeneric("callerType"))
canOOM = "canOOM" in extendedAttributes
if isFallible or canOOM:
if isFallible:
args.append(CGGeneric("rv"))
args.extend(CGGeneric(arg) for arg in argsPost)
@@ -7277,12 +7263,8 @@ class CGCallGenerator(CGThing):
self.cgRoot.prepend(callerCheck)
self.cgRoot.prepend(CGGeneric("CallerType callerType;\n"))
if isFallible or canOOM:
if isFallible:
reporterClass = "binding_detail::FastErrorResult"
else:
reporterClass = "binding_danger::OOMReporterInstantiator"
self.cgRoot.prepend(CGGeneric("%s rv;\n" % reporterClass))
if isFallible:
self.cgRoot.prepend(CGGeneric("binding_detail::FastErrorResult rv;\n"))
self.cgRoot.append(CGGeneric(dedent(
"""
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
@@ -9061,10 +9043,9 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
nativeName = MakeNativeName(descriptor.binaryNameFor(name))
_, resultOutParam, _, _, _ = getRetvalDeclarationForType(attr.type,
descriptor)
extendedAttrs = descriptor.getExtendedAttributes(attr, getter=True)
canFail = ('infallible' not in extendedAttrs or
'canOOM' in extendedAttrs)
if resultOutParam or attr.type.nullable() or canFail:
infallible = ('infallible' in
descriptor.getExtendedAttributes(attr, getter=True))
if resultOutParam or attr.type.nullable() or not infallible:
nativeName = "Get" + nativeName
return nativeName
@@ -9362,27 +9343,13 @@ class CGMemberJITInfo(CGThing):
# while we have the right type.
getter = ("(JSJitGetterOp)get_%s" %
IDLToCIdentifier(self.member.identifier.name))
extendedAttrs = self.descriptor.getExtendedAttributes(self.member, getter=True)
getterinfal = "infallible" in extendedAttrs
# At this point getterinfal is true if our getter either can't throw
# at all, or can only throw OOM. In both cases, it's safe to move,
# or dead-code-eliminate, the getter, because throwing OOM is not
# semantically meaningful, so code can't rely on it happening. Note
# that this makes the behavior consistent for OOM thrown from the
# getter itself and OOM thrown from the to-JS conversion of the
# return value (see the "canOOM" and "infallibleForMember" checks
# below).
getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
movable = self.mayBeMovable() and getterinfal
eliminatable = self.mayBeEliminatable() and getterinfal
aliasSet = self.aliasSet()
# Now we have to set getterinfal to whether we can _really_ ever
# throw, from the point of view of the JS engine.
getterinfal = (getterinfal and
"canOOM" not in extendedAttrs and
infallibleForMember(self.member, self.member.type, self.descriptor))
getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
isAlwaysInSlot = self.member.getExtendedAttribute("StoreInSlot")
if self.member.slotIndices is not None:
assert isAlwaysInSlot or self.member.getExtendedAttribute("Cached")
@@ -9445,16 +9412,7 @@ class CGMemberJITInfo(CGThing):
# argument conversions, since argument conversions that can
# reliably throw would be effectful anyway and the jit doesn't
# move effectful things.
extendedAttrs = self.descriptor.getExtendedAttributes(self.member)
hasInfallibleImpl = "infallible" in extendedAttrs
# At this point hasInfallibleImpl is true if our method either
# can't throw at all, or can only throw OOM. In both cases, it
# may be safe to move, or dead-code-eliminate, the method,
# because throwing OOM is not semantically meaningful, so code
# can't rely on it happening. Note that this makes the behavior
# consistent for OOM thrown from the method itself and OOM
# thrown from the to-JS conversion of the return value (see the
# "canOOM" and "infallibleForMember" checks below).
hasInfallibleImpl = "infallible" in self.descriptor.getExtendedAttributes(self.member)
movable = self.mayBeMovable() and hasInfallibleImpl
eliminatable = self.mayBeEliminatable() and hasInfallibleImpl
# XXXbz can we move the smarts about fallibility due to arg
@@ -9464,8 +9422,7 @@ class CGMemberJITInfo(CGThing):
# We have arguments or our return-value boxing can fail
methodInfal = False
else:
methodInfal = (hasInfallibleImpl and
"canOOM" not in extendedAttrs)
methodInfal = hasInfallibleImpl
# For now, only bother to output args if we're side-effect-free.
if self.member.affects == "Nothing":
args = sig[1]
@@ -10973,7 +10930,6 @@ class CGResolveOwnPropertyViaResolve(CGAbstractBindingMethod):
// to avoid re-resolving the properties if someone deletes
// them.
JSAutoCompartment ac(cx, obj);
JS_MarkCrossZoneId(cx, id);
JS::Rooted<JS::PropertyDescriptor> objDesc(cx);
if (!self->DoResolve(cx, obj, id, &objDesc)) {
return false;
@@ -11395,7 +11351,7 @@ class CGProxyUnwrap(CGAbstractMethod):
obj = js::UncheckedUnwrap(obj);
}
MOZ_ASSERT(IsProxy(obj));
return static_cast<${type}*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
return static_cast<${type}*>(js::GetProxyPrivate(obj).toPrivate());
""",
type=self.descriptor.nativeType)
@@ -12103,8 +12059,7 @@ class CGDOMJSProxyHandler_finalize(ClassMethod):
def getBody(self):
return (("%s* self = UnwrapPossiblyNotInitializedDOMObject<%s>(proxy);\n" %
(self.descriptor.nativeType, self.descriptor.nativeType)) +
finalizeHook(self.descriptor, FINALIZE_HOOK_NAME,
self.args[0].name, self.args[1].name).define())
finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name).define())
class CGDOMJSProxyHandler_getElements(ClassMethod):
@@ -12218,21 +12173,6 @@ class CGDOMJSProxyHandler_isCallable(ClassMethod):
return true;
""")
class CGDOMJSProxyHandler_canNurseryAllocate(ClassMethod):
"""
Override the default canNurseryAllocate in BaseProxyHandler, for cases when
we should be nursery-allocated.
"""
def __init__(self):
ClassMethod.__init__(self, "canNurseryAllocate", "bool",
[],
virtual=True, override=True, const=True)
def getBody(self):
return dedent("""
return true;
""")
class CGDOMJSProxyHandler(CGClass):
def __init__(self, descriptor):
@@ -12270,11 +12210,6 @@ class CGDOMJSProxyHandler(CGClass):
if descriptor.operations['LegacyCaller']:
methods.append(CGDOMJSProxyHandler_call())
methods.append(CGDOMJSProxyHandler_isCallable())
if descriptor.interface.isProbablyShortLivingObject():
if not descriptor.wrapperCache:
raise TypeError("Need a wrapper cache to support nursery "
"allocation of DOM objects")
methods.append(CGDOMJSProxyHandler_canNurseryAllocate())
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
parentClass = 'ShadowingDOMProxyHandler'
@@ -14355,12 +14290,10 @@ class CGNativeMember(ClassMethod):
# And the caller type, if desired.
if needsCallerType(self.member):
args.append(Argument("CallerType", "aCallerType"))
# And the ErrorResult or OOMReporter
# And the ErrorResult
if 'infallible' not in self.extendedAttrs:
# Use aRv so it won't conflict with local vars named "rv"
args.append(Argument("ErrorResult&", "aRv"))
elif 'canOOM' in self.extendedAttrs:
args.append(Argument("OOMReporter&", "aRv"))
# The legacycaller thisval
if self.member.isMethod() and self.member.isLegacycaller():
# If it has an identifier, we can't deal with it yet
@@ -15275,11 +15208,11 @@ class CGJSImplClass(CGBindingImplClass):
}
// Now define it on our chrome object
JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
JSAutoCompartment ac(aCx, mImpl->Callback());
if (!JS_WrapObject(aCx, &obj)) {
return nullptr;
}
if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
if (!JS_DefineProperty(aCx, mImpl->Callback(), "__DOM_IMPL__", obj, 0)) {
return nullptr;
}
return obj;
@@ -17073,8 +17006,6 @@ class CGEventGetter(CGNativeMember):
def getArgs(self, returnType, argList):
if 'infallible' not in self.extendedAttrs:
raise TypeError("Event code generator does not support [Throws]!")
if 'canOOM' in self.extendedAttrs:
raise TypeError("Event code generator does not support [CanOOM]!")
if not self.member.isAttr():
raise TypeError("Event code generator does not support methods")
if self.member.isStatic():
+2 -19
View File
@@ -568,29 +568,17 @@ class Descriptor(DescriptorProvider):
return self.isGlobal() and self.supportsNamedProperties()
def getExtendedAttributes(self, member, getter=False, setter=False):
def ensureValidBoolExtendedAttribute(attr, name):
if (attr is not None and attr is not True):
raise TypeError("Unknown value for '%s': %s" % (name, attr[0]))
def ensureValidThrowsExtendedAttribute(attr):
ensureValidBoolExtendedAttribute(attr, "Throws")
def ensureValidCanOOMExtendedAttribute(attr):
ensureValidBoolExtendedAttribute(attr, "CanOOM")
if (attr is not None and attr is not True):
raise TypeError("Unknown value for 'Throws': " + attr[0])
def maybeAppendInfallibleToAttrs(attrs, throws):
ensureValidThrowsExtendedAttribute(throws)
if throws is None:
attrs.append("infallible")
def maybeAppendCanOOMToAttrs(attrs, canOOM):
ensureValidCanOOMExtendedAttribute(canOOM)
if canOOM is not None:
attrs.append("canOOM")
name = member.identifier.name
throws = self.interface.isJSImplemented() or member.getExtendedAttribute("Throws")
canOOM = member.getExtendedAttribute("CanOOM")
if member.isMethod():
# JSObject-returning [NewObject] methods must be fallible,
# since they have to (fallibly) allocate the new JSObject.
@@ -599,7 +587,6 @@ class Descriptor(DescriptorProvider):
throws = True
attrs = self.extendedAttributes['all'].get(name, [])
maybeAppendInfallibleToAttrs(attrs, throws)
maybeAppendCanOOMToAttrs(attrs, canOOM)
return attrs
assert member.isAttr()
@@ -610,10 +597,6 @@ class Descriptor(DescriptorProvider):
throwsAttr = "GetterThrows" if getter else "SetterThrows"
throws = member.getExtendedAttribute(throwsAttr)
maybeAppendInfallibleToAttrs(attrs, throws)
if canOOM is None:
canOOMAttr = "GetterCanOOM" if getter else "SetterCanOOM"
canOOM = member.getExtendedAttribute(canOOMAttr)
maybeAppendCanOOMToAttrs(attrs, canOOM)
return attrs
def supportsIndexedProperties(self):
+13 -13
View File
@@ -33,7 +33,7 @@ js::DOMProxyShadowsResult
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
{
JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
JS::Value v = js::GetProxyPrivate(proxy);
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
if (expando) {
bool hasOwn;
@@ -63,26 +63,24 @@ struct SetDOMProxyInformation
{
SetDOMProxyInformation() {
js::SetDOMProxyInformation((const void*) &DOMProxyHandler::family,
DOMProxyShadows);
JSPROXYSLOT_EXPANDO, DOMProxyShadows);
}
};
SetDOMProxyInformation gSetDOMProxyInformation;
// static
JSObject*
DOMProxyHandler::GetAndClearExpandoObject(JSObject* obj)
{
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
JS::Value v = js::GetProxyPrivate(obj);
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
if (v.isUndefined()) {
return nullptr;
}
if (v.isObject()) {
js::SetProxyPrivate(obj, UndefinedValue());
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, UndefinedValue());
} else {
js::ExpandoAndGeneration* expandoAndGeneration =
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
@@ -115,7 +113,7 @@ JSObject*
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
{
NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
JS::Value v = js::GetProxyPrivate(obj);
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
if (v.isObject()) {
return &v.toObject();
}
@@ -150,7 +148,7 @@ DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
return expando;
}
js::SetProxyPrivate(obj, ObjectValue(*expando));
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
return expando;
}
@@ -281,7 +279,7 @@ JSObject *
DOMProxyHandler::GetExpandoObject(JSObject *obj)
{
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
JS::Value v = js::GetProxyPrivate(obj);
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
if (v.isObject()) {
return &v.toObject();
}
@@ -302,12 +300,14 @@ ShadowingDOMProxyHandler::trace(JSTracer* trc, JSObject* proxy) const
DOMProxyHandler::trace(trc, proxy);
MOZ_ASSERT(IsDOMProxy(proxy), "expected a DOM proxy object");
JS::Value v = js::GetProxyPrivate(proxy);
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
MOZ_ASSERT(!v.isObject(), "Should not have expando object directly!");
// The proxy's private slot is set when we allocate the proxy,
// so it cannot be |undefined|.
MOZ_ASSERT(!v.isUndefined());
if (v.isUndefined()) {
// This can happen if we GC while creating our object, before we get a
// chance to set up its JSPROXYSLOT_EXPANDO slot.
return;
}
js::ExpandoAndGeneration* expandoAndGeneration =
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
+26 -20
View File
@@ -13,29 +13,35 @@
#include "js/Proxy.h"
#include "nsString.h"
#define DOM_PROXY_OBJECT_SLOT js::PROXY_PRIVATE_SLOT
namespace mozilla {
namespace dom {
/**
* DOM proxies store the expando object in the private slot.
*
* The expando object is a plain JSObject whose properties correspond to
* "expandos" (custom properties set by the script author).
*
* The exact value stored in the proxy's private slot depends on whether the
* interface is annotated with the [OverrideBuiltins] extended attribute.
*
* If it is, the proxy is initialized with a PrivateValue, which contains a
* pointer to a js::ExpandoAndGeneration object; this contains a pointer to
* the actual expando object as well as the "generation" of the object. The
* proxy handler will trace the expando object stored in the
* js::ExpandoAndGeneration while the proxy itself is alive.
*
* If it is not, the proxy is initialized with an UndefinedValue. In
* EnsureExpandoObject, it is set to an ObjectValue that points to the
* expando object directly. (It is set back to an UndefinedValue only when
* the object is about to die.)
*/
enum {
/**
* DOM proxies have an extra slot for the expando object at index
* JSPROXYSLOT_EXPANDO.
*
* The expando object is a plain JSObject whose properties correspond to
* "expandos" (custom properties set by the script author).
*
* The exact value stored in the JSPROXYSLOT_EXPANDO slot depends on whether
* the interface is annotated with the [OverrideBuiltins] extended attribute.
*
* If it is, the proxy is initialized with a PrivateValue, which contains a
* pointer to a js::ExpandoAndGeneration object; this contains a pointer to
* the actual expando object as well as the "generation" of the object. The
* proxy handler will trace the expando object stored in the
* js::ExpandoAndGeneration while the proxy itself is alive.
*
* If it is not, the proxy is initialized with an UndefinedValue. In
* EnsureExpandoObject, it is set to an ObjectValue that points to the
* expando object directly. (It is set back to an UndefinedValue only when
* the object is about to die.)
*/
JSPROXYSLOT_EXPANDO = 0
};
template<typename T> struct Prefable;
-78
View File
@@ -101,7 +101,6 @@ struct StringArrayAppender
} // namespace dom
class ErrorResult;
class OOMReporter;
namespace binding_danger {
@@ -162,7 +161,6 @@ public:
}
operator ErrorResult&();
operator OOMReporter&();
void Throw(nsresult rv) {
MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
@@ -557,82 +555,6 @@ class IgnoredErrorResult :
{
};
namespace dom {
namespace binding_detail {
class FastErrorResult :
public mozilla::binding_danger::TErrorResult<
mozilla::binding_danger::JustAssertCleanupPolicy>
{
};
} // namespace binding_detail
} // namespace dom
// This part is a bit annoying. We want an OOMReporter class that has the
// following properties:
//
// 1) Can be cast to from any ErrorResult-like type.
// 2) Has a fast destructor (because we want to use it from bindings).
// 3) Won't be randomly instantiated by non-binding code (because the fast
// destructor is not so safe.
// 4) Doesn't look ugly on the callee side (e.g. isn't in the binding_detail or
// binding_danger namespace).
//
// We do this by having two classes: The class callees should use, which has the
// things we want and a private constructor, and a friend subclass in the
// binding_danger namespace that can be used to construct it.
namespace binding_danger {
class OOMReporterInstantiator;
} // namespace binding_danger
class OOMReporter : private dom::binding_detail::FastErrorResult
{
public:
void ReportOOM()
{
Throw(NS_ERROR_OUT_OF_MEMORY);
}
private:
// OOMReporterInstantiator is a friend so it can call our constructor and
// MaybeSetPendingException.
friend class binding_danger::OOMReporterInstantiator;
// TErrorResult is a friend so its |operator OOMReporter&()| can work.
template<typename CleanupPolicy>
friend class binding_danger::TErrorResult;
OOMReporter()
: dom::binding_detail::FastErrorResult()
{
}
};
namespace binding_danger {
class OOMReporterInstantiator : public OOMReporter
{
public:
OOMReporterInstantiator()
: OOMReporter()
{
}
// We want to be able to call MaybeSetPendingException from codegen. The one
// on OOMReporter is not callable directly, because it comes from a private
// superclass. But we're a friend, so _we_ can call it.
bool MaybeSetPendingException(JSContext* cx)
{
return OOMReporter::MaybeSetPendingException(cx);
}
};
} // namespace binding_danger
template<typename CleanupPolicy>
binding_danger::TErrorResult<CleanupPolicy>::operator OOMReporter&()
{
return *static_cast<OOMReporter*>(
reinterpret_cast<TErrorResult<JustAssertCleanupPolicy>*>(this));
}
/******************************************************************************
** Macros for checking results
******************************************************************************/
+1
View File
@@ -111,3 +111,4 @@ MSG_DEF(MSG_PMO_INVALID_MEMBERS, 0, JSEXN_TYPEERR, "PerformanceMeasureOptions ca
MSG_DEF(MSG_PMO_CONSTRUCTOR_INACCESSIBLE, 0, JSEXN_TYPEERR, "Can't access PerformanceMark constructor, performance is null.")
MSG_DEF(MSG_PMO_UNEXPECTED_START_TIME, 0, JSEXN_TYPEERR, "Expected startTime >= 0.")
MSG_DEF(MSG_PMO_INVALID_ATTR_FOR_NON_GLOBAL, 1, JSEXN_TYPEERR, "Cannot get PerformanceTiming attribute values for non-Window global object. Given: {0}.")
MSG_DEF(MSG_NOT_SUBMIT_BUTTON, 0, JSEXN_TYPEERR, "The submitter is not a submit button.")
-1
View File
@@ -46,7 +46,6 @@ SimpleGlobal_finalize(js::FreeOp *fop, JSObject *obj)
{
SimpleGlobalObject* globalObject =
static_cast<SimpleGlobalObject*>(JS_GetPrivate(obj));
globalObject->ClearWrapper(obj);
NS_RELEASE(globalObject);
}
+1 -1
View File
@@ -86,7 +86,7 @@ private:
virtual ~SimpleGlobalObject()
{
MOZ_ASSERT(!GetWrapperMaybeDead());
ClearWrapper();
}
const GlobalType mType;
+1 -1
View File
@@ -131,7 +131,7 @@ ToJSValue(JSContext* aCx,
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
aValue.setObjectOrNull(aArgument.Callback(aCx));
aValue.setObject(*aArgument.Callback());
return MaybeWrapValue(aCx, aValue);
}
+10 -17
View File
@@ -4116,19 +4116,15 @@ class IDLAttribute(IDLInterfaceMember):
def handleExtendedAttribute(self, attr):
identifier = attr.identifier()
if ((identifier == "SetterThrows" or identifier == "SetterCanOOM")
and self.readonly):
if identifier == "SetterThrows" and self.readonly:
raise WebIDLError("Readonly attributes must not be flagged as "
"[%s]" % identifier,
"[SetterThrows]",
[self.location])
elif (((identifier == "Throws" or identifier == "GetterThrows" or
identifier == "CanOOM" or identifier == "GetterCanOOM") and
elif (((identifier == "Throws" or identifier == "GetterThrows") and
self.getExtendedAttribute("StoreInSlot")) or
(identifier == "StoreInSlot" and
(self.getExtendedAttribute("Throws") or
self.getExtendedAttribute("GetterThrows") or
self.getExtendedAttribute("CanOOM") or
self.getExtendedAttribute("GetterCanOOM")))):
self.getExtendedAttribute("GetterThrows")))):
raise WebIDLError("Throwing things can't be [StoreInSlot]",
[attr.location])
elif identifier == "LenientThis":
@@ -4291,9 +4287,6 @@ class IDLAttribute(IDLInterfaceMember):
identifier == "SetterThrows" or
identifier == "Throws" or
identifier == "GetterThrows" or
identifier == "SetterCanOOM" or
identifier == "CanOOM" or
identifier == "GetterCanOOM" or
identifier == "ChromeOnly" or
identifier == "Func" or
identifier == "SecureContext" or
@@ -4951,12 +4944,13 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def handleExtendedAttribute(self, attr):
identifier = attr.identifier()
if (identifier == "GetterThrows" or
identifier == "SetterThrows" or
identifier == "GetterCanOOM" or
identifier == "SetterCanOOM"):
if identifier == "GetterThrows":
raise WebIDLError("Methods must not be flagged as "
"[%s]" % identifier,
"[GetterThrows]",
[attr.location, self.location])
elif identifier == "SetterThrows":
raise WebIDLError("Methods must not be flagged as "
"[SetterThrows]",
[attr.location, self.location])
elif identifier == "Unforgeable":
if self.isStatic():
@@ -5029,7 +5023,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
"attribute, setter, and deleter",
[attr.location, self.location])
elif (identifier == "Throws" or
identifier == "CanOOM" or
identifier == "NewObject" or
identifier == "ChromeOnly" or
identifier == "UnsafeInPrerendering" or
-8
View File
@@ -74,7 +74,6 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/Conversions.h"
#include "js/HeapAPI.h"
#include "mozilla/Alignment.h"
#include "mozilla/Assertions.h"
@@ -122,7 +121,6 @@
#include "nsFontMetrics.h"
#include "Units.h"
#include "CanvasUtils.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "nsStyleSet.h"
#include "mozilla/layers/CanvasClient.h"
@@ -1749,12 +1747,6 @@ CanvasRenderingContext2D::RegisterAllocation()
if (context) {
JS_updateMallocCounter(context, mWidth * mHeight * 4);
}
JSObject* wrapper = GetWrapperPreserveColor();
if (wrapper) {
CycleCollectedJSContext::Get()->
AddZoneWaitingForGC(JS::GetObjectZone(wrapper));
}
}
static already_AddRefed<LayerManager>
+76 -14
View File
@@ -9,6 +9,7 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsPrintfCString.h"
#include "WebGLActiveInfo.h"
#include "WebGLBuffer.h"
#include "WebGLContextUtils.h"
#include "WebGLFramebuffer.h"
@@ -27,6 +28,30 @@ namespace mozilla {
// For a Tegra workaround.
static const int MAX_DRAW_CALLS_SINCE_FLUSH = 100;
static uint8_t
NumUsedLocationsByElemTypeForDraw(GLenum elemType)
{
switch (elemType) {
case LOCAL_GL_FLOAT_MAT2:
case LOCAL_GL_FLOAT_MAT2x3:
case LOCAL_GL_FLOAT_MAT2x4:
return 2;
case LOCAL_GL_FLOAT_MAT3x2:
case LOCAL_GL_FLOAT_MAT3:
case LOCAL_GL_FLOAT_MAT3x4:
return 3;
case LOCAL_GL_FLOAT_MAT4x2:
case LOCAL_GL_FLOAT_MAT4x3:
case LOCAL_GL_FLOAT_MAT4:
return 4;
default:
return 1;
}
}
////////////////////////////////////////
class ScopedResolveTexturesForDraw
@@ -331,6 +356,7 @@ class ScopedDrawHelper final
{
WebGLContext* const mWebGL;
bool mDidFake;
std::vector<GLuint> mDisabledUnusedAttribs;
public:
ScopedDrawHelper(WebGLContext* webgl, const char* funcName, uint32_t firstVertex,
@@ -367,11 +393,43 @@ public:
}
mDidFake = true;
const auto& linkInfo = mWebGL->mActiveProgramLinkInfo;
#ifdef XP_MACOSX
if (mWebGL->gl->WorkAroundDriverBugs()) {
std::vector<bool> isActiveAttrib(mWebGL->mBoundVertexArray->mAttribs.Length(),
false);
for (const auto& progAttrib : linkInfo->attribs) {
const auto loc = progAttrib.mLoc;
if (loc < 0) {
continue;
}
const auto usedLocs =
NumUsedLocationsByElemTypeForDraw(progAttrib.mActiveInfo->mElemType);
for (uint32_t i = 0; i < usedLocs; ++i) {
const auto usedLoc = static_cast<uint32_t>(loc) + i;
if (usedLoc < isActiveAttrib.size()) {
isActiveAttrib[usedLoc] = true;
}
}
}
for (uint32_t i = 0; i < mWebGL->mBoundVertexArray->mAttribs.Length(); ++i) {
const auto& attrib = mWebGL->mBoundVertexArray->mAttribs[i];
if (!attrib.mEnabled || isActiveAttrib[i]) {
continue;
}
mWebGL->gl->fDisableVertexAttribArray(i);
mDisabledUnusedAttribs.push_back(i);
}
}
#endif
////
// Check UBO sizes.
const auto& linkInfo = mWebGL->mActiveProgramLinkInfo;
for (const auto& cur : linkInfo->uniformBlocks) {
const auto& dataSize = cur->mDataSize;
const auto& binding = cur->mBinding;
@@ -477,6 +535,10 @@ public:
if (mDidFake) {
mWebGL->UndoFakeVertexAttrib0();
}
for (const auto loc : mDisabledUnusedAttribs) {
mWebGL->gl->fEnableVertexAttribArray(loc);
}
}
};
@@ -607,12 +669,12 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
return;
MakeContextCurrent();
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
bool error = false;
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
@@ -855,12 +917,12 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type,
return;
MakeContextCurrent();
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
bool error = false;
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
+3 -6
View File
@@ -176,6 +176,8 @@ public:
void
Trace(const TraceCallbacks& aCallbacks, void* aClosure)
{
AssertIsOnOwningThread();
ConsoleCallData* tmp = this;
for (uint32_t i = 0; i < mCopiedArguments.Length(); ++i) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCopiedArguments[i])
@@ -2276,16 +2278,11 @@ Console::NotifyHandler(JSContext* aCx, const Sequence<JS::Value>& aArguments,
JS::Rooted<JS::Value> value(aCx);
JS::Rooted<JSObject*> callable(aCx, mConsoleEventNotifier->CallableOrNull());
if (NS_WARN_IF(!callable)) {
return;
}
// aCx and aArguments are in the same compartment because this method is
// called directly when a Console.something() runs.
// mConsoleEventNotifier->Callable() is the scope where value will be sent to.
if (NS_WARN_IF(!PopulateConsoleNotificationInTheTargetScope(aCx, aArguments,
callable,
mConsoleEventNotifier->Callable(),
&value,
aCallData))) {
return;
+1 -1
View File
@@ -322,7 +322,7 @@ DOMEventTargetHelper::GetEventHandler(nsIAtom* aType,
{
EventHandlerNonNull* handler = GetEventHandler(aType, EmptyString());
if (handler) {
*aValue = JS::ObjectValue(*handler->Callback(aCx));
*aValue = JS::ObjectValue(*handler->Callable());
} else {
*aValue = JS::NullValue();
}
+1 -7
View File
@@ -1533,16 +1533,10 @@ EventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
} else {
eventType.Assign(Substring(nsDependentAtomString(listener.mTypeAtom), 2));
}
nsCOMPtr<nsIDOMEventListener> callback = listener.mListener.ToXPCOMCallback();
if (!callback) {
// This will be null for cross-compartment event listeners which have been
// destroyed.
continue;
}
// EventListenerInfo is defined in XPCOM, so we have to go ahead
// and convert to an XPCOM callback here...
RefPtr<EventListenerInfo> info =
new EventListenerInfo(eventType, callback.forget(),
new EventListenerInfo(eventType, listener.mListener.ToXPCOMCallback(),
listener.mFlags.mCapture,
listener.mFlags.mAllowUntrustedEvents,
listener.mFlags.mInSystemGroup);
+7 -8
View File
@@ -137,7 +137,7 @@ EventListenerInfo::GetJSVal(JSContext* aCx,
nsCOMPtr<JSEventHandler> jsHandler = do_QueryInterface(mListener);
if (jsHandler && jsHandler->GetTypedEventHandler().HasEventHandler()) {
JS::Handle<JSObject*> handler =
jsHandler->GetTypedEventHandler().Ptr()->CallableOrNull();
jsHandler->GetTypedEventHandler().Ptr()->Callable();
if (handler) {
aAc.emplace(aCx, handler);
aJSVal.setObject(*handler);
@@ -376,13 +376,12 @@ EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarg
&EventListenerService::NotifyPendingChanges));
}
RefPtr<EventListenerChange> changes =
mPendingListenerChangesSet.LookupForAdd(aTarget).OrInsert(
[this, aTarget] () {
EventListenerChange* c = new EventListenerChange(aTarget);
mPendingListenerChanges->AppendElement(c, false);
return c;
});
RefPtr<EventListenerChange> changes = mPendingListenerChangesSet.Get(aTarget);
if (!changes) {
changes = new EventListenerChange(aTarget);
mPendingListenerChanges->AppendElement(changes, false);
mPendingListenerChangesSet.Put(aTarget, changes);
}
changes->AddChangedListenerName(aName);
}
+7 -2
View File
@@ -4366,8 +4366,13 @@ EventStateManager::GetWrapperByEventID(WidgetMouseEvent* aEvent)
}
return mMouseEnterLeaveHelper;
}
return mPointersEnterLeaveHelper.LookupForAdd(pointer->pointerId).OrInsert(
[] () { return new OverOutElementsWrapper(); });
RefPtr<OverOutElementsWrapper> helper;
if (!mPointersEnterLeaveHelper.Get(pointer->pointerId, getter_AddRefs(helper))) {
helper = new OverOutElementsWrapper();
mPointersEnterLeaveHelper.Put(pointer->pointerId, helper);
}
return helper;
}
/* static */ void
-8
View File
@@ -884,10 +884,6 @@ IMEContentObserver::CharacterDataWillChange(nsIDocument* aDocument,
{
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
"character data changed for non-text node");
if (!aContent->IsNodeOfType(nsINode::eTEXT)) {
return; // Ignore if it's a comment node or something other invisible data
// node.
}
MOZ_ASSERT(mPreCharacterDataChangeLength < 0,
"CharacterDataChanged() should've reset "
"mPreCharacterDataChangeLength");
@@ -907,10 +903,6 @@ IMEContentObserver::CharacterDataChanged(nsIDocument* aDocument,
nsIContent* aContent,
CharacterDataChangeInfo* aInfo)
{
if (!aContent->IsNodeOfType(nsINode::eTEXT)) {
return; // Ignore if it's a comment node or something other invisible data
// node.
}
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
"character data changed for non-text node");
+1 -40
View File
@@ -772,21 +772,6 @@ GetFileHandleThreadPoolFor(FileHandleStorage aStorage)
}
}
nsresult ClampResultCode(nsresult aResultCode) {
if (NS_SUCCEEDED(aResultCode) ||
NS_ERROR_GET_MODULE(aResultCode) == NS_ERROR_MODULE_DOM_FILEHANDLE) {
return aResultCode;
}
NS_WARNING(nsPrintfCString("Converting non-filehandle error code (0x%" PRIX32
") to "
"NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR",
static_cast<uint32_t>(aResultCode))
.get());
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
}
} // namespace
/*******************************************************************************
@@ -2107,8 +2092,7 @@ NormalFileHandleOp::SendFailureResult(nsresult aResultCode)
if (!IsActorDestroyed()) {
result =
PBackgroundFileRequestParent::Send__delete__(
this, ClampResultCode(aResultCode));
PBackgroundFileRequestParent::Send__delete__(this, aResultCode);
}
DEBUGONLY(mResponseSent = true;)
@@ -2270,10 +2254,6 @@ CopyFileHandleOp::DoFileWork(FileHandle* aFileHandle)
mOwningThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
} while (true);
if (mOffset < mSize) {
// end-of-file reached
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(mOffset == mSize);
if (mRead) {
@@ -2598,25 +2578,6 @@ TruncateOp::DoFileWork(FileHandle* aFileHandle)
nsCOMPtr<nsISeekableStream> sstream = do_QueryInterface(mFileStream);
MOZ_ASSERT(sstream);
if (mParams.offset()) {
nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mFileStream);
MOZ_ASSERT(fileMetadata);
int64_t size;
nsresult rv = fileMetadata->GetSize(&size);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(size >= 0);
if (mParams.offset() > static_cast<uint64_t>(size)) {
// Cannot extend the size of a file through truncate.
return NS_ERROR_DOM_INVALID_MODIFICATION_ERR;
}
}
// XXX If we allowed truncate to extend the file size, we would to ensure that
// the quota limit is checked, e.g. by making FileQuotaStream override Seek.
nsresult rv = sstream->Seek(nsISeekableStream::NS_SEEK_SET, mParams.offset());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
+9 -6
View File
@@ -110,12 +110,15 @@ DocAllResultMatch(Element* aElement, int32_t aNamespaceID, nsIAtom* aAtom,
nsContentList*
HTMLAllCollection::GetDocumentAllList(const nsAString& aID)
{
return mNamedMap.LookupForAdd(aID).OrInsert(
[this, &aID] () {
nsCOMPtr<nsIAtom> id = NS_Atomize(aID);
return new nsContentList(mDocument, DocAllResultMatch, nullptr,
nullptr, true, id);
});
if (nsContentList* docAllList = mNamedMap.GetWeak(aID)) {
return docAllList;
}
nsCOMPtr<nsIAtom> id = NS_Atomize(aID);
RefPtr<nsContentList> docAllList =
new nsContentList(mDocument, DocAllResultMatch, nullptr, nullptr, true, id);
mNamedMap.Put(aID, docAllList);
return docAllList;
}
void
+35
View File
@@ -276,6 +276,41 @@ HTMLFormElement::Submit()
return rv.StealNSResult();
}
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
void
HTMLFormElement::RequestSubmit(nsGenericHTMLElement* aSubmitter,
ErrorResult& aRv) {
// 1. If submitter is not null, then:
if (aSubmitter) {
nsCOMPtr<nsIFormControl> fc = do_QueryObject(aSubmitter);
// 1.1. If submitter is not a submit button, then throw a TypeError.
if (!fc || !fc->IsSubmitControl()) {
aRv.ThrowTypeError<MSG_NOT_SUBMIT_BUTTON>();
return;
}
// 1.2. If submitter's form owner is not this form element, then throw a
// "NotFoundError" DOMException.
if (fc->GetFormElement() != this) {
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return;
}
}
// 2. Otherwise, set submitter to this form element.
// 3. Submit this form element, from submitter.
// We go through the presShell here for the corner case a submit event
// is pending while the window is being destroyed.
InternalFormEvent event(true, eFormSubmit);
event.mOriginator = aSubmitter;
nsEventStatus status = nsEventStatus_eIgnore;
nsCOMPtr<nsIPresShell> presShell = GetComposedDoc()->GetShell();
if (MOZ_LIKELY(presShell)) {
presShell->HandleDOMEventWithTarget(this, &event, &status);
}
}
NS_IMETHODIMP
HTMLFormElement::Reset()
{
+13
View File
@@ -391,6 +391,19 @@ public:
void Submit(ErrorResult& aRv);
/**
* Requests to submit the form. Unlike submit(), this method includes
* interactive constraint validation and firing a submit event,
* either of which can cancel submission.
*
* @param aSubmitter The submitter argument can be used to point to a specific
* submit button.
* @param aRv An ErrorResult.
* @see
* https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
*/
void RequestSubmit(nsGenericHTMLElement* aSubmitter, ErrorResult& aRv);
// XPCOM Reset() is OK
bool CheckValidity()
-8
View File
@@ -5093,14 +5093,6 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType, bool aNotify)
uint8_t oldType = mType;
MOZ_ASSERT(oldType != aNewType);
nsFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
// Input element can represent very different kinds of UIs, and we may
// need to flush styling even when focusing the already focused input
// element.
fm->NeedsFlushBeforeEventHandling(this);
}
if (aNewType == NS_FORM_INPUT_FILE || oldType == NS_FORM_INPUT_FILE) {
// Strictly speaking, we only need to clear files on going _to_ or _from_
// the NS_FORM_INPUT_FILE type, not both, since we'll never confuse values
-4
View File
@@ -3977,10 +3977,6 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
NotifyOwnerDocumentActivityChanged();
UpdateAudioChannelPlayingState();
if (mPausedForInactiveDocumentOrChannel) {
mDecoder->Suspend();
}
if (!mPaused) {
SetPlayedOrSeeked(true);
if (!mPausedForInactiveDocumentOrChannel) {
+14 -47
View File
@@ -105,22 +105,6 @@ namespace indexedDB {
[1, 2] // 0x60 bf f0 0 0 0 0 0 0 0x10 c0
[[]] // 0x80
*/
// |aPos| should point to the type indicator.
// The returned length doesn't include the type indicator
// or the terminator.
static size_t LengthOfEncodedBinary(const unsigned char* aPos,
const unsigned char* aEnd) {
MOZ_ASSERT(*aPos % Key::eMaxType == Key::eBinary, "Don't call me!");
auto iter = ++aPos;
for (; iter < aEnd && *iter != Key::eTerminator; ++iter) {
if (*iter & 0x80) {
iter++;
}
}
return iter - aPos;
}
nsresult
Key::ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const
{
@@ -145,16 +129,11 @@ Key::ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const
bool canShareBuffers = true;
while (it < end) {
auto type = *it % eMaxType;
if (type == eTerminator) {
if (type == eTerminator || type == eArray) {
it++;
} else if (type == eFloat || type == eDate) {
it++;
it += std::min(sizeof(uint64_t), size_t(end - it));
} else if (type == eBinary) {
// skip all binary data
auto binaryLength = LengthOfEncodedBinary(it, end);
it++;
it += binaryLength;
} else {
// We have a string!
canShareBuffers = false;
@@ -176,7 +155,9 @@ Key::ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const
return NS_ERROR_OUT_OF_MEMORY;
}
std::copy(start, it, buffer);
while (start < it) {
*(buffer++) = *(start++);
}
}
// Now continue decoding
@@ -185,38 +166,24 @@ Key::ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const
uint32_t oldLen = aTarget.mBuffer.Length();
auto type = *it % eMaxType;
// Note: Do not modify |it| before calling |updateBufferAndIter|;
// |byteCount| doesn't include the type indicator
auto updateBufferAndIter = [&](size_t byteCount) -> bool {
if (!aTarget.mBuffer.GetMutableData(&buffer, oldLen + 1 + byteCount)) {
return false;
}
buffer += oldLen;
// should also copy the type indicator at the begining
std::copy_n(it, byteCount + 1, buffer);
it += (byteCount + 1);
return true;
};
if (type == eTerminator) {
if (type == eTerminator || type == eArray) {
// Copy array TypeID and terminator from raw key
if (!updateBufferAndIter(0)) {
if (!aTarget.mBuffer.GetMutableData(&buffer, oldLen + 1)) {
return NS_ERROR_OUT_OF_MEMORY;
}
*(buffer + oldLen) = *(it++);
} else if (type == eFloat || type == eDate) {
// Copy number from raw key
const size_t byteCount = std::min(sizeof(uint64_t), size_t(end - it - 1));
if (!updateBufferAndIter(byteCount)) {
if (!aTarget.mBuffer.GetMutableData(&buffer,
oldLen + 1 + sizeof(uint64_t))) {
return NS_ERROR_OUT_OF_MEMORY;
}
} else if (type == eBinary) {
// skip all binary data
auto binaryLength = LengthOfEncodedBinary(it, end);
buffer += oldLen;
*(buffer++) = *(it++);
if (!updateBufferAndIter(binaryLength)) {
return NS_ERROR_OUT_OF_MEMORY;
const size_t byteCount = std::min(sizeof(uint64_t), size_t(end - it));
for (size_t count = 0; count < byteCount; count++) {
*(buffer++) = (*it++);
}
} else {
// Decode string and reencode
+51 -11
View File
@@ -371,6 +371,9 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(TrackType aTrack)
case TrackType::kVideoTrack: {
// Decoders use the layers backend to decide if they can use hardware decoding,
// so specify LAYERS_NONE if we want to forcibly disable it.
using Option = CreateDecoderParams::Option;
using OptionSet = CreateDecoderParams::OptionSet;
data.mDecoder = mOwner->mPlatform->CreateDecoder({
ownerData.mInfo
? *ownerData.mInfo->GetAsVideoInfo()
@@ -383,7 +386,10 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(TrackType aTrack)
mOwner->mCrashHelper,
#endif
ownerData.mIsBlankDecode,
&result
&result,
OptionSet(ownerData.mHardwareDecodingDisabled
? Option::HardwareDecoderNotAllowed
: Option::Default)
});
break;
}
@@ -921,6 +927,8 @@ MediaFormatReader::NotifyNewOutput(TrackType aTrack, MediaData* aSample)
decoder.mOutput.AppendElement(aSample);
decoder.mNumSamplesOutput++;
decoder.mNumOfConsecutiveError = 0;
// We have decoded our first frame, we can now start to skip future errors.
decoder.mFirstFrameTime.reset();
ScheduleUpdate(aTrack);
}
@@ -1415,7 +1423,7 @@ MediaFormatReader::Update(TrackType aTrack)
RefPtr<MediaData> output = decoder.mOutput[0];
decoder.mOutput.RemoveElementAt(0);
decoder.mSizeOfQueue -= 1;
decoder.mLastSampleTime =
decoder.mLastDecodedSampleTime =
Some(TimeInterval(TimeUnit::FromMicroseconds(output->mTime),
TimeUnit::FromMicroseconds(output->GetEndTime())));
decoder.mNumSamplesOutputTotal++;
@@ -1463,14 +1471,14 @@ MediaFormatReader::Update(TrackType aTrack)
LOG("Rejecting %s promise: EOS", TrackTypeToStr(aTrack));
decoder.RejectPromise(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
} else if (decoder.mWaitingForData) {
if (wasDraining && decoder.mLastSampleTime &&
if (wasDraining && decoder.mLastDecodedSampleTime &&
!decoder.mNextStreamSourceID) {
// We have completed draining the decoder following WaitingForData.
// Set up the internal seek machinery to be able to resume from the
// last sample decoded.
LOG("Seeking to last sample time: %lld",
decoder.mLastSampleTime.ref().mStart.ToMicroseconds());
InternalSeek(aTrack, InternalSeekTarget(decoder.mLastSampleTime.ref(), true));
decoder.mLastDecodedSampleTime.ref().mStart.ToMicroseconds());
InternalSeek(aTrack, InternalSeekTarget(decoder.mLastDecodedSampleTime.ref(), true));
}
if (!decoder.mReceivedNewData) {
LOG("Rejecting %s promise: WAITING_FOR_DATA", TrackTypeToStr(aTrack));
@@ -1506,24 +1514,52 @@ MediaFormatReader::Update(TrackType aTrack)
if (decoder.mError && !decoder.HasFatalError()) {
decoder.mDecodePending = false;
bool needsNewDecoder = decoder.mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER;
MOZ_RELEASE_ASSERT(!decoder.HasInternalSeekPending(),
"No error can occur while an internal seek is pending");
nsCString error;
bool firstFrameDecodingFailedWithHardware =
decoder.mFirstFrameTime &&
decoder.mError.ref() == NS_ERROR_DOM_MEDIA_DECODE_ERR &&
decoder.mDecoder && decoder.mDecoder->IsHardwareAccelerated(error) &&
!decoder.mHardwareDecodingDisabled;
bool needsNewDecoder =
decoder.mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER ||
firstFrameDecodingFailedWithHardware;
if (!needsNewDecoder && ++decoder.mNumOfConsecutiveError > decoder.mMaxConsecutiveError) {
NotifyError(aTrack, decoder.mError.ref());
return;
}
if (firstFrameDecodingFailedWithHardware) {
decoder.mHardwareDecodingDisabled = true;
}
decoder.mError.reset();
LOG("%s decoded error count %d", TrackTypeToStr(aTrack),
decoder.mNumOfConsecutiveError);
if (needsNewDecoder) {
LOG("Error: Need new decoder");
decoder.ShutdownDecoder();
}
if (decoder.mFirstFrameTime) {
TimeInterval seekInterval = TimeInterval(decoder.mFirstFrameTime.ref(),
decoder.mFirstFrameTime.ref());
InternalSeek(aTrack, InternalSeekTarget(seekInterval, false));
return;
}
media::TimeUnit nextKeyframe;
if (aTrack == TrackType::kVideoTrack && !decoder.HasInternalSeekPending() &&
NS_SUCCEEDED(decoder.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe))) {
if (needsNewDecoder) {
decoder.ShutdownDecoder();
}
SkipVideoDemuxToNextKeyFrame(decoder.mLastSampleTime.refOr(TimeInterval()).Length());
NS_SUCCEEDED(decoder.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe)) &&
!nextKeyframe.IsInfinite()) {
SkipVideoDemuxToNextKeyFrame(decoder.mLastDecodedSampleTime.refOr(TimeInterval()).Length());
return;
} else if (aTrack == TrackType::kAudioTrack) {
decoder.Flush();
} else {
// We can't recover from this error.
NotifyError(aTrack, NS_ERROR_DOM_MEDIA_FATAL_ERR);
}
}
@@ -1664,6 +1700,7 @@ MediaFormatReader::ResetDecode(TrackSet aTracks)
if (HasVideo() && aTracks.contains(TrackInfo::kVideoTrack)) {
mVideo.ResetDemuxer();
mVideo.mFirstFrameTime = Some(media::TimeUnit());
Reset(TrackInfo::kVideoTrack);
if (mVideo.HasPromise()) {
mVideo.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
@@ -1672,6 +1709,7 @@ MediaFormatReader::ResetDecode(TrackSet aTracks)
if (HasAudio() && aTracks.contains(TrackInfo::kAudioTrack)) {
mAudio.ResetDemuxer();
mVideo.mFirstFrameTime = Some(media::TimeUnit());
Reset(TrackInfo::kAudioTrack);
if (mAudio.HasPromise()) {
mAudio.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
@@ -2030,6 +2068,7 @@ MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
LOGV("Video seeked to %lld", aTime.ToMicroseconds());
mVideo.mSeekRequest.Complete();
mVideo.mFirstFrameTime = Some(aTime);
mPreviousDecodedKeyframeTime_us = sNoPreviousDecodedKeyframe;
SetVideoDecodeThreshold();
@@ -2111,6 +2150,7 @@ MediaFormatReader::OnAudioSeekCompleted(media::TimeUnit aTime)
MOZ_ASSERT(OnTaskQueue());
LOGV("Audio seeked to %lld", aTime.ToMicroseconds());
mAudio.mSeekRequest.Complete();
mAudio.mFirstFrameTime = Some(aTime);
mPendingSeekTime.reset();
mSeekPromise.Resolve(aTime, __func__);
}
+11 -3
View File
@@ -235,6 +235,7 @@ private:
, mDrainComplete(false)
, mNumOfConsecutiveError(0)
, mMaxConsecutiveError(aNumOfMaxError)
, mFirstFrameTime(Some(media::TimeUnit()))
, mNumSamplesInput(0)
, mNumSamplesOutput(0)
, mNumSamplesOutputTotal(0)
@@ -243,6 +244,7 @@ private:
, mIsHardwareAccelerated(false)
, mLastStreamSourceID(UINT32_MAX)
, mIsBlankDecode(false)
, mHardwareDecodingDisabled(false)
{}
MediaFormatReader* mOwner;
@@ -316,6 +318,11 @@ private:
uint32_t mNumOfConsecutiveError;
uint32_t mMaxConsecutiveError;
// Set when we haven't yet decoded the first frame.
// Cleared once the first frame has been decoded.
// This is used to determine, upon error, if we should try again to decode
// the frame, or skip to the next keyframe.
Maybe<media::TimeUnit> mFirstFrameTime;
Maybe<MediaResult> mError;
bool HasFatalError() const
@@ -341,8 +348,8 @@ private:
// Used for internal seeking when a change of stream is detected or when
// encountering data discontinuity.
Maybe<InternalSeekTarget> mTimeThreshold;
// Time of last sample returned.
Maybe<media::TimeInterval> mLastSampleTime;
// Time of last decoded sample returned.
Maybe<media::TimeInterval> mLastDecodedSampleTime;
// Decoded samples returned my mDecoder awaiting being returned to
// state machine upon request.
@@ -405,7 +412,7 @@ private:
mDraining = false;
mDrainComplete = false;
mTimeThreshold.reset();
mLastSampleTime.reset();
mLastDecodedSampleTime.reset();
mOutput.Clear();
mNumSamplesInput = 0;
mNumSamplesOutput = 0;
@@ -437,6 +444,7 @@ private:
Maybe<media::TimeUnit> mFirstDemuxedSampleTime;
// Use BlankDecoderModule or not.
bool mIsBlankDecode;
bool mHardwareDecodingDisabled;
};
+1
View File
@@ -7,6 +7,7 @@
#define GMP_DEVICE_BINDING_h_
#include <string>
#include <cstdint>
namespace mozilla {
namespace gmp {
@@ -963,7 +963,7 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
// 1. Update the duration attribute if it currently equals NaN.
// Those steps are performed by the MediaSourceDecoder::SetInitialDuration
AbstractThread::MainThread()->Dispatch(NewRunnableMethod<int64_t>
(mParentDecoder.get(),
(mParentDecoder,
&MediaSourceDecoder::SetInitialDuration,
duration ? duration : -1));
@@ -10,6 +10,7 @@
#include "ImageContainer.h"
#include "MediaDecoderReader.h"
#include "MediaInfo.h"
#include "mozilla/EnumSet.h"
#include "mozilla/MozPromise.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/KnowsCompositor.h"
@@ -47,6 +48,13 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
: mConfig(aConfig)
{}
enum class Option
{
Default,
HardwareDecoderNotAllowed,
};
using OptionSet = EnumSet<Option>;
template <typename T1, typename... Ts>
CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
: mConfig(aConfig)
@@ -85,6 +93,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
RefPtr<GMPCrashHelper> mCrashHelper;
#endif
bool mUseBlankDecoder = false;
OptionSet mOptions = OptionSet(Option::Default);
private:
void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; }
@@ -96,6 +105,7 @@ private:
void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
#endif
void Set(bool aUseBlankDecoder) { mUseBlankDecoder = aUseBlankDecoder; }
void Set(OptionSet aOptions) { mOptions = aOptions; }
void Set(layers::KnowsCompositor* aKnowsCompositor) { mKnowsCompositor = aKnowsCompositor; }
template <typename T1, typename T2, typename... Ts>
void Set(T1&& a1, T2&& a2, Ts&&... args)
@@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VPXDecoder.h"
#include "mp4_demuxer/BitReader.h"
#include "gfx2DGlue.h"
#include "nsError.h"
#include "TimeUnits.h"
@@ -383,5 +384,32 @@ VPXDecoder::GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec)
return nsIntSize(si.w, si.h);
}
/* static */
int
VPXDecoder::GetVP9Profile(Span<const uint8_t> aBuffer)
{
if (aBuffer.Length() < 2) {
// Can't be good.
return -1;
}
mp4_demuxer::BitReader br(aBuffer.Elements(), aBuffer.Length() * 8);
uint32_t frameMarker = br.ReadBits(2); // frame_marker
if (frameMarker != 2) {
// That's not a valid vp9 header.
return -1;
}
uint32_t profile = br.ReadBits(1); // profile_low_bit
profile |= br.ReadBits(1) << 1; // profile_high_bit
if (profile == 3) {
profile += br.ReadBits(1); // reserved_zero
if (profile > 3) {
// reserved_zero wasn't zero.
return -1;
}
}
return profile;
}
} // namespace mozilla
#undef LOG
@@ -53,6 +53,10 @@ public:
// Return the frame dimensions for a sample for the specified codec.
static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec);
// Return the VP9 profile as per https://www.webmproject.org/vp9/profiles/
// Return negative value if error.
static int GetVP9Profile(Span<const uint8_t> aBuffer);
private:
void ProcessDecode(MediaRawData* aSample);
MediaResult DoDecode(MediaRawData* aSample);
@@ -40,11 +40,7 @@ AppleVTDecoder::AppleVTDecoder(const VideoInfo& aConfig,
, mMaxRefFrames(mp4_demuxer::H264::ComputeMaxRefFrames(aConfig.mExtraData))
, mImageContainer(aImageContainer)
, mIsShutDown(false)
#ifdef MOZ_WIDGET_UIKIT
, mUseSoftwareImages(true)
#else
, mUseSoftwareImages(false)
#endif
, mIsFlushing(false)
, mMonitor("AppleVideoDecoder")
, mFormat(nullptr)
@@ -356,7 +352,6 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
// Unlock the returned image data.
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
} else {
#ifndef MOZ_WIDGET_UIKIT
IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
MOZ_ASSERT(surface, "Decoder didn't return an IOSurface backed buffer");
@@ -373,9 +368,6 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
aFrameRef.is_sync_point,
aFrameRef.decode_timestamp.ToMicroseconds(),
visible);
#else
MOZ_ASSERT_UNREACHABLE("No MacIOSurface on iOS");
#endif
}
if (!data) {
+6 -5
View File
@@ -91,11 +91,12 @@ WMFDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
return nullptr;
}
nsAutoPtr<WMFVideoMFTManager> manager(
new WMFVideoMFTManager(aParams.VideoConfig(),
aParams.mKnowsCompositor,
aParams.mImageContainer,
sDXVAEnabled));
nsAutoPtr<WMFVideoMFTManager> manager(new WMFVideoMFTManager(
aParams.VideoConfig(),
aParams.mKnowsCompositor,
aParams.mImageContainer,
sDXVAEnabled && !aParams.mOptions.contains(
CreateDecoderParams::Option::HardwareDecoderNotAllowed)));
if (!manager->Init()) {
return nullptr;
+16 -1
View File
@@ -576,6 +576,16 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
return E_FAIL;
}
if (mStreamType == VP9 && aSample->mKeyframe) {
// Check the VP9 profile. the VP9 MFT can only handle correctly profile 0
// and 2 (yuv420 8/10/12 bits)
int profile =
VPXDecoder::GetVP9Profile(MakeSpan(aSample->Data(), aSample->Size()));
if (profile != 0 && profile != 2) {
return E_FAIL;
}
}
HRESULT hr = mDecoder->CreateInputSample(aSample->Data(),
uint32_t(aSample->Size()),
aSample->mTime,
@@ -990,7 +1000,12 @@ WMFVideoMFTManager::Output(int64_t aStreamOffset,
aOutData = frame;
// Set the potentially corrected pts and duration.
aOutData->mTime = pts.ToMicroseconds();
aOutData->mDuration = duration.ToMicroseconds();
// The VP9 decoder doesn't provide a valid duration. AS VP9 doesn't have a
// concept of pts vs dts and have no latency. We can as such use the last
// known input duration.
aOutData->mDuration = (mStreamType == VP9 && duration == media::TimeUnit())
? mLastDuration
: duration.ToMicroseconds();
if (mNullOutputCount) {
mGotValidOutputAfterNullOutput = true;
+39
View File
@@ -100,6 +100,45 @@ public:
uint32_t mChunksToProcess = 0;
};
/* static */ already_AddRefed<AnalyserNode>
AnalyserNode::Create(AudioContext& aAudioContext,
const AnalyserOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AnalyserNode> analyserNode = new AnalyserNode(&aAudioContext);
analyserNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetFftSize(aOptions.mFftSize, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetMinDecibels(aOptions.mMinDecibels, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetMaxDecibels(aOptions.mMaxDecibels, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
analyserNode->SetSmoothingTimeConstant(aOptions.mSmoothingTimeConstant, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return analyserNode.forget();
}
AnalyserNode::AnalyserNode(AudioContext* aContext)
: AudioNode(aContext,
1,
+15 -4
View File
@@ -14,16 +14,26 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct AnalyserOptions;
class AnalyserNode final : public AudioNode
{
public:
explicit AnalyserNode(AudioContext* aContext);
static already_AddRefed<AnalyserNode>
Create(AudioContext& aAudioContext, const AnalyserOptions& aOptions,
ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<AnalyserNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const AnalyserOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
void GetFloatFrequencyData(const Float32Array& aArray);
void GetByteFrequencyData(const Uint8Array& aArray);
void GetFloatTimeDomainData(const Float32Array& aArray);
@@ -61,10 +71,9 @@ public:
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
protected:
~AnalyserNode() {}
private:
~AnalyserNode() = default;
friend class AnalyserNodeEngine;
void AppendChunk(const AudioChunk& aChunk);
bool AllocateBuffer();
@@ -73,6 +82,8 @@ private:
void GetTimeDomainData(float* aData, size_t aLength);
private:
explicit AnalyserNode(AudioContext* aContext);
FFTBlock mAnalysisBlock;
nsTArray<AudioChunk> mChunks;
double mMinDecibels;
+18
View File
@@ -178,6 +178,24 @@ AudioBuffer::~AudioBuffer()
mozilla::DropJSObjects(this);
}
/* static */ already_AddRefed<AudioBuffer>
AudioBuffer::Constructor(const GlobalObject& aGlobal,
AudioContext& aAudioContext,
const AudioBufferOptions& aOptions,
ErrorResult& aRv)
{
if (!aOptions.mNumberOfChannels) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
float sampleRate = aOptions.mSampleRate.WasPassed()
? aOptions.mSampleRate.Value()
: aAudioContext.SampleRate();
return Create(&aAudioContext, aOptions.mNumberOfChannels, aOptions.mLength,
sampleRate, aRv);
}
void
AudioBuffer::ClearJSChannels()
{
+5 -1
View File
@@ -24,6 +24,7 @@ class ThreadSharedFloatArrayBufferList;
namespace dom {
struct AudioBufferOptions;
class AudioContext;
/**
@@ -56,6 +57,10 @@ public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AudioBuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioBuffer)
static already_AddRefed<AudioBuffer>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const AudioBufferOptions& aOptions, ErrorResult& aRv);
nsPIDOMWindowInner* GetParentObject() const
{
nsCOMPtr<nsPIDOMWindowInner> parentObject = do_QueryReferent(mOwnerWindow);
@@ -134,4 +139,3 @@ protected:
} // namespace mozilla
#endif
+22 -2
View File
@@ -607,10 +607,30 @@ AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
mStream->AddMainThreadListener(this);
}
AudioBufferSourceNode::~AudioBufferSourceNode()
/* static */ already_AddRefed<AudioBufferSourceNode>
AudioBufferSourceNode::Create(JSContext* aCx, AudioContext& aAudioContext,
const AudioBufferSourceOptions& aOptions,
ErrorResult& aRv)
{
}
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AudioBufferSourceNode> audioNode = new AudioBufferSourceNode(&aAudioContext);
if (aOptions.mBuffer.WasPassed()) {
MOZ_ASSERT(aCx);
audioNode->SetBuffer(aCx, aOptions.mBuffer.Value());
}
audioNode->Detune()->SetValue(aOptions.mDetune);
audioNode->SetLoop(aOptions.mLoop);
audioNode->SetLoopEnd(aOptions.mLoopEnd);
audioNode->SetLoopStart(aOptions.mLoopStart);
audioNode->PlaybackRate()->SetValue(aOptions.mPlaybackRate);
return audioNode.forget();
}
void
AudioBufferSourceNode::DestroyMediaStream()
{
+16 -8
View File
@@ -12,13 +12,16 @@
namespace mozilla {
namespace dom {
struct AudioBufferSourceOptions;
class AudioParam;
class AudioBufferSourceNode final : public AudioNode,
public MainThreadMediaStreamListener
class AudioBufferSourceNode final : public AudioNode
, public MainThreadMediaStreamListener
{
public:
explicit AudioBufferSourceNode(AudioContext* aContext);
static already_AddRefed<AudioBufferSourceNode>
Create(JSContext* aCx, AudioContext& aAudioContext,
const AudioBufferSourceOptions& aOptions, ErrorResult& aRv);
void DestroyMediaStream() override;
@@ -33,6 +36,13 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode, AudioNode)
static already_AddRefed<AudioBufferSourceNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const AudioBufferSourceOptions& aOptions, ErrorResult& aRv)
{
return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void Start(double aWhen, double aOffset,
@@ -98,10 +108,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
protected:
virtual ~AudioBufferSourceNode();
private:
explicit AudioBufferSourceNode(AudioContext* aContext);
~AudioBufferSourceNode() = default;
friend class AudioBufferSourceNodeEngine;
// START is sent during Start().
// STOP is sent during Stop().
@@ -129,7 +139,6 @@ private:
void SendBufferParameterToStream(JSContext* aCx);
void SendOffsetAndDurationParametersToStream(AudioNodeStream* aStream);
private:
double mLoopStart;
double mLoopEnd;
double mOffset;
@@ -145,4 +154,3 @@ private:
} // namespace mozilla
#endif
+49 -166
View File
@@ -11,10 +11,26 @@
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/AnalyserNode.h"
#include "mozilla/dom/AnalyserNodeBinding.h"
#include "mozilla/dom/AudioBufferSourceNodeBinding.h"
#include "mozilla/dom/AudioContextBinding.h"
#include "mozilla/dom/BiquadFilterNodeBinding.h"
#include "mozilla/dom/ChannelMergerNodeBinding.h"
#include "mozilla/dom/ChannelSplitterNodeBinding.h"
#include "mozilla/dom/ConvolverNodeBinding.h"
#include "mozilla/dom/DelayNodeBinding.h"
#include "mozilla/dom/DynamicsCompressorNodeBinding.h"
#include "mozilla/dom/GainNodeBinding.h"
#include "mozilla/dom/IIRFilterNodeBinding.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/MediaElementAudioSourceNodeBinding.h"
#include "mozilla/dom/MediaStreamAudioSourceNodeBinding.h"
#include "mozilla/dom/OfflineAudioContextBinding.h"
#include "mozilla/dom/OscillatorNodeBinding.h"
#include "mozilla/dom/PannerNodeBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/StereoPannerNodeBinding.h"
#include "mozilla/dom/WaveShaperNodeBinding.h"
#include "AudioBuffer.h"
#include "AudioBufferSourceNode.h"
@@ -245,13 +261,9 @@ bool AudioContext::CheckClosed(ErrorResult& aRv)
already_AddRefed<AudioBufferSourceNode>
AudioContext::CreateBufferSource(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AudioBufferSourceNode> bufferNode =
new AudioBufferSourceNode(this);
return bufferNode.forget();
return AudioBufferSourceNode::Create(nullptr, *this,
AudioBufferSourceOptions(),
aRv);
}
already_AddRefed<ConstantSourceNode>
@@ -303,18 +315,8 @@ bool IsValidBufferSize(uint32_t aBufferSize) {
already_AddRefed<MediaStreamAudioDestinationNode>
AudioContext::CreateMediaStreamDestination(ErrorResult& aRv)
{
if (mIsOffline) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<MediaStreamAudioDestinationNode> node =
new MediaStreamAudioDestinationNode(this);
return node.forget();
return MediaStreamAudioDestinationNode::Create(*this, AudioNodeOptions(),
aRv);
}
already_AddRefed<ScriptProcessorNode>
@@ -344,181 +346,93 @@ AudioContext::CreateScriptProcessor(uint32_t aBufferSize,
already_AddRefed<AnalyserNode>
AudioContext::CreateAnalyser(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<AnalyserNode> analyserNode = new AnalyserNode(this);
return analyserNode.forget();
return AnalyserNode::Create(*this, AnalyserOptions(), aRv);
}
already_AddRefed<StereoPannerNode>
AudioContext::CreateStereoPanner(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<StereoPannerNode> stereoPannerNode = new StereoPannerNode(this);
return stereoPannerNode.forget();
return StereoPannerNode::Create(*this, StereoPannerOptions(), aRv);
}
already_AddRefed<MediaElementAudioSourceNode>
AudioContext::CreateMediaElementSource(HTMLMediaElement& aMediaElement,
ErrorResult& aRv)
{
if (mIsOffline) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
MediaElementAudioSourceOptions options;
options.mMediaElement = aMediaElement;
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<DOMMediaStream> stream =
aMediaElement.CaptureAudio(aRv, mDestination->Stream()->Graph());
if (aRv.Failed()) {
return nullptr;
}
return MediaElementAudioSourceNode::Create(this, stream, aRv);
return MediaElementAudioSourceNode::Create(*this, options, aRv);
}
already_AddRefed<MediaStreamAudioSourceNode>
AudioContext::CreateMediaStreamSource(DOMMediaStream& aMediaStream,
ErrorResult& aRv)
{
if (mIsOffline) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
MediaStreamAudioSourceOptions options;
options.mMediaStream = aMediaStream;
if (CheckClosed(aRv)) {
return nullptr;
}
return MediaStreamAudioSourceNode::Create(this, &aMediaStream, aRv);
return MediaStreamAudioSourceNode::Create(*this, options, aRv);
}
already_AddRefed<GainNode>
AudioContext::CreateGain(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<GainNode> gainNode = new GainNode(this);
return gainNode.forget();
return GainNode::Create(*this, GainOptions(), aRv);
}
already_AddRefed<WaveShaperNode>
AudioContext::CreateWaveShaper(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<WaveShaperNode> waveShaperNode = new WaveShaperNode(this);
return waveShaperNode.forget();
return WaveShaperNode::Create(*this, WaveShaperOptions(), aRv);
}
already_AddRefed<DelayNode>
AudioContext::CreateDelay(double aMaxDelayTime, ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
if (aMaxDelayTime > 0. && aMaxDelayTime < 180.) {
RefPtr<DelayNode> delayNode = new DelayNode(this, aMaxDelayTime);
return delayNode.forget();
}
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
DelayOptions options;
options.mMaxDelayTime = aMaxDelayTime;
return DelayNode::Create(*this, options, aRv);
}
already_AddRefed<PannerNode>
AudioContext::CreatePanner(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<PannerNode> pannerNode = new PannerNode(this);
mPannerNodes.PutEntry(pannerNode);
return pannerNode.forget();
return PannerNode::Create(*this, PannerOptions(), aRv);
}
already_AddRefed<ConvolverNode>
AudioContext::CreateConvolver(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ConvolverNode> convolverNode = new ConvolverNode(this);
return convolverNode.forget();
return ConvolverNode::Create(nullptr, *this, ConvolverOptions(), aRv);
}
already_AddRefed<ChannelSplitterNode>
AudioContext::CreateChannelSplitter(uint32_t aNumberOfOutputs, ErrorResult& aRv)
{
if (aNumberOfOutputs == 0 ||
aNumberOfOutputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ChannelSplitterNode> splitterNode =
new ChannelSplitterNode(this, aNumberOfOutputs);
return splitterNode.forget();
ChannelSplitterOptions options;
options.mNumberOfOutputs = aNumberOfOutputs;
return ChannelSplitterNode::Create(*this, options, aRv);
}
already_AddRefed<ChannelMergerNode>
AudioContext::CreateChannelMerger(uint32_t aNumberOfInputs, ErrorResult& aRv)
{
if (aNumberOfInputs == 0 ||
aNumberOfInputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ChannelMergerNode> mergerNode =
new ChannelMergerNode(this, aNumberOfInputs);
return mergerNode.forget();
ChannelMergerOptions options;
options.mNumberOfInputs = aNumberOfInputs;
return ChannelMergerNode::Create(*this, options, aRv);
}
already_AddRefed<DynamicsCompressorNode>
AudioContext::CreateDynamicsCompressor(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<DynamicsCompressorNode> compressorNode =
new DynamicsCompressorNode(this);
return compressorNode.forget();
return DynamicsCompressorNode::Create(*this, DynamicsCompressorOptions(), aRv);
}
already_AddRefed<BiquadFilterNode>
AudioContext::CreateBiquadFilter(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<BiquadFilterNode> filterNode =
new BiquadFilterNode(this);
return filterNode.forget();
return BiquadFilterNode::Create(*this, BiquadFilterOptions(), aRv);
}
already_AddRefed<IIRFilterNode>
@@ -526,47 +440,16 @@ AudioContext::CreateIIRFilter(const mozilla::dom::binding_detail::AutoSequence<d
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback,
mozilla::ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
if (aFeedforward.Length() == 0 || aFeedforward.Length() > 20) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
if (aFeedback.Length() == 0 || aFeedback.Length() > 20) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
bool feedforwardAllZeros = true;
for (size_t i = 0; i < aFeedforward.Length(); ++i) {
if (aFeedforward.Elements()[i] != 0.0) {
feedforwardAllZeros = false;
}
}
if (feedforwardAllZeros || aFeedback.Elements()[0] == 0.0) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
RefPtr<IIRFilterNode> filterNode =
new IIRFilterNode(this, aFeedforward, aFeedback);
return filterNode.forget();
IIRFilterOptions options;
options.mFeedforward = aFeedforward;
options.mFeedback = aFeedback;
return IIRFilterNode::Create(*this, options, aRv);
}
already_AddRefed<OscillatorNode>
AudioContext::CreateOscillator(ErrorResult& aRv)
{
if (CheckClosed(aRv)) {
return nullptr;
}
RefPtr<OscillatorNode> oscillatorNode =
new OscillatorNode(this);
return oscillatorNode.forget();
return OscillatorNode::Create(*this, OscillatorOptions(), aRv);
}
already_AddRefed<PeriodicWave>
+2 -2
View File
@@ -316,6 +316,8 @@ public:
IMPL_EVENT_HANDLER(mozinterruptbegin)
IMPL_EVENT_HANDLER(mozinterruptend)
bool CheckClosed(ErrorResult& aRv);
private:
void DisconnectFromWindow();
void RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob);
@@ -326,8 +328,6 @@ private:
friend struct ::mozilla::WebAudioDecodeJob;
bool CheckClosed(ErrorResult& aRv);
nsTArray<MediaStream*> GetAllStreams() const;
private:
+22
View File
@@ -71,6 +71,28 @@ AudioNode::~AudioNode()
}
}
void
AudioNode::Initialize(const AudioNodeOptions& aOptions, ErrorResult& aRv)
{
if (aOptions.mChannelCount.WasPassed()) {
SetChannelCount(aOptions.mChannelCount.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
if (aOptions.mChannelCountMode.WasPassed()) {
SetChannelCountModeValue(aOptions.mChannelCountMode.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
if (aOptions.mChannelInterpretation.WasPassed()) {
SetChannelInterpretationValue(aOptions.mChannelInterpretation.Value());
}
}
size_t
AudioNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
+3
View File
@@ -250,6 +250,9 @@ private:
bool DisconnectFromOutputIfConnected(uint32_t aOutputIndex, uint32_t aInputIndex);
protected:
// Helper for the Constructors for nodes.
void Initialize(const AudioNodeOptions& aOptions, ErrorResult& aRv);
// Helpers for sending different value types to streams
void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
void SendInt32ParameterToStream(uint32_t aIndex, int32_t aValue);
+22 -1
View File
@@ -262,8 +262,29 @@ BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
aContext->Graph());
}
BiquadFilterNode::~BiquadFilterNode()
/* static */ already_AddRefed<BiquadFilterNode>
BiquadFilterNode::Create(AudioContext& aAudioContext,
const BiquadFilterOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<BiquadFilterNode> audioNode = new BiquadFilterNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->SetType(aOptions.mType);
audioNode->Q()->SetValue(aOptions.mQ);
audioNode->Detune()->SetValue(aOptions.mDetune);
audioNode->Frequency()->SetValue(aOptions.mFrequency);
audioNode->Gain()->SetValue(aOptions.mGain);
return audioNode.forget();
}
size_t
+14 -5
View File
@@ -14,15 +14,25 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct BiquadFilterOptions;
class BiquadFilterNode final : public AudioNode
{
public:
explicit BiquadFilterNode(AudioContext* aContext);
static already_AddRefed<BiquadFilterNode>
Create(AudioContext& aAudioContext, const BiquadFilterOptions& aOptions,
ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode)
static already_AddRefed<BiquadFilterNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const BiquadFilterOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
BiquadFilterType Type() const
@@ -63,10 +73,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
protected:
virtual ~BiquadFilterNode();
private:
explicit BiquadFilterNode(AudioContext* aContext);
~BiquadFilterNode() = default;
BiquadFilterType mType;
RefPtr<AudioParam> mFrequency;
RefPtr<AudioParam> mDetune;
@@ -78,4 +88,3 @@ private:
} // namespace mozilla
#endif
+23 -2
View File
@@ -74,8 +74,30 @@ ChannelMergerNode::ChannelMergerNode(AudioContext* aContext,
aContext->Graph());
}
ChannelMergerNode::~ChannelMergerNode()
/* static */ already_AddRefed<ChannelMergerNode>
ChannelMergerNode::Create(AudioContext& aAudioContext,
const ChannelMergerOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
if (aOptions.mNumberOfInputs == 0 ||
aOptions.mNumberOfInputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
RefPtr<ChannelMergerNode> audioNode =
new ChannelMergerNode(&aAudioContext, aOptions.mNumberOfInputs);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return audioNode.forget();
}
JSObject*
@@ -86,4 +108,3 @@ ChannelMergerNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
} // namespace dom
} // namespace mozilla
+15 -6
View File
@@ -12,15 +12,24 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct ChannelMergerOptions;
class ChannelMergerNode final : public AudioNode
{
public:
ChannelMergerNode(AudioContext* aContext,
uint16_t aInputCount);
static already_AddRefed<ChannelMergerNode>
Create(AudioContext& aAudioContext, const ChannelMergerOptions& aOptions,
ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
static already_AddRefed<ChannelMergerNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const ChannelMergerOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint16_t NumberOfInputs() const override { return mInputCount; }
@@ -35,10 +44,11 @@ public:
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
protected:
virtual ~ChannelMergerNode();
private:
ChannelMergerNode(AudioContext* aContext,
uint16_t aInputCount);
~ChannelMergerNode() = default;
const uint16_t mInputCount;
};
@@ -46,4 +56,3 @@ private:
} // namespace mozilla
#endif
+23 -2
View File
@@ -65,8 +65,30 @@ ChannelSplitterNode::ChannelSplitterNode(AudioContext* aContext,
aContext->Graph());
}
ChannelSplitterNode::~ChannelSplitterNode()
/* static */ already_AddRefed<ChannelSplitterNode>
ChannelSplitterNode::Create(AudioContext& aAudioContext,
const ChannelSplitterOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
if (aOptions.mNumberOfOutputs == 0 ||
aOptions.mNumberOfOutputs > WebAudioUtils::MaxChannelCount) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return nullptr;
}
RefPtr<ChannelSplitterNode> audioNode =
new ChannelSplitterNode(&aAudioContext, aOptions.mNumberOfOutputs);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return audioNode.forget();
}
JSObject*
@@ -77,4 +99,3 @@ ChannelSplitterNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProt
} // namespace dom
} // namespace mozilla
+15 -6
View File
@@ -12,15 +12,24 @@ namespace mozilla {
namespace dom {
class AudioContext;
struct ChannelSplitterOptions;
class ChannelSplitterNode final : public AudioNode
{
public:
ChannelSplitterNode(AudioContext* aContext,
uint16_t aOutputCount);
static already_AddRefed<ChannelSplitterNode>
Create(AudioContext& aAudioContext, const ChannelSplitterOptions& aOptions,
ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
static already_AddRefed<ChannelSplitterNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const ChannelSplitterOptions& aOptions, ErrorResult& aRv)
{
return Create(aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint16_t NumberOfOutputs() const override { return mOutputCount; }
@@ -35,10 +44,11 @@ public:
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
protected:
virtual ~ChannelSplitterNode();
private:
ChannelSplitterNode(AudioContext* aContext,
uint16_t aOutputCount);
~ChannelSplitterNode() = default;
const uint16_t mOutputCount;
};
@@ -46,4 +56,3 @@ private:
} // namespace mozilla
#endif
+27 -2
View File
@@ -203,8 +203,34 @@ ConvolverNode::ConvolverNode(AudioContext* aContext)
aContext->Graph());
}
ConvolverNode::~ConvolverNode()
/* static */ already_AddRefed<ConvolverNode>
ConvolverNode::Create(JSContext* aCx, AudioContext& aAudioContext,
const ConvolverOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
RefPtr<ConvolverNode> audioNode = new ConvolverNode(&aAudioContext);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// This must be done before setting the buffer.
audioNode->SetNormalize(!aOptions.mDisableNormalization);
if (aOptions.mBuffer.WasPassed()) {
MOZ_ASSERT(aCx);
audioNode->SetBuffer(aCx, aOptions.mBuffer.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
return audioNode.forget();
}
size_t
@@ -291,4 +317,3 @@ ConvolverNode::SetNormalize(bool aNormalize)
} // namespace dom
} // namespace mozilla
+17 -6
View File
@@ -12,14 +12,26 @@
namespace mozilla {
namespace dom {
class AudioContext;
struct ConvolverOptions;
class ConvolverNode final : public AudioNode
{
public:
explicit ConvolverNode(AudioContext* aContext);
static already_AddRefed<ConvolverNode>
Create(JSContext* aCx, AudioContext& aAudioContext,
const ConvolverOptions& aOptions, ErrorResult& aRv);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConvolverNode, AudioNode);
static already_AddRefed<ConvolverNode>
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
const ConvolverOptions& aOptions, ErrorResult& aRv)
{
return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
AudioBuffer* GetBuffer(JSContext* aCx) const
@@ -27,7 +39,7 @@ public:
return mBuffer;
}
void SetBuffer(JSContext* aCx, AudioBuffer* aBufferi, ErrorResult& aRv);
void SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv);
bool Normalize() const
{
@@ -61,10 +73,10 @@ public:
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
protected:
virtual ~ConvolverNode();
private:
explicit ConvolverNode(AudioContext* aContext);
~ConvolverNode() = default;
RefPtr<AudioBuffer> mBuffer;
bool mNormalize;
};
@@ -74,4 +86,3 @@ private:
} //end namespace mozilla
#endif
+23 -1
View File
@@ -205,8 +205,30 @@ DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
aContext->Graph());
}
DelayNode::~DelayNode()
/* static */ already_AddRefed<DelayNode>
DelayNode::Create(AudioContext& aAudioContext,
const DelayOptions& aOptions,
ErrorResult& aRv)
{
if (aAudioContext.CheckClosed(aRv)) {
return nullptr;
}
if (aOptions.mMaxDelayTime <= 0. || aOptions.mMaxDelayTime >= 180.) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
}
RefPtr<DelayNode> audioNode = new DelayNode(&aAudioContext,
aOptions.mMaxDelayTime);
audioNode->Initialize(aOptions, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
audioNode->DelayTime()->SetValue(aOptions.mDelayTime);
return audioNode.forget();
}
size_t
Loaded 100 of 2737 files, more files were not shown because too many files have changed in this diff. Show more