Compare commits

...
Author SHA1 Message Date
Moonchild 53bf5b5a21 Bump NSS (UXP) patch level. 2026-07-28 15:51:54 +02:00
John Schanck 07b2881965 Bug 2043887 - guard against integer overflow in CERT_Hexify. 2026-07-28 15:51:45 +02:00
Benjamin Beurdouche ca1b7c2595 Bug 2027353 - clamp input.len to testString size in pk11_mergeSecretKey. 2026-07-28 15:51:41 +02:00
Benjamin Beurdouche a0d8eeb768 Bug 2029433 - Bounds-check wrap index in PK11_GetWrapKey to match PK11_SetWrapKey. 2026-07-28 15:51:34 +02:00
Anna Weine 278ce9a272 Bug 2028954 - CERT_DecodeAVAValue — Integer Overflow in Output Buffer Sizing. 2026-07-28 15:51:29 +02:00
Moonchild 9367b64f2a Bug 2027364 - Set tail pointer to null in static slot lists when deallocating. 2026-07-28 15:51:24 +02:00
John Schanck 080247cf2f Bug 2032110 - fix two integer overflows on LLP64 systems. 2026-07-28 15:51:19 +02:00
John Schanck 95bf9478c7 Bug 2030102 - avoid leaving a dangling ss->sec.ci.sid on allocation failure. 2026-07-28 15:51:13 +02:00
Maurice Dauer 4ae3149d2e Bug 2027325 - Reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-28 15:51:08 +02:00
Moonchild 9bf01636f1 Bug 2030563 - Validate CKA_CERTIFICATE_TYPE ulValueLen in nss_cert_type_from_ck_attrib. 2026-07-28 15:51:03 +02:00
Benjamin Beurdouche e48fe8e307 Bug 2029807 - Guard padding read against empty output in SEC_PKCS7DecryptContents. 2026-07-28 15:50:56 +02:00
Benjamin Beurdouche 27c12ad698 Bug 2027346 - validate encoded EC params length and tag in SECKEY_ECParamsToKeySize/BasePointOrderLen. 2026-07-28 15:50:51 +02:00
Benjamin Beurdouche 612ddb64e5 Bug 2027371 - rewrite labelLen bound in tls13_HkdfExpandLabelGeneral to avoid unsigned overflow. 2026-07-28 15:50:46 +02:00
Benjamin Beurdouche c6c8421a2a Bug 2027373 - guard space subtraction in ssl_CallCustomExtensionSenders. 2026-07-28 15:50:41 +02:00
Benjamin Beurdouche f9859d226c Bug 2029901 - Guard against keySize overflow in IKE PRF/PRF+ output sizing. 2026-07-28 15:50:36 +02:00
Benjamin Beurdouche 7c0e60c4f1 Bug 2027362 - bound usageCount in PK11_UnwrapPrivKey to keyTemplate capacity. 2026-07-28 15:50:27 +02:00
Benjamin Beurdouche e06ef010c4 Bug 2027349 - reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-28 15:50:20 +02:00
Moonchild 3935cd9ed3 [network] Fix CacheEntry::mDoomCallback data race. 2026-07-28 15:49:52 +02:00
Moonchild f781824676 [layout] Fix nsFrameSetFrame primary frame handling of replicated children. 2026-07-28 15:49:40 +02:00
Moonchild 5a231d5bf9 [DOM media] Perform more thorough checks on video regions. 2026-07-28 15:49:19 +02:00
az 02302031dd Bug 2045742 2026-07-28 15:49:11 +02:00
Andrew McCreight b59b350424 Bug 2049523 - Make ToJSValue for float consistent with double. 2026-07-28 15:48:56 +02:00
Moonchild 99b8669d0a Fix comment (nit) 2026-07-28 15:48:49 +02:00
Randell Jesup 919fbff2ec Bug 2029734: Flush before calling sctp_process_init() 2026-07-28 15:48:10 +02:00
Moonchild 4977713834 [image] Make sure the image was fully and cleanly decoded before finalizing its animation state as complete. 2026-07-28 15:48:01 +02:00
Moonchild 1f8bd8cf45 [parser] Associate image elements with form only if the form and the intended parent are in the same tree. 2026-07-28 15:47:55 +02:00
Moonchild 8f6bacf33e [DOM media] Stop accepting audio samples with too low sample rates.
This sets the floor to 8kHz audio, which is generally considered to be
the lowest acceptable "phone quality"/"walkie-talkie" audio rate.
Audio outside the range will refuse to decode after this commit and give
a console error.
This avoids a whole class of potential bugs.
2026-07-28 15:47:27 +02:00
Moonchild a79a1b55a1 [layout] Add corner-case correctness check in DottedCornerFinder::FindBestOverlap. 2026-07-28 15:47:21 +02:00
Moonchild fa4d389b91 [network] Add usrsctp TSN gap check. 2026-07-28 15:47:08 +02:00
Moonchild 36b884ff7f [js] Clamp length of regexp captures array for dollar substitution. 2026-07-28 15:46:52 +02:00
Moonchild f3a7e60608 [js] Initialize BaselineFrame return value slot in OnLeaveBaselineFrame. 2026-07-28 15:46:45 +02:00
Moonchild a8405c5667 [DOM] Make parser update form owner properly 2026-07-28 15:46:39 +02:00
Moonchild 829354fb65 [gfx] Hold a strong ref during GetFontAt lookup. 2026-07-28 15:46:33 +02:00
Moonchild 4be7883908 [gfx] Add bounds checks and limit reverse scanning of ligature data. 2026-07-28 15:46:27 +02:00
Moonchild 2f77b246b3 No issue - Use strnlen instead of strnlen_s.
Apparently, GCC doesn't like the _s variants.
2026-07-28 15:46:08 +02:00
Moonchild ddf950f5ed [js] Guard against OOB string sizes in internal Printf 2026-07-28 15:45:28 +02:00
Basilisk-Dev ad98fe5130 Issue #3140 - implement URL.parse() 2026-07-14 23:08:55 +02:00
Moonchild 659c690d5b Issue #3129 - Add palette_neon_intrinsics.c to moz.build 2026-06-23 08:11:16 +02:00
Moonchild f1dc542b0b Issue #3122 - Put base paths in the json viewer client deps.
The dependency modules are requested early. Seems CSP can block baseURL
on these networking requests, so add the base manually to the resource
paths to prevent network requests before the html base element is
resolved and active.
2026-06-22 18:54:00 +02:00
Moonchild 0c5437c80b Apply (hopefully for the last time before 2.0.x) APNG support code.
This commit also removes MOZCHANGES (old and irrelevant information)
This commit also adds a new readme.
2026-06-21 14:23:55 +02:00
Moonchild db9881b854 Fresh import of libpng 1.6.58 2026-06-21 14:23:47 +02:00
Moonchild c5a37cad2e Bump NSS version for adopted changes. 2026-06-21 14:23:40 +02:00
Moonchild dd97244289 [DOM] Clean up WebGL transform feedback validation. 2026-06-21 14:23:07 +02:00
John Schanck 5372fed15c Bug 2030564 - add defensive input validation to sftk_compute_ANSI_X9_63_kdf. 2026-06-21 14:22:56 +02:00
John Schanck 37a8909357 Bug 2030366 - avoid race with module unloading in NSSTrustDomain_FindTokensByURI. 2026-06-21 14:22:48 +02:00
John Schanck 18f4069d8d Bug 2029403 - avoid PORT_Strdup in ssl_DecodeResumptionToken. 2026-06-21 14:22:27 +02:00
Julian Descottes 78c01f1b3f [devtools] Consistently show filepicker on first save action from StyleEditor.
Bug 2038133
2026-06-21 14:22:18 +02:00
Moonchild f946c969a2 Issue #3127 - Add trademark notice to the tree.
Resolves #3127
2026-06-21 14:22:11 +02:00
Moonchild 2dfa2b7c19 [network] Make HttpBaseChannel::mLoadFlags atomic. 2026-06-21 14:21:44 +02:00
Moonchild 8b88dd736a [gfx] Check more offsets during CFF subsetting.
Also fixes a bunch of whitespace (TAB -> spaces)
2026-06-21 14:21:33 +02:00
Moonchild b9fd964fec [DOM] Avoid over-optimizing some getter/function calls. 2026-06-21 14:21:25 +02:00
Moonchild 9c74a819e4 [parser] Better align with spec definition of adding nodes. 2026-06-21 14:21:18 +02:00
Moonchild f700453cb1 No issue - Use ImmGCPtr for module meta data visits.
This should make module GCs less touchy.
2026-06-21 14:20:42 +02:00
Moonchild 4ea0375575 [DOM media] Zero-initialize ThreadSharedFloatArrayBufferList. 2026-06-21 14:20:33 +02:00
Kui-Feng Lee 7071894a52 Bug 2033848 - Use non-default response ID for GTK file picker accept button. r=stransky
Replace GTK_RESPONSE_ACCEPT (-3) with a non-negative application-defined
response ID (kFilePickerAccept = 0) for the accept button in the GTK file
chooser dialog, and remove the gtk_dialog_set_default_response() call.

GTK treats buttons with negative built-in response IDs as candidates for
the dialog's default widget, which activates on Enter key press. By using
a non-negative ID and not calling set_default_response(), the accept button
is no longer pre-selected, preventing a page from tricking the user into
confirming a file upload by holding Enter before the dialog appears.

GTK's file chooser internally emits GTK_RESPONSE_ACCEPT via file_activated_cb
when the user double-clicks a file, so we keep that case in DoneNonPortal()
alongside kFilePickerAccept.
2026-06-21 14:20:22 +02:00
John Schanck 0f471cfde7 Bug 2023478 - improve handling of escape sequences in pk11uri_ParseAttributes. 2026-06-21 14:20:15 +02:00
Moonchild a8cc198e79 [DOM] Reject too large mLength in MutableBlobStorage::WriteRunnable. 2026-06-21 14:20:09 +02:00
John Schanck 477b1010fe Bug 2030570 - use correct data for ID comparison in transfer_uri_certs_to_collection. 2026-06-21 14:20:02 +02:00
Moonchild 8722bc3693 [network] Make keep-alive pref Atomic. 2026-06-21 14:19:53 +02:00
John Schanck e31e3802a0 Bug 2029765 - avoid refcount over-release in nssTokenObjectCache error path [@ nssToken_Destroy]. 2026-06-21 14:19:46 +02:00
Nicolas B. Pierron 723d95295e Bug 2029066 - Remove Sinking of Live instructions.
Instruction sinking was made possible by the introduction of recover
instructions, which are moving instructions to be executed on bailout, but this
is only possible for instructions which are not used.

This feature, which is now removed, was made to sink instructions which are
live, but only in a small set of branches, by moving the computation of these
instructions to bailout paths, and to the concerned if branches.

The current implementation never delivered and remained as dead-code for
multiple years, without having a firm benefit on performance oriented
benchmarks.

Thus, this change removes the part of the Sink optimization which deals with
live instructions but keeps the part of the Sink optimization which deals with
instructions which are only used on bailout paths.
2026-06-21 14:19:37 +02:00
John Schanck 91b3b6fdc8 Bug 2029803 - add defensive info->len check in PK11_HPKE_SetupS and PK11_HPKE_SetupR. 2026-06-21 14:19:18 +02:00
Moonchild 34a901430d Issue #3122 - Exclude local resources from <base> CSP checks.
This avoids local-resource <base> URLs being restricted/nullified by
remote CSP. This aligns the CSP handling with direct requests.

Resolves #3122
2026-06-14 10:52:53 +02:00
Moonchild 83826f1f34 Issue #3111 - Clean up logic in SweepFinalizationRegistries.
Resolves #3111
2026-06-09 18:07:37 +02:00
Moonchild 3562ba1235 [DOM] Provide more silent audio processing frames. 2026-06-05 12:39:58 +02:00
Moonchild 1cc002018f Revert "Bug 2027433 Treat null input channels as zero in InterleaveAndConvertBuffer()"
This reverts commit e76fc5637a.
2026-06-05 11:38:27 +02:00
Moonchild 352863cab4 Revert "Bug 2027433 Treat null input channels as zero in AudioChannelsDownMix()"
This reverts commit ddd016a6f8.
2026-06-05 11:38:22 +02:00
Moonchild d69570b62b Revert "Bug 2027433 use nullptr for silent up-mix channels"
This reverts commit 5309640d6c.
2026-06-05 11:38:14 +02:00
Moonchild 26c44d4869 Issue #3109 - Use CSS' internal length clamp value instead. 2026-05-30 10:44:40 +02:00
Moonchild f10fc4489c Issue #3109 - Clamp border-radius value to Int32.MaxValue
This avoids artifacts from out-of-bounds values.
Resolves #3109
2026-05-30 10:44:32 +02:00
Moonchild 3450ed2282 Merge branch 'master' into release 2026-05-26 14:16:41 +02:00
Moonchild a0f135b94f NSS version update 2026-05-26 14:16:25 +02:00
Moonchild 967e985c5f Merge branch 'master' into release 2026-05-26 09:32:40 +02:00
Moonchild 3be679effc [DOM] Stop speech synthesis if the originating document is closed. 2026-05-25 20:32:10 +02:00
Moonchild 2d91c80555 [media] ffvpx patch: Fix leak in flac decoder in case of alloc failure. 2026-05-25 19:10:46 +02:00
Moonchild e5326c1d74 [DOM] Hold a strong ref to VoiceData in nsSynthVoiceRegistry::RemoveVoice. 2026-05-25 18:56:57 +02:00
Jens Stutte 5ddccdc7f6 Bug 1784128 - Assert count passed to PR_Read/PR_Write in nsFileStreamBase fits INT32_MAX. 2026-05-25 15:44:51 +02:00
Moonchild 8dc41b293a [gfx/layout] Simplify textruns
Cache overflow textruns in a better place and stop using a lazy class.
This avoids doing caching in the rendering back-end, and does so where
necessary in TextOverflow (for ellipses)
2026-05-25 14:59:51 +02:00
Moonchild f02956a324 No issue - Remove ISO-2022-JP from menu, overridability and detector.
Removed autodetection of this charset due to unreliability.
There are known security issues around charset auto-detection for ISO-2022-JP.
Given the usage is around 0.000002% of page loads, and Safari does not
support auto-detection of ISO-2022-JP, Chrome also planned to remove
support for it to eliminate the security issues.

See also https://www.sonarsource.com/blog/encoding-differentials-why-charset-matters/

Removal from the menu to avoid social engineering hazards and it being
literally unused on the web.
2026-05-25 13:08:29 +02:00
Moonchild e3646af419 [libvorbis] Allocate memory with _ogg_malloc
See https://gitlab.xiph.org/xiph/vorbis/-/commit/28965ede851bb9c1ce5cc0ed733fdf4ebd3d4241 and related commits.
2026-05-25 11:44:16 +02:00
Moonchild ee1f2e31a1 [layout] Hide accessible carets when needed. 2026-05-25 11:23:05 +02:00
Moonchild dcb90d6f92 [DOM] Check values in audio resampling. 2026-05-25 10:57:18 +02:00
John Schanck f9cdc54e09 Bug 2029818 - avoid refcount over-release in CERT_CertChainFromCert error path. 2026-05-25 10:22:44 +02:00
Moonchild 28be7ae6e0 [NSS] Fix use of uninitialized length after failed PK11_SignWithMechanism/SymKey. 2026-05-25 07:27:51 +02:00
Moonchild 463e7ec3c6 Force Clobber 2026-05-25 06:44:48 +02:00
John Schanck 531eeaabaa [NSS] Fix maxSize calculation in NSSUTIL_AddNSSFlagToModuleSpec. 2026-05-25 06:43:53 +02:00
Moonchild d6915b9014 Merge branch 'master' into release 2026-05-25 06:08:13 +02:00
Moonchild af92afbd6c Merge pull request 'Revert all Issue #3092 Commits' (#3107) from Basilisk-Dev/UXP-contrib:revert-3092 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3107
2026-05-25 04:05:41 +00:00
John Schanck 5005a47921 Bug 2027381 - improve error handling in SECITEM_DupArray with non-null arena. 2026-05-24 22:30:38 +02:00
Basilisk-Dev 72d4ca2b35 Clean up Issue #3092 revert whitespace 2026-05-24 16:19:36 -04:00
Basilisk-Dev b8951dbc2a Revert "Issue #3092 - Fix unsafe GC multithreading changes"
This reverts commit 2ca5d21147.

The mechanical inverse patch would restore earlier Issue #3092 parallel GC code that has already been removed by the preceding revert commits, so this records the revert without changing the tree.
2026-05-24 16:18:45 -04:00
Basilisk-Dev 20c92e63c5 Revert "Issue #3092 - Safely parallelize GC background finalization"
This reverts commit 3cf7c94995.
2026-05-24 16:13:21 -04:00
Moonchild ea785c3bb0 [netwerk] Make socket transport hold a reference to TLSServerConnectionInfo. 2026-05-24 21:48:55 +02:00
Randell Jesup 7abc11b3d1 Bug 2036905: Fix UDPSocketParent::ConnectInternal data race on mSocket. 2026-05-24 21:22:57 +02:00
Moonchild 2a4c4687c6 [netwerk] Make nsSocketTransport2::mConnectionFlags atomic. 2026-05-24 21:10:00 +02:00
Basilisk-Dev de3970d9b4 Revert "Issue #3092 - Refactor WASM compilation handling"
This reverts commit 1c09cd7816.
2026-05-24 14:58:21 -04:00
Basilisk-Dev 4da8c1fe4c Revert "Issue #3092 - Add new GC sweep tasks."
This reverts commit 8b6414ea7c.
2026-05-24 14:57:38 -04:00
Basilisk-Dev 8230f9b359 Revert "Issue #3092 - Implement BackgroundFinalizeTask for parallel garbage collection finalization"
This reverts commit 8ca5438db9.
2026-05-24 14:57:38 -04:00
Basilisk-Dev 310fec9ad5 Revert "Issue #3092 - Implement parallel sweeping and compaction tasks"
This reverts commit f33ccb5ce3.
2026-05-24 14:55:47 -04:00
Basilisk-Dev 5f2040153b Revert "Issue #3092 - Initial idle GC implementation"
This reverts commit fba218cff4.
2026-05-24 14:54:58 -04:00
Basilisk-Dev 30a774eb08 Revert "Issue #3092 - Perform a minor GC on tab close"
This reverts commit 266cc371f7.
2026-05-24 14:53:56 -04:00
Moonchild e8ee09b41f Merge pull request 'Implement CSSStyleSheet constructor' (#3103) from Basilisk-Dev/UXP-contrib:cssstylesheet-updates into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3103
2026-05-24 18:36:53 +00:00
Moonchild 5fc626f0fc [netwerk] nsRequestObserverProxy ref cleanup. 2026-05-24 19:40:23 +02:00
John Schanck c87c0e440b Bug 2029782 - fix 8-byte over-read of AES-192 key buffer in x86 builds without USE_HW_AES. 2026-05-24 15:10:06 +02:00
John Schanck 39b34ed8c5 Bug 2029771 - Heap use-after-free in [@ token_destructor] reading tok->pk11slot after nssToken_Destroy frees the token arena. 2026-05-24 15:07:24 +02:00
John Schanck e6b4a84e7e [NSS] Avoid integer overflow when converting AVA value to hex string. 2026-05-24 15:03:12 +02:00
John Schanck f7dfc278c4 [NSS] Enforce minimum buffer length in sftk_CheckCBCPadding. 2026-05-24 14:58:53 +02:00
Dana Keeler 13349f484c [NSS] VerifyCodeSigningCertificateChain: require at least one certificate. 2026-05-24 14:40:56 +02:00
Moonchild bd2670e006 [NSS] Initialize src in SEC_PKCS5GetIV 2026-05-24 14:37:06 +02:00
Dana Keeler e5bebae2c7 [NSS] NSS_CMSContentInfo_SetContent: only modify cinfo if everything succeeds. 2026-05-24 12:03:33 +02:00
Dennis Jackson d93df7216d [NSS] Align PKCS7 digest array with digestAlgorithms. 2026-05-24 11:50:38 +02:00
Moonchild 3d0a6899ce [libjar] Check Jar entry names for nulls. 2026-05-24 10:51:21 +02:00
John Schanck fdde68855b [NSS] Handle SEC_ASN1_NULL in sec_asn1e_contents_length. 2026-05-24 10:16:24 +02:00
Moonchild 304e6d045d Merge branch 'master' into release
# Conflicts:
#	dom/media/webm/WebMDemuxer.cpp
2026-05-24 10:11:40 +02:00
Moonchild 2d038e6c1a [NSS] Fix instances of softoken attributes freed after owning object. 2026-05-24 10:09:28 +02:00
Moonchild c10f8a567b Merge branch 'master' of https://repo.palemoon.org/MoonchildProductions/UXP 2026-05-24 09:10:39 +02:00
Moonchild dcfa35e1ff Merge pull request 'Restore libAOM to the tree and making it a build-time configuration.' (#3104) from 888-32-bit-work2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3104
2026-05-24 07:09:19 +00:00
Iain Ireland de1a7f5fe1 [js] Use size_t when inflating UTF8 2026-05-24 09:08:03 +02:00
Basilisk-Dev 34d88ac937 Issue #3053 - Implement CSSStyleSheet constructor 2026-05-23 16:45:54 -04:00
Moonchild 39a89b708e Issue #888 - Fix makefile configure syntax for x86 check.
Not sure what language I was thinking but it was the wrong one. :P
2026-05-23 14:02:04 +02:00
Moonchild 69ad4f1674 Fix line endings in WebmDemuxer.cpp
No code changes.
2026-05-23 13:42:03 +02:00
Moonchild 59ae55a0e2 Issue #888 - Back out changes to the Dav1d lib. 2026-05-23 12:46:23 +02:00
Moonchild 6eb551332e Issue #888 - Hook libAOM back up, and make it configurable at build time.
Since the Dav1d changes will be reverted in the next commit, this also
includes a test for 32-bit x86 targets which makes libAOM mandatory.
2026-05-23 12:44:12 +02:00
Moonchild 96be1bb7a0 Revert "Issue #888 - Remove bundled libaom"
This reverts commit eb487c2ca1.
2026-05-23 10:26:43 +02:00
Moonchild 4dc3b6db93 Merge pull request 'Follow up on Dav1d implementation for 32-bit targets' (#3100) from 888-32bit into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3100
2026-05-23 07:37:32 +00:00
Moonchild a1da555b51 Issue #888 - Follow-up: Put smooth_weights_{1|2}d_16bpc back in ipred16 sources.
This reverts commit 16212905de and places
the SMOOTH_WEIGHTS in the SSE source instead, since that is always included.
2026-05-22 12:15:20 +02:00
Moonchild c1abc2eb3e Merge pull request 'ffvpx: Configuration for NetBSD/powerpc' (#3101) from nia/UXP:ffvpx-ppc into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3101
2026-05-22 08:14:01 +00:00
nia f0acda0bf4 ffvpx: Configuration for NetBSD/powerpc
Signed-off-by: Nia Alarie <nia@NetBSD.org>
2026-05-21 17:10:41 +02:00
Moonchild 16212905de Issue #888 - Follow-up: Lift smooth_weights_{1|2}d_16bpc out of AVX source.
This lifts the 2 functions out of the AVX-specific source (since it's
also used in the SSE one as external) and places it in the common x86
include.

This is an upstream code placement error; should be reported upstream.
2026-05-21 13:38:47 +02:00
Moonchild 2eb5e91b62 Issue #888 - Follow-up: don't assemble AVX into Dav1d on 32-bit x86 2026-05-21 13:34:47 +02:00
Moonchild fa6b67c8ac Re-land: Fix devtools on 32-bit big endian platforms
Tag PR #3098
2026-05-21 09:42:07 +02:00
Moonchild 6a117bd9d1 Revert "Fix dev tools on 32-bit big endian platforms"
This reverts commit f363ec1838.
2026-05-20 16:18:09 +02:00
Moonchild 714c709ad0 Merge pull request 'Add NetBSD to list of platforms where mapfile gets generated' (#3099) from nia/UXP:mapfile into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3099
2026-05-20 10:47:37 +00:00
Moonchild eafc230ff2 Merge pull request 'A collection of random fixes I've been accumulating.' (#3097) from dbsoft/UXP:miscfixes4 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3097
2026-05-20 10:46:57 +00:00
Moonchild 523a9aa2de Merge pull request 'Split loongarch jit so it no longer uses any mips files' (#3096) from Basilisk-Dev/UXP-contrib:loongarch-fix-jit into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3096
2026-05-20 10:46:19 +00:00
Moonchild ec92c29029 Merge pull request 'Fix dev tools on 32-bit big endian platforms' (#3098) from nia/UXP:devtools-lp32 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3098
2026-05-20 10:45:41 +00:00
nia 4a9d702bc1 Add NetBSD to list of platforms where mapfile gets generated
Signed-off-by: Nia Alarie <nia@NetBSD.org>
2026-05-20 10:26:38 +02:00
nia f363ec1838 Fix dev tools on 32-bit big endian platforms
This resolves a crash when pressing F12.

The __LP64__ macro is relied upon elsewhere in UXP so I think
this change should be safe.

Signed-off-by: Nia Alarie <nia@NetBSD.org>
2026-05-20 10:05:48 +02:00
Basilisk-Dev ffb3a95eb9 Issue #3095 - split loongarch jit so it no longer uses any mips files 2026-05-19 15:43:21 -04:00
Moonchild 63094adef4 Merge pull request 'Fix build on NetBSD/aarch64' (#3094) from nia/UXP:netbsd-aarch64 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3094
2026-05-19 15:50:04 +00:00
nia 1f8dcf74c8 Fix build on NetBSD/aarch64
Signed-off-by: Nia Alarie <nia@NetBSD.org>
2026-05-19 09:28:23 +02:00
Moonchild f20c549f66 Issue #888 - Follow-up: Spot-fix; set PREFIX in Dav1d config on Apple. 2026-05-19 09:02:10 +02:00
Brian Smith b62cccda62 Issue #1829 - Follow-up: Fix package name check for 32-bit Intel. 2026-05-18 08:51:11 -05:00
Brian Smith 43f3b3c7ee Issue #1829 - Follow-up: Fix version check for CoreLocation on 10.5 and earlier. 2026-05-18 08:51:11 -05:00
Brian Smith a328464912 Issue #1829 - Follow-up: Remove obsolete font code from Cairo.
This code only gets built on 32-bit MacOS, and it isn't used.
This allows Intel 32-bit MacOS builds to succeed.
2026-05-18 08:51:11 -05:00
Brian Smith 977ddd9e81 No Issue - Fix font crash on MacOS 10.7-10.11 using fonts with variations.
Switch to MacOS version guard's instead of PowerPC guards, for Intel support.
Remove inactive debug code.
2026-05-18 08:51:11 -05:00
Brian Smith 67717762f9 Issue #2051 - Follow-up: Fix CSS image masks on PowerPC Mac.
When I brought back CoreGraphics backend I brought back a fix for this.
However the fix was designed for Intel which uses Skia as a backend.
Our Skia does not support big endian, so change it to use Cairo backend.
2026-05-18 08:51:11 -05:00
Brian Smith a33f6857fd Issue #2354 - Follow-up: Fix building WebRTC on 32-bit ARM without hardware float. 2026-05-18 08:51:11 -05:00
Brian Smith 5c7c192df1 No Issue - Fix cubeb compilation targeting MacOS 10.5 from newer versions.
Remove obsolete iOS checks.
2026-05-18 08:51:11 -05:00
Basilisk-Dev 0186e78221 Fix WeakRef constructor realm prototype 2026-05-18 13:05:28 +02:00
Basilisk-Dev e9e858348b Fix FinalizationRegistry constructor realm prototype 2026-05-18 13:05:21 +02:00
Basilisk-Dev 631bb15b05 Implement FinalizationRegistry 2026-05-18 13:05:15 +02:00
Basilisk-Dev e7d6301c75 Make WeakRef support always enabled 2026-05-18 12:52:09 +02:00
Moonchild 22001fbca3 Fix incorrect variadic for size_t in fprintf statement in hyphen.c. 2026-05-18 12:41:20 +02:00
Basilisk-Dev 22e3028d56 Fix ArrayBuffer storage and error types 2026-05-18 12:31:46 +02:00
Basilisk-Dev 9498ce3f1e Fix ArrayBuffer slice after resizable source shrink 2026-05-18 12:31:40 +02:00
Basilisk-Dev 172c7b6f25 Validate typed array set and constructors on resizable buffers 2026-05-18 12:31:35 +02:00
Basilisk-Dev 750ef67831 Validate typed array methods on resizable buffers 2026-05-18 12:31:29 +02:00
Basilisk-Dev c19a39c4a5 Fix resizable DataView out-of-bounds semantics 2026-05-18 12:31:24 +02:00
Basilisk-Dev d6bfeeaf1a Support BigInt Atomics waiters 2026-05-18 12:31:17 +02:00
Basilisk-Dev e7ea20c073 Support DataView on shared array buffers 2026-05-18 12:31:11 +02:00
Basilisk-Dev a7e01b3f77 Guard typed array JIT paths for resizable buffers 2026-05-18 12:31:06 +02:00
Basilisk-Dev c3a541c55a Implement resizable buffer view semantics 2026-05-18 12:30:59 +02:00
Basilisk-Dev 41efdfd488 Implement Atomics.waitAsync 2026-05-18 12:30:52 +02:00
Basilisk-Dev 7d41d2a47c Implement growable SharedArrayBuffer 2026-05-18 12:30:46 +02:00
Basilisk-Dev ec951c592a Allow symbols as weak collection keys 2026-05-18 12:30:39 +02:00
Basilisk-Dev 829fd431e2 Implement ES2024 ArrayBuffer transfer APIs 2026-05-18 12:30:33 +02:00
Basilisk-Dev 9b7d25d1fd Implement ES2024 grouping and resolver builtins 2026-05-18 12:30:28 +02:00
Basilisk-Dev 1ab3e82a4d Fix JS shell module hook build 2026-05-18 12:30:22 +02:00
Moonchild b07102b821 Merge pull request 'Paralellize GC and implement GC-on-Idle' (#3093) from 3092 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3093
2026-05-18 10:28:10 +00:00
Moonchild 3adf3917ee Merge pull request 'Port various code changes from eUXP that should have been upstreamed' (#3091) from eUXP_ports2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3091
2026-05-18 10:27:54 +00:00
Moonchild bbaf41e032 Merge pull request 'Truncate fractional border calculations to integers with special handling' (#3090) from 3088 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3090
2026-05-18 10:26:16 +00:00
Moonchild 618c017249 Merge pull request 'Replace libAOM reference AV1 implementation with Dav1d' (#3087) from dav1d-work into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3087
2026-05-18 10:25:52 +00:00
Basilisk-Dev 3cf7c94995 Issue #3092 - Safely parallelize GC background finalization
Parallelize background finalization across zones within each finalize
phase while preserving phase ordering and falling back to serial work
when no helper thread is idle.

Make compacting GC pointer updates schedule background work per zone and
only when enough background-safe arenas exist.
2026-05-18 12:18:05 +02:00
Basilisk-Dev 2ca5d21147 Issue #3092 - Fix unsafe GC multithreading changes 2026-05-18 12:17:18 +02:00
ownedbywuigi 266cc371f7 Issue #3092 - Perform a minor GC on tab close 2026-05-18 12:16:56 +02:00
ownedbywuigi fba218cff4 Issue #3092 - Initial idle GC implementation 2026-05-18 12:15:55 +02:00
ownedbywuigi f33ccb5ce3 Issue #3092 - Implement parallel sweeping and compaction tasks
for improved garbage collection performance
2026-05-18 12:15:34 +02:00
ownedbywuigi 8ca5438db9 Issue #3092 - Implement BackgroundFinalizeTask for parallel garbage collection finalization 2026-05-18 12:15:09 +02:00
ownedbywuigi 8b6414ea7c Issue #3092 - Add new GC sweep tasks.
For saved stacks, self-hosting scripts, and native iterators.
2026-05-18 12:14:30 +02:00
ownedbywuigi 1c09cd7816 Issue #3092 - Refactor WASM compilation handling 2026-05-18 12:13:18 +02:00
wuggy 07b47c8472 Whitelist virtual GPUs (VirtualBox, VMware, VirtIO (QEMU and forks like UTM), Parallels) 2026-05-18 09:48:35 +02:00
Basilisk-Dev 950a608e01 Support CSS shadow parts 2026-05-17 09:57:14 +02:00
Basilisk-Dev c7f08c7e53 Issue #2506 - Support range media query syntax
Resolves #2506
2026-05-17 09:55:27 +02:00
Basilisk-Dev 4f3857c1ea Issue #1826 - Parse calc() weights in color-mix 2026-05-17 09:53:56 +02:00
Basilisk-Dev 60b4b1ad47 Issue #3089 - Support logical border radius properties
Resolves #3089
2026-05-17 09:53:05 +02:00
Basilisk-Dev 8262184873 Revert "Cloudflare Image Resizing fix take 2"
This reverts commit ef19ad3ffd.

No longer necessary with aspect-ratio in place.
2026-05-17 09:46:52 +02:00
Basilisk-Dev e9abd8b022 Support CSS sizing math functions
Prereq for parts of #2404
2026-05-17 09:46:07 +02:00
Basilisk-Dev fe29e0430c Issue #2404 - Enable CSS aspect-ratio sizing 2026-05-17 09:44:59 +02:00
Moonchild 589967f3df Merge branch '3088' into euxp-ports2 2026-05-17 09:44:13 +02:00
Basilisk-Dev 9db275d300 Remove stale imagebitmap support file entry 2026-05-17 09:42:03 +02:00
Basilisk-Dev b6d0a261d2 Load mochitest modules without imp 2026-05-17 09:41:56 +02:00
Basilisk-Dev dad0daf389 Issue #2982 - Follow-up: allow color-mix to work with oklab and oklch
Tag #2489 and #3003
2026-05-17 09:41:44 +02:00
Basilisk-Dev b58e2b9312 Issue #1826 - Serialize special calc() number values 2026-05-17 09:39:23 +02:00
Basilisk-Dev b8f458a819 Issue #1826 - Add typed calc() arithmetic for media queries 2026-05-17 09:39:00 +02:00
Basilisk-Dev 39321f4796 Issue #1826 - Canonicalize nested calc() serialization 2026-05-17 09:38:31 +02:00
Basilisk-Dev d8de738239 Issue #1826 - Support calc() in media queries 2026-05-17 09:37:49 +02:00
Basilisk-Dev 40407bb784 Issue #1826 - Implement broader CSS calc() parsing 2026-05-17 09:37:11 +02:00
Basilisk-Dev a5b2671f1e Fix app-unit rounding for border width edges 2026-05-17 09:34:28 +02:00
Basilisk-Dev 4249686af4 Flush layout for computed border-width shorthand 2026-05-17 09:34:20 +02:00
Basilisk-Dev 69ba22d624 Fix CSS border rounding and currentcolor clipping 2026-05-17 09:34:13 +02:00
Basilisk-Dev 4359582e67 Test fractional border width rounding 2026-05-17 09:33:59 +02:00
Basilisk-Dev fa06d2de31 Floor fractional border widths 2026-05-17 09:33:49 +02:00
ownedbywuigi b7b1918a36 Issue #888 - Add dav1d_flush 2026-05-17 09:06:09 +02:00
ownedbywuigi aa69d5ec99 Issue #888 - Make symbols direct to dav1d, not AOM. 2026-05-17 09:05:44 +02:00
ownedbywuigi 6e4bb257a4 Issue #888 - (potentially) fix MSVC builderr 2026-05-17 09:05:24 +02:00
wuggy a30f439a9c Issue #888 - Fix alphabetical order issue 2026-05-17 09:04:52 +02:00
Basilisk-Dev 0ccaab55ca Issue #888 - Update AV1 configure comment for dav1d 2026-05-17 09:04:31 +02:00
Basilisk-Dev e61621692c Issue #888 - Enable AV1 playback by default 2026-05-17 09:04:05 +02:00
Basilisk-Dev 9a8cb2e22e Issue #888 - Enable dav1d SIMD on more architectures 2026-05-17 09:03:41 +02:00
Basilisk-Dev eb487c2ca1 Issue #888 - Remove bundled libaom 2026-05-17 09:03:21 +02:00
Basilisk-Dev 5c0a35a358 Issue #888 - Enable dav1d LoongArch SIMD 2026-05-17 09:02:50 +02:00
Basilisk-Dev a468f81a5e Issue #888 - Use in-tree dav1d for AV1 decoding 2026-05-17 09:00:34 +02:00
Basilisk-Dev d1b46d7347 Issue #888 - Vendor dav1d 1.5.3 2026-05-17 09:00:07 +02:00
Moonchild 4dea7f04dc [gfx] Add sanity checks in ANGLE D3D11 renderer. 2026-04-29 15:06:03 +02:00
Moonchild 7cc35f1195 [DOM] Do not interrupt worker execution if already scheduled. 2026-04-29 15:05:56 +02:00
Moonchild afd0648631 [DOM] Validate size in FileReader. 2026-04-29 15:05:17 +02:00
Moonchild 6524bfee21 [DOM/media] Add some sanity checks to MP3 demuxer.
Note: `vbr.NumAudioFrames()` is already checked in `vbr.IsComplete()`
2026-04-29 15:05:11 +02:00
Iain Ireland de8c2d1762 Bug 2029806: Handle ill-formed UTF16 2026-04-29 15:05:06 +02:00
Karl Tomlinson 5309640d6c Bug 2027433 use nullptr for silent up-mix channels 2026-04-29 15:05:01 +02:00
Karl Tomlinson ddd016a6f8 Bug 2027433 Treat null input channels as zero in AudioChannelsDownMix() 2026-04-29 15:04:55 +02:00
Karl Tomlinson e76fc5637a Bug 2027433 Treat null input channels as zero in InterleaveAndConvertBuffer()
The loop nesting is inverted so as not to add a null check to the inner
loop, but this change would also have some impact on cache use:

* The loop ordering might perhaps not be the ideal for two channels and
large sample counts, for example, because it means going through the
output/largest buffer twice.
* It does, however, avoid pathological situations of iterating across
planar channel buffers, likely to load set-associative cache lines if
the channel buffers are page aligned, due to having 1024 (or somewhat
fewer) floats, for example.
2026-04-29 15:04:49 +02:00
Moonchild 62110dcf7f Revert "[DOM] Ensure the GC sees consistent states while adopting DOM nodes."
This reverts commit 7664a83451.
2026-04-28 17:39:16 +02:00
Moonchild c597f4de77 [NSS] Restore dropped 'S' :P 2026-04-26 17:06:16 +02:00
Moonchild fe4b55154b [NSS] Update NSS version for release.
Add (UXP) to the version display string to signify this is our variant of
NSS 3.90 to avoid confusion with the 3.90 branch used in Firefox 115 ESR.
This version has backported considerably more fixes than Mozilla's NSS.
2026-04-26 15:56:47 +02:00
Moonchild d9f4319bfd [parser] Handle foster parenting properly. 2026-04-26 15:56:36 +02:00
Moonchild ec7baced6c [media] Spot-fix for ffvpx handling of bad video data. 2026-04-26 15:56:28 +02:00
Moonchild 5ed591c3d7 [image] Don't do unnecessary work if the image is being destroyed. 2026-04-26 15:56:21 +02:00
Iain Ireland 32859868d6 Bug 2029727: Update RegExpStatics data after realloc 2026-04-26 15:56:09 +02:00
Moonchild 4ab80fceb4 [gfx] OTS/HB: Correct bounds checks. 2026-04-26 15:56:00 +02:00
Moonchild 4e25cc130f [js] Use isElement in UnmappedArgSetter to check if the argument was marked as deleted.
This is more consistent with `UnmappedArgGetter` and better handles the
case where the property was marked deleted in `RareArgumentsData` but not
actually deleted from the object due to OOM. Unfortunately this scenario
is hard to prevent because the property is marked as deleted in the
`ArgumentsObject::obj_delProperty` class hook and after that
`NativeDeleteProperty` tries to remove the property and this can fail.
2026-04-26 15:55:52 +02:00
Dennis Jackson f1b56f6512 Bug 2029323 - Improve size calculations in CMS content buffering 2026-04-26 15:55:38 +02:00
John Schanck b5d6c427ad Bug 2029425 - Heap use-after-free in cert_VerifyCertChainOld via dangling certsList[] entry on NameConstraints violation. 2026-04-26 15:55:29 +02:00
Moonchild 9a900503ea [image] Hold a strong ref on mInnerImage when requesting a refresh. 2026-04-26 15:55:22 +02:00
Moonchild f6296891bf [DOM] Add some death grips to TextTrackManager. 2026-04-26 15:55:17 +02:00
Moonchild bbd16ed644 [DOM/media] Use extended channel data as-appropriate. 2026-04-26 15:55:11 +02:00
John Schanck 8f6cd1cfcd Bug 2030135 - improve error handling in PK11_ImportPrivateKeyInfoAndReturnKey 2026-04-26 15:55:06 +02:00
Moonchild 70a3532f49 Revert "[gfx] Use local statics for harfbuzz callback pointers"
This reverts commit 60a96d9cd2.
2026-04-26 15:54:57 +02:00
Moonchild c160edb49b No issue - Update our in-tree brotli library to 1.2.0+
This includes a minor patch to encode.c to work around the "static init"
check that actually doesn't do anything in its default state, but, due to
compiler subtleties in handling duplicate object names, would not be able
to link brotli.exe because it would refuse to expose all symbols for
duplicate objects (a later one would just be ignored).
Unsure how clang does this but it's not portable across compilers.
(we need the brotli.exe tool for resource package compression)
2026-04-26 15:54:50 +02:00
John Schanck 32f0e6d1e6 Bug 2029462 - store email on subject cache_entry in NSS trust domain.
remove_email_entry used cert->email of the last-destroyed cert to locate
the hash entry to clean up. If that cert had no email, the entry was
silently skipped, leaving a dangling subjectList pointer after the arena
was freed. Store the registration-time email on the subject cache_entry
(mirroring ce->nickname) and thread it through remove_subject_entry so
removal always uses the correct email regardless of destruction order.
2026-04-26 15:54:36 +02:00
Moonchild 8c6098ed9e [security] Ensure DispatchToMainThreadAndWait isn't interrupted.
In some cases, `lock.wait()` can be interrupted by spurious wake-ups
before processing is done. To ensure things are, in fact, synchronous,
loop over `wait()` until it is actually done.
2026-04-26 15:54:26 +02:00
Timothy Nikkel 5f70302bfc Bug 2029291. 2026-04-26 15:54:16 +02:00
Jan de Mooij f1cc25409a Bug 2029317 - Create RareArgumentsData before mutating the arguments object in MappedArgumentsObject::obj_defineProperty. 2026-04-26 15:54:10 +02:00
Jan-Ivar Bruaroey 1bb67f87d1 Bug 2029423 - Reset post_proc state. 2026-04-26 15:53:55 +02:00
Andy Leiserson 6f89be191d Bug 2029427 - Fix format string 2026-04-26 15:53:50 +02:00
Moonchild f453aac0eb [gfx] Explicitly cast calculation to int32. 2026-04-26 15:53:42 +02:00
Moonchild abc2e56e6a [gfx] Port libyuv upstream bounds check. 2026-04-26 15:53:31 +02:00
Simon Farre 2f2c86599f Bug 2025973 - Use value-semantics for txExecutionState::TemplateRule
TemplateRule is a wrapper around references mostly and can for the
purposes of this function be copied to the stack, given that
TemplateRule::mModeNsId is not mutated there.
2026-04-26 15:53:24 +02:00
Dennis Jackson a52e68f04d [NSS] Clarify extension negotiation mechanism for TLS Handshakes. 2026-04-26 15:53:16 +02:00
Moonchild ee256eda09 [js] Only allow strings as function name. 2026-04-26 15:53:07 +02:00
Olli Pettay adbedd87a3 Bug 2025370 - Properly handle error case in EventListenerManager::GetTypedEventHandler 2026-04-26 15:52:46 +02:00
Moonchild 4f94981ad9 [DOM/XSLT] Don't use txXPathNode by reference.
Follow-up to previous XSLT fixes.
2026-04-26 15:52:36 +02:00
Moonchild fb15e11ef3 [gfx] Stop using binary arithmetic in software filtering.
There was some weird binary arithmetic to artificially clamp values in
calculations for dot products. (multiply by (x >= 0)...)
Switch to `std::clamp()` on the initial value instead.
2026-04-26 15:52:31 +02:00
Tom Schuster b0e1570535 Bug 2025332 - ErrorResult should call ClearUnionData more. 2026-04-26 15:52:26 +02:00
Karl Tomlinson b370042040 Bug 2025483 update mBeginProcessing even on speex_resampler_set_rate() error 2026-04-26 15:52:20 +02:00
Moonchild 60daf77274 [NSS] Deep copy profile data in CERT_FindSMimeProfile. 2026-04-26 15:52:15 +02:00
Moonchild 4f9ed77789 [DOM/XSLT] Prevent circular indexing
Added additional flag to txIndexedKeyHashEntry to signal whether or not
this entry is already in the process of indexing.

The XSL specs 3.0 talk about recursion being fine, but circularity not
being ok, which is the case when a key is already being looked up.
2026-04-26 15:52:04 +02:00
Moonchild c819a0b3c8 No issue - Deduplicate HTMLAllCollection::GetSupportedNames code.
This was duplicated with a minor difference from the code present in
nsContentList::GetSupportedNames.
2026-04-26 15:51:57 +02:00
Moonchild 104f493044 [NSS] Reject excessively large ASN.1 SEQUENCE OF in quickder. 2026-04-26 15:51:14 +02:00
Moonchild ccfb3fc5db [DOM] Avoid leaks in nsXMLPrettyPrinter. 2026-04-26 15:51:05 +02:00
Moonchild 9fa543c9f4 [DOM/WebCrypto] Reject absurdly large salt values. 2026-04-26 15:51:00 +02:00
Moonchild 1d18178eda [DOM] Add a death grip and use locals in BaseMediaResource::ModifyLoadFlags. 2026-04-26 15:50:54 +02:00
Moonchild 8a6b1f309b [DOM] Add a SequenceRooter to ConsoleProfile. 2026-04-26 15:50:48 +02:00
Moonchild a60ab0def7 [widget] Improve clearing of data during clipboard operations. 2026-04-26 15:50:40 +02:00
Daniel Holbert 6276177e20 Bug 2026293: Block scripts when initiating async scrollbar activity. 2026-04-26 15:50:33 +02:00
Moonchild 6c4e8f1466 [accessibility] Hold a strong ref to mParent in AccIterator. 2026-04-26 15:50:22 +02:00
Moonchild 19a4ae248b [gfx] Don't return dummy surfaces. 2026-04-26 15:50:16 +02:00
Moonchild 744212dbf3 [webrtc] Fix off-by-one comparison. 2026-04-26 15:50:10 +02:00
Simon Farre a46fbd6ead Bug 2025971 - Use txSingleNodeContext getter of owned txXPathNode.
eContext gets a copy of aNode. The function should use that one's member
as it's not a shared reference, which we can't know the life time of.
2026-04-26 15:50:04 +02:00
Moonchild bb39100caf Bug 2025976 - Follow-up: Make txXPathNode() a public class member. 2026-04-26 15:49:51 +02:00
Moonchild a27a4e4b60 [DOM/XSLT] Re-fetch index entry. 2026-04-26 15:49:45 +02:00
Simon Farre 490cf03fba Bug 2025976 - Make txxPathNode be a value instead of reference.
txxPathNode has value semantics (it's a smart pointer + uint32_t index;
two different objects of this instance with the same contents are the same
thing).

Increase correctness by making a copy instead of a reference.
2026-04-26 15:49:40 +02:00
Moonchild e93191409e [NSS] Improve input validation in DSAU signature decoding 2026-04-26 15:49:33 +02:00
Moonchild 5cfdaf4ad4 [image] Hold a strong ref on error. 2026-04-26 15:49:28 +02:00
Moonchild 7664a83451 [DOM] Ensure the GC sees consistent states while adopting DOM nodes.
This should prevent some intermittent CC crashes when the wrapper cache
has an incorrect state.
2026-04-26 15:49:22 +02:00
Moonchild f449e1fd7d [DOM] Improve CC/WrapperCache for nursery objects. 2026-04-26 15:49:16 +02:00
Moonchild bbd4a99be2 [network] Ensure UDPSocket remains alive during CloseWithReason. 2026-04-26 15:49:11 +02:00
Moonchild 4ae471baf9 [network] Hold strong ref in nsSyncStreamListener::Available. 2026-04-26 15:49:01 +02:00
Moonchild 4d41b5df11 [network] Force NUL termination in ToStringBuffer AF_LOCAL.
Also reject AF_LOCAL in IPC reader (just in case).
2026-04-26 15:48:54 +02:00
Moonchild 01188c1465 [webrtc] Hold a self-ref on behalf of sigslot, just in case.
Also, stop using these PC_AUTO_ENTER_API_CALL... macros
in functions that aren't actually JS API.
2026-04-26 15:48:41 +02:00
Moonchild 7eac3090a5 [DOM] Fix access to shared RuntimeService::mNavigatorProperties. 2026-04-26 15:48:28 +02:00
Moonchild e9bb602131 Issue #3060 - Align cookie magic prefix handling with the updated spec.
This adds `__Http-` and `__Host-Http-` magic prefixes, and aligns
our checks with RFC6265bis.

Resolves #3060
2026-04-26 15:48:16 +02:00
Moonchild ddc8b21705 [network] Handle WebSocketChannel::IsPersistentFramePtr correctly. 2026-04-26 15:47:59 +02:00
Moonchild 6209d33f4e [network] Hold strong ref in nsDownloader::OnDataAvailable. 2026-04-26 15:47:50 +02:00
Moonchild cbaace24c0 [DOM] Add a death grip. 2026-04-26 15:47:44 +02:00
Moonchild 051951ef00 [network] Use locals for VisitHeader 2026-04-26 15:47:38 +02:00
Moonchild a9062b8710 [DOM] Update some DOM canvas checks. 2026-04-26 15:47:14 +02:00
Moonchild 18c656ebba Issue #3058 - Part 1: Fix arithmetic issue in ConvertYCbCrToRGB32
The more complex part can be landed later.
2026-04-26 15:46:58 +02:00
Moonchild 9220d05de2 [NSS] Fix memory leak in NSC_GenerateKey error path. 2026-04-26 15:46:43 +02:00
Moonchild fdd286d190 [NSS] Protect rwSessionCount with slotLock.
Previously, SFTKSlot.rwSessionCount was incremented and decremented
atomically, which meant that there was no way to synchronize reads from it
in NSC_GetTokenInfo. This patch removes the atomic operations but protects
rwSessionCount with SFTKSlot.slotLock.
SFTKSlot.sessionCount is already protected in this way, so this should
have no performance impact.
2026-04-26 15:46:29 +02:00
Moonchild 4fa8a8ce1d [NSS] Fix potential integer underflow in tls 1.3.
Fix integer underflow in tls13_AEAD when ciphertext is shorter than tag.
2026-04-26 15:46:24 +02:00
Moonchild d5e853a25b [media] Check alpha data pointer instead of length.
`nestegg_packet_additional_data()` can return a non-zero length with a
null-pointer after failure to parse an ID_BLOCK_ADDITIONAL element.
See upstream bug https://github.com/mozilla/nestegg/issues/76
2026-04-26 15:46:18 +02:00
Moonchild 6ea3635847 [network] use nsCOMPtr for mRequest in Base Channel's ScopedRequestSuspender 2026-04-26 15:46:09 +02:00
Moonchild 0ea3d42a38 Issue #2946 - Follow-up: Sanity-check WMF video properties.
Not sure where else to put this under, but it's a WMF HWA related check,
so filing it as a follow-up here to recent work.
Also tag #2949
2026-04-26 15:45:50 +02:00
Moonchild a024df6124 [DOM] More consistently use already-calculated image properties. 2026-04-26 15:45:33 +02:00
Moonchild 11a80021f4 [layout] Minor frame scroll improvements. 2026-04-26 15:45:26 +02:00
Moonchild 301873c751 [XPCOM] Update list of executable extensions on Windows. 2026-04-26 15:45:18 +02:00
Moonchild 90986caee8 [NSS] ensure permittedSubtrees don't match wildcards that could be outside
the permitted tree.
2026-04-26 15:45:12 +02:00
Moonchild 778d93ac49 [network] Ignore non-compliant http server header. 2026-04-03 07:38:32 +02:00
Moonchild f9ba08fa11 [NSS] Update NSS to 3.90.9.1 (custom) 2026-04-03 07:38:24 +02:00
Moonchild 95911aa2ce [gfx] Use local statics for harfbuzz callback pointers
This ensures thread-safe initialization.
2026-04-03 07:38:10 +02:00
Moonchild ccbea05142 [XPCOM] Add more validation to SnappyUncompressInputStream 2026-04-03 07:37:56 +02:00
Moonchild 867c957ceb No issue - Add convolver sanity check 2026-04-03 07:37:41 +02:00
Moonchild 0d2ff3ee65 Merge branch 'master' into release 2026-03-28 19:02:37 +01:00
Moonchild 14122475be Issue #2981 - Add nullcheck in GetPointerCapabilities (uplift)
Uplift to release.
2026-03-09 11:32:39 +01:00
Moonchild d881e7ed56 Merge branch 'master' into release 2026-03-01 23:37:59 +01:00
Moonchild 9b0054c55f Merge branch 'master' into release 2026-02-27 19:28:35 +01:00
Moonchild baeae97784 Merge branch 'master' into release 2026-02-27 07:08:35 +01:00
Moonchild 0324bfa219 Re-sync master to release.
Post-merge synchronization to bypass rebase-shenanigans after backouts.
2026-02-24 17:25:53 +01:00
Moonchild b279fd025b Merge branch 'master' into release
# Conflicts:
#	js/src/jit/CodeGenerator.cpp
#	js/src/jit/arm/Lowering-arm.cpp
#	js/src/jit/arm64/Lowering-arm64.cpp
#	js/src/jit/mips32/Lowering-mips32.cpp
#	js/src/jit/mips64/Lowering-mips64.cpp
#	js/src/jit/shared/LIR-shared.h
#	js/src/jit/x64/Lowering-x64.cpp
#	js/src/jit/x86/Lowering-x86.cpp
#	mfbt/Xoroshiro128PlusPlusRNG.h
#	parser/expat/lib/xmlparse.c
2026-02-24 14:37:42 +01:00
Francis Dominic Fajardo f31546817a Issue #2828 - Follow-up: Simplify rule node tracking and ensure rule walker state isn't reset for the first child processor (uplift)
Styles contained in NAC shouldn't be tracked with their own rule node (as opposed to what was done in https://repo.palemoon.org/MoonchildProductions/UXP/pulls/2859) because it causes precedence issues. This should now more closely imitate the original behavior where NAC and regular document styles (at least, the "unlayered" layer) are grouped together.

This also gets rid of the manual last rule node checks against null, since they are now consistently handled by the separate function.
2026-01-25 14:44:49 +01:00
Moonchild f272382a9c Revert "Issue #2895 - Part 1: Replace XorShift128+ with Xoroshiro128++"
This reverts commit c90df0c332.
2026-01-21 10:18:46 +01:00
Moonchild aa8af9d7f8 Revert "Issue #2895 - Part 2: Remove incorrect debug asserts."
This reverts commit 97786271f9.
2026-01-21 10:18:38 +01:00
Moonchild e1f03ae019 Revert "Issue #2895 - Part 1b: Update license block."
This reverts commit 12821ae90a.
2026-01-21 10:18:08 +01:00
Moonchild f316bc6535 Revert "Issue #2895 - Follow-up: Fix JIT code generator for 32-bit targets."
This reverts commit 8112ed2e6c.
2026-01-21 10:17:51 +01:00
Moonchild 82e4c66520 Revert "Issue #2889 - Part 0: Relocate Mozilla-specific files from Expat source."
This reverts commit f93d0fadf2.
2026-01-21 10:04:52 +01:00
Moonchild 3c923e0467 Revert "Issue #2889 - Part 1: Prepare Mozilla's changes and extensions for Expat 2.6.4."
This reverts commit 6c7850482f.
2026-01-21 10:04:44 +01:00
Moonchild 866985ac88 Revert "Issue #2889 - Part 2: Import Expat 2.6.4 source."
This reverts commit e7cacf4642.
2026-01-21 10:04:37 +01:00
Moonchild ba772b40ad Revert "Issue #2889 - Part 3: Apply Mozilla's patches to Expat 2.6.4."
This reverts commit 2ae8833092.
2026-01-21 10:04:29 +01:00
Moonchild 7a86f0e1b7 Revert "Issue #2889 - Part 4: Fix build and runtime issues."
This reverts commit ef1532cab2.
2026-01-21 10:04:22 +01:00
Moonchild 7e9286f2d8 Revert "Issue #2889 - Follow-up: Avoid conflicts with system version of libexpat"
This reverts commit e284ffab6c.
2026-01-21 10:04:14 +01:00
Moonchild b0d1e365ec Revert "Issue #2889 - Follow-up: void methods shouldn't return a value."
This reverts commit 647a1ab5f0.
2026-01-21 10:04:07 +01:00
Moonchild dbd5a2cbf4 Revert "Issue #2889 - Part 5: Rewrite patches for Expat 2.7.3."
This reverts commit 0f1faad9a3.
2026-01-21 10:03:58 +01:00
Moonchild d60fb1d5c0 Revert "Issue #2889 - Part 6: Import Expat 2.7.3 source."
This reverts commit 627fdf8fe4.
2026-01-21 10:03:49 +01:00
Moonchild 29c91fcdba Revert "Issue #2889 - Part 7: Apply patches to Expat 2.7.3."
This reverts commit 112abdc25a.
2026-01-21 10:03:40 +01:00
Moonchild fe65674f3f Revert "Issue #2889 - Follow-up: Allow generate_hash_secret_salt to be used." 2026-01-21 10:03:24 +01:00
Moonchild a3a6b5ed7e Revert "Issue #2889 - Follow-up: Adjust Expat 2.7.3 local patches for removal of 3rd patch."
This reverts commit 073378ec92.
2026-01-21 10:01:44 +01:00
Moonchild d2de8658a7 Revert "Issue #2889 - Follow-up: Remove fix for BZ 569229."
This reverts commit a22613d3e0.
2026-01-21 10:01:37 +01:00
Moonchild be785b4783 Merge branch 'master' into release
This resyncs platform to master, overwriting more recent backouts from
the release branch.
2026-01-16 23:16:32 +01:00
Moonchild 70e34941c4 [devtools] Remove newline kludge from "Copy as cURL" on Windows 2025-10-15 19:46:52 +02:00
Moonchild 545d52572d Revert "Issue #2828 - Part 1: Build and store the array of layer name tokens in the layer at-rules"
This reverts commit 253ec6706a.
2025-10-08 23:24:27 +02:00
Moonchild dfa0736b49 Revert "Issue #2828 - Part 2: Collect and hold rule cascade data per cascade layer"
This reverts commit a91b385f68.
2025-10-08 23:24:20 +02:00
Moonchild c7bb5664d9 Revert "Issue #2828 - Part 3: Refactor selector matching and rule cascade data into separate files/classes"
This reverts commit 211aa6d652.
2025-10-08 23:24:13 +02:00
Moonchild 6bbc6f3417 Revert "Issue #2828 - Part 4: Move cache key storage to ResolvedRuleCascades"
This reverts commit 202e354f87.
2025-10-08 23:24:07 +02:00
Moonchild 631169a312 Revert "Issue #2828 - Part 5: Implement child rule processors"
This reverts commit bc45ec4f57.
2025-10-08 23:24:02 +02:00
Moonchild 427b3312a6 Revert "Issue #2828 - Part 6: Assert rules were added to the rule cascade data"
This reverts commit be7a231579.
2025-10-08 23:23:56 +02:00
Moonchild 2287b0b57a Revert "Issue #2828 - Part 7: Walk child rule processors separately and ensure inverted cascade layer order is enforced for important rules"
This reverts commit c3e12fe822.
2025-10-08 23:23:50 +02:00
Moonchild 56aaba09b1 Revert "Issue #2828 - Part 8: Extract RuleProcessorGroup (formerly ResolvedRuleCascades) into separate file"
This reverts commit 5fda071898.
2025-10-08 23:23:45 +02:00
Moonchild 332938fef3 Revert "Issue #2828 - Part 9: Rename CascadeEnumData to CascadeLayer"
This reverts commit ebb0ae456c.
2025-10-08 23:23:39 +02:00
Moonchild 13710f7a06 Revert "Issue #2828 – Part 10: Clean up cascade layer constructor"
This reverts commit 047458a002.
2025-10-08 23:23:33 +02:00
Moonchild 530693099b Revert "Issue #2828 - Part 11: Detach weighted rule data from cascade layer"
This reverts commit b1c19137ad.
2025-10-08 23:23:28 +02:00
Moonchild f68aa7ea88 Revert "Issue #2828 - Part 12: Implement cascade layer SizeOfIncludingThis"
This reverts commit 5ef79e303f.
2025-10-08 23:23:23 +02:00
Moonchild 5bdaee5e40 Revert "Issue #2828 - Part 13: Exclude strong layers-related code from release builds"
This reverts commit e82fa3450a.
2025-10-08 23:23:18 +02:00
Moonchild 1b465bc2e2 Revert "Issue #2828 - Part 14: Clobber required for CSS rule processor refactoring"
This reverts commit 038c5a95fc.
2025-10-08 23:23:12 +02:00
Moonchild e455021bea Revert "Issue #2835 - Part 1: Expose nsCSSRuleProcessor::CascadeSheet"
This reverts commit 618f62e753.
2025-10-08 23:23:02 +02:00
Moonchild 4fe1246bcc Revert "Issue #2835 - Part 2: Implement processing of import rules based on order of appearance"
This reverts commit 2ba24302d9.
2025-10-08 23:22:57 +02:00
Moonchild 59b4ac4d5f Revert "Issue #2835 - Follow-up: Guard against import rules with no attached style sheet"
This reverts commit 5fccc6ec3d.
2025-10-08 23:22:42 +02:00
Moonchild de641fedfe Merge branch 'master' into release 2025-10-02 21:21:39 +02:00
Moonchild cb99fabcc0 Merge branch 'master' into release 2025-09-24 10:33:48 +02:00
Moonchild f996ea12c2 Merge branch 'master' into release 2025-09-19 21:04:01 +02:00
Moonchild 4e7fb3e0ea Merge branch 'master' into release 2025-09-18 13:15:14 +02:00
Moonchild e7cbbbef0f Merge branch 'master' into release 2025-09-14 11:54:15 +02:00
Moonchild a181078981 Revert "[gfx] Guard against possible race via gfxFontEntry::GetFontTable."
This reverts commit 98ddf30155.
2025-08-27 15:54:15 +02:00
Moonchild 987a662b51 [NSS] Avoid leak in pkcs12 decoder. 2025-08-20 16:26:17 +02:00
Moonchild 77e3e14e55 [js] Error-check pthread calls
These calls return error states (int) that weren't checked for success.
Failures here are fatal, so using MOZ_RELEASE_ASSERT to safely crash.
2025-08-20 16:26:10 +02:00
Moonchild 98ddf30155 [gfx] Guard against possible race via gfxFontEntry::GetFontTable. 2025-08-20 16:26:03 +02:00
Moonchild 83da5c58a2 Issue #2850 - Alias :focus-visible to :-moz-focusring
Band-aid to have it be parsed as valid with reasonably-expected behaviour.
2025-08-17 10:46:32 +02:00
Moonchild 7136ae45a7 [DOM] Simplify <object> scheme check code and fix plugin handling.
Trying to do a positive check on nested URIs apparently doesn't work,
but the handling could be simplified to just check for non-null mURI
instead - this also fixes plugin loading (which broke with the previous
check).
2025-07-31 10:44:08 +02:00
Moonchild 97d3d61749 [DOM] Fix crash in <object> scheme checking code.
If a website would nor supply a URI for object loading code, the browser
would crash on a null deref.
This reintroduces the nestedURI check to make sure we have a valid URI.
2025-07-30 09:29:51 +02:00
Sergey Larin 9c8bf1fe5d No Issue - Disable VSX extensions (uplift)
There is no detection script for them as for AltiVec, and
it's breaking older machines (PowerMac G5 in particular).
2025-07-25 16:57:09 +02:00
Sergey Larin d1cc6ff3cb Issue #2777 - Fix ffvpx build on PPC64 (uplift) 2025-07-25 16:55:27 +02:00
Moonchild db76d74820 [DOM] Make object loading use an explicit scheme whitelist. 2025-07-25 14:23:45 +02:00
Moonchild 8fdd9d52f9 [network] Stop accepting nameless cookies. 2025-07-25 14:23:34 +02:00
Moonchild d42797f587 [js] Align br_table limits with V8/Gecko. 2025-07-25 14:23:18 +02:00
Moonchild 6b9c1f6ab8 [gfx] Hold a stronger reference to gfxFontEntry. 2025-07-25 14:23:10 +02:00
Moonchild 4aedc96db2 No issue - Adjust CSP URI reporting more closely with the spec.
According to the W3C discussion we should allow websocket URIs to be
reported aside from http/https/ftp ones.
This rewrites things slightly and updates comments to clarify.
We do retain the non-standard reduction to origin only in case the
report is for cross-origin URIs (stops leaking full URIs to the CSP
reported destination).
See https://github.com/w3c/webappsec-csp/issues/735
2025-07-25 14:22:58 +02:00
Francis Dominic Fajardo 234830da1e Issue #2826 - Set up fontconfig on XRE startup (GTK only) 2025-07-25 14:22:35 +02:00
Moonchild 244b95968f Issue #2720 - Follow-up: Use temp value for duplicate color stop 2025-07-25 14:20:13 +02:00
Moonchild 810cd553b5 [devtools] Further improve special character escaping in "copy as curl".
Follow-up to 15335ce39d

Trying to cross-platform sanitize causes issues escaping too much and
as a result mangling the curl commands that get spit out.
This reverts previously added Windows-specific escaping on POSIX and
vice versa.
Since we do not offer cross-platform copying as a curl command in devtools
anyway, it makes little sense to sanitize for the O.S. we're not running on
as we would not be using the command processor in such environments that
could trip over characters for the other O.S. This was previously added
as a defense-in-depth in case we would start offering this, but I see no
real reason to do so, anyway.

Also decided to in-line comments for readability instead of a bulleted
list in the function head.

Mozilla has taken similar steps because of fall-out, but they do offer
cross-platform "copy as curl" for corner cases, so they will have to
find solutions for a problem we won't have.
2025-07-08 22:57:28 +02:00
Basilisk-dev e52eaa961c Issue #2773 - Allow building FFVPX on all architectures (uplift)
Resolves build bustage.
2025-07-03 20:16:10 +02:00
Moonchild b7827091b8 Merge branch 'master' into release 2025-06-26 14:26:02 +02:00
Moonchild 2e344377b5 Merge branch 'master' into release
# Conflicts:
#	devtools/client/shared/curl.js
#	security/nss/lib/ckfw/builtins/certdata.txt
#	security/nss/lib/nss/nss.h
#	security/nss/lib/softoken/softkver.h
#	security/nss/lib/util/nssutil.h
2025-06-24 17:08:59 +02:00
Moonchild 15335ce39d [devtools] Improve special character escaping for curl 2025-05-29 17:28:44 +02:00
Moonchild 14b03e1f8c No issue - Set device contrast to an acceptable value if OOB.
On Mac and Win+DW, enhanced device contrast can possibly not be set.
This throws Skia for a loop by passing in an OOB scalar to its init.
Work around this by setting an accepted average value that helps
prevent font wash-out while not causing fringing.
2025-05-29 17:28:30 +02:00
Moonchild 0968b94e5c No issue - Force C++ run-time type information on protobuf (uplift)
Protobuf uses `dynamic_cast` on polymorphic types which cannot be
inferred properly at compile-time, which can lead to unexpected behavior.
As a code safety measure, enable C++ RTTI for protobuf.
2025-05-29 17:27:29 +02:00
Moonchild ba6b2258aa No issue - Don't support modulo math space in ExtractLinearSum. (uplift) 2025-05-20 00:56:35 +02:00
Moonchild 1e1715ff11 No issue - Fix promise combinator function state. (uplift) 2025-05-19 22:50:48 +02:00
Brian Smith c93381fa79 No Issue - Fixes for building with LLVM 19 (uplift).
Fix a conflict with libc++ 19 and the old Mozilla (re)alloc macros.
LLVM 18+ does not allow std::char_traits<unsigned char> so avoid it.
https://bugzilla.mozilla.org/show_bug.cgi?id=1849070
Partial NSS upgrade to replace ByteString with a class.
https://bugzilla.mozilla.org/show_bug.cgi?id=1851092
2025-05-07 13:01:33 +02:00
Moonchild 65b0a59757 [devtools] Escape some more characters for copying as cURL on Posix. 2025-04-30 15:01:54 +02:00
Moonchild c785639043 [NSS] Update NSS version to 3.90.7 2025-04-30 15:01:48 +02:00
Moonchild 512c259822 [NSS] Update built-in data 2025-04-30 15:01:42 +02:00
Moonchild 90fea6f0d4 [NSS] Improve locking in nssPKIObject_GetInstances. 2025-04-30 15:01:35 +02:00
Moonchild d892468fd0 Issue #2731 - Fix crashes on unknown BigInt types in JIT (uplift)
This only works around the unknown type crashes but doesn't actually fix
attempts at using 64-bit BigInts in Ion.
Resolves #2731
2025-04-22 15:27:34 +02:00
Moonchild 81ab98b329 Merge branch 'master' into release 2025-04-04 20:37:42 +02:00
Moonchild 3f1cacd3e6 Merge branch 'master' into release 2025-04-03 10:22:24 +02:00
Moonchild 6e41e01a29 No issue - fix some minor link issues in about:rights
Privacy was moved to a subdir. Also replacing http with https because
that is what everyone expects by default.
2025-03-07 15:43:13 +01:00
Moonchild 9ce81488d4 No issue - Update Twemoji font to unicode 15.1.3 2025-03-07 02:06:25 +01:00
Moonchild 25bc2630d9 [js] Disable potentially unsafe attempts at recovering JIT operations. 2025-03-06 20:18:39 +01:00
Moonchild e5b69418a0 No Issue - NULL crash fix in nsExternalResourceMap::PendingLoad::OnDataAvailable
Curiously, we should have had this at our fork point (as it was backported
by Mozilla to 52.5.2) by apparently Tobin's import wasn't actually 52.6.0.
:-/
2025-03-06 20:18:24 +01:00
Shadow 229a69be5f Update js/src/wasm/WasmIonCompile.cpp
Bug 1328639 , wasm , Simplify block-value popping in Ion compilation
2025-03-06 20:18:07 +01:00
Moonchild 7f2561312a [layout] Always reserve 64 bits for frame property value
This ensures frame property values can always be stored even in edge cases
on 32-bit machines (where a void ptr is half the width).
2025-02-18 21:42:59 +01:00
Moonchild 93d11a07f9 Issue #2694 - Improve nested grid layout performance by caching.
This improves performance by caching the grid items' block axis
measurement, avoiding potentially exponential calculations and reflows.
Resolves #2694
2025-02-18 16:57:20 +01:00
Moonchild 8e5e24c4c6 Issue #2693 - Disable CSP reporting by default in the platform.
This is a temporary measure to work around CF OOM situations.
Reporting is desirable normally so webmasters get alerted to CSP issues,
and this should be flipped back on once we can.
2025-02-18 10:13:35 +01:00
Moonchild 517ee6754c [DOM] Honor security.csp.reporting.enabled pref in more places. 2025-02-18 10:13:28 +01:00
Moonchild 47690c287c No issue - avoid potential underflow in StructuredClone.
Prevents potential loop-around if there's bogus internal Map data.
2025-02-18 10:13:19 +01:00
Moonchild 364b95170e Merge branch 'master' into release 2025-02-05 23:36:07 +01:00
Moonchild 407006d673 Merge branch 'master' into release 2025-02-05 18:33:29 +01:00
Moonchild 2d60605cc6 Merge branch 'master' into release
# Conflicts:
#	netwerk/cookie/nsCookieService.cpp
2025-02-03 19:13:42 +01:00
Moonchild 2d1129eb7e [network] Don't try to use non-existing connections. 2025-01-13 20:29:31 +01:00
Moonchild 495b4980e7 [DOM] Convert cleanup of FlushCurrentWord() to a ScopeExit task.
Ensures consistent cleanup even if early exit due to OOM.
2025-01-10 15:55:10 +01:00
Moonchild ad480be112 [DOM] Slightly extend lifetime of data in Structured Clone operations. 2025-01-10 15:54:44 +01:00
Moonchild a06001c022 [network] Verify connection NPN against negotiated NPN. 2025-01-10 15:54:35 +01:00
Moonchild 6cbda74aeb Issue #2670 - Compute baseDomain when cookies are read from the database
baseDomain is used as a key for cookies in a hashmap. For cookie
operations to work properly, the baseDomain generation must be reliable.
This is, however, not the case, because the result can change by updates
to the public suffix list (PSL).

Since the stored baseDomain is not reliable, the value must be recomputed
when the database is read. This causes a minor performance hit but is
needed if we want to keep abreast of PSL changes without clobbering the
cookies database.

Resolves #2670
2024-12-24 22:12:33 +01:00
Moonchild 576fbdf490 Issue #2672 - Follow-up: Remove unused telemetry variable. 2024-12-24 22:12:24 +01:00
Moonchild 52b00c38ea Issue #2672 - Part 4: Prevent db access while rebuilding is underway. 2024-12-24 22:12:15 +01:00
Moonchild 8ec56f459b Issue #2672 - Part 3: Ensure thread lifetimes are in tandem. 2024-12-24 22:12:05 +01:00
Moonchild 5cbe423461 Issue #2672 - Part 2: Auto-close syncConn for edge cases. 2024-12-24 22:11:59 +01:00
Moonchild 369fbba750 Issue #2672 - Part 1: Load nsCookieService OMT and use sync reads.
No more lazy-loading on the main thread, thanks. Everyone needs this.
2024-12-24 22:11:52 +01:00
Martok 8e3c35efc6 Issue #1787 - Follow-up: remove no longer used AppClearDataObserver. 2024-12-24 22:11:37 +01:00
Moonchild b3b852b877 Merge branch 'master' into release 2024-12-04 11:10:21 +01:00
Moonchild d5c6e20e9e Merge branch 'master' into release 2024-12-01 20:52:12 +01:00
Moonchild 89b36775fb Merge branch 'master' into release 2024-11-29 10:21:36 +01:00
Karl Tomlinson df16df5693 Bug 1920800 - Remove oldImages from check for flushed old principal handle
The logic should be equivalent when frame IDs on aImages are contiguously
increasing from IDs on previously set frames.

There are currently no callers passing empty aImages, but the logic in this
case would now be as described in the documentation of
UpdatePrincipalHandleForFrameID():

> We will notify mElement that aPrincipalHandle has been applied when all
> FrameIDs prior to aFrameID have been flushed out.
2024-10-31 11:44:56 +01:00
Moonchild aa1fd576ac Issue #2648 - Inherit the content disposition of the multipart response 2024-10-30 10:54:11 +01:00
Moonchild 2512188ca7 Issue #2648 - Apply CSP to documents sent through multipart/x-mixed-replace 2024-10-30 10:54:04 +01:00
Moonchild 89e88ca6a0 Merge branch 'master' into release 2024-10-02 19:45:47 +02:00
Moonchild 2697dd162f [js xpconnect] Fix error handling in xpc::CreateSandboxObject 2024-09-05 10:13:09 +02:00
Moonchild 53a4179c4a [js] Simplify with-env handling in FetchName 2024-09-05 10:13:01 +02:00
Moonchild a120731ddd [DOM] Stop exposing NotifyPaintEvent to web content.
There's no reason this should be available to the web, as it's an
indicator of browser internals.
2024-09-05 10:12:55 +02:00
Moonchild bda611a41a Revert "Issue #2523 - Part 1 - Import headers from FFmpeg 7.0"
This reverts commit 27bb48deaf.
2024-09-03 13:03:20 +02:00
Moonchild 5a02a4a1a4 Revert "Issue #2523 - Part 2 - Update audio & video decoders to work with FFmpeg 7.0"
This reverts commit 7dbc24a739.
2024-09-03 13:03:12 +02:00
Moonchild e59f358b45 Revert "Issue #2527 - Part 1 - Remove old FFmpeg and LibAV headers"
This reverts commit b970fc412a.
2024-09-03 13:02:55 +02:00
Moonchild 90c9535b39 Revert "Issue #2527 - Part 2 - Remove support for libavcodec < 58"
This reverts commit 738c6a740a.
2024-09-03 13:02:46 +02:00
Moonchild ad778bbfdb Revert "Issue #2527 - Part 3 - Remove additional checks for LibAV"
This reverts commit b0f872c919.
2024-09-03 13:02:31 +02:00
Moonchild 8868552b24 Merge branch 'master' into release 2024-08-09 19:35:34 +02:00
Moonchild 66826eb487 Merge branch 'master' into release 2024-08-09 19:18:02 +02:00
Moonchild 39127b5ee9 Merge branch 'master' into release 2024-08-09 16:18:50 +02:00
Moonchild 80cff816a8 Merge branch 'master' into release 2024-08-09 15:56:36 +02:00
Moonchild e9dda8dafa Merge branch 'master' into release
# Conflicts:
#	security/nss/doc/rst/releases/index.rst
#	security/nss/lib/nss/nss.h
#	security/nss/lib/softoken/softkver.h
#	security/nss/lib/util/nssutil.h
2024-08-07 20:13:00 +02:00
Moonchild 11fc818dfb [DOM/network] Disable DNS prefetching if document nodePrincipal is systemPrincipal 2024-07-10 10:54:53 +02:00
Moonchild 84ed844e3f [IPC] Clean up control flow in WaitableEvent. 2024-07-10 10:54:43 +02:00
Moonchild 50af804f1c [network] Add additional cookie setting checks.
Added checks for sub-document navigations from cross-site to same-site in
third-party checks when setting a cookie.
2024-07-10 10:54:37 +02:00
Moonchild 82ce93bce9 No issue - Update SQLite to 3.46.0 2024-07-10 10:54:24 +02:00
Moonchild 228abc8259 No issue - Update NSS to 3.90.3 2024-07-10 10:54:17 +02:00
Moonchild 1692fa5291 Issue #2045 - Temporarily force hidden elements to be actually hidden.
For the time being, because we don't have `revert` yet, we should force
normally hidden elements to be hidden, so they aren't revealed by sites
using the bad practice of `*{ }` style blanking rules but then using
`revert` to re-hide them.
2024-07-10 10:54:02 +02:00
Moonchild bb58c6ae38 Issue #2541 - Deal with empty LineNameList in CSS grid templates.
Resolves #2541
2024-07-02 01:39:01 +02:00
Moonchild 4f58dc27f9 Re-synchronize branches, picking up 2 commits that were not correctly merged. 2024-06-16 12:32:02 +02:00
Moonchild fc5324b9f7 Issue #2532 - Align dialog submission triggered by form.submit() with the spec.
Submission in click handler of submit button should not be deferred
per https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-dialog

See Bug 1719872
2024-06-15 17:56:37 +02:00
Moonchild 561f65aabf Issue #2532 - Prevent unwanted text selection when backdrop is clicked. 2024-06-15 17:56:31 +02:00
Moonchild 9acfe36b95 Issue #2532 - Don't do PreventDefault for escape key if <select> dropdown is not shown
We always use PreventDefault for <select> element, which is problematic if modal
dialog is on as it prevents cancelling the dialog. We fix it by not blocking the
default action if <select> is not shown.

See Bug 1649278
2024-06-15 17:56:25 +02:00
Moonchild ce495cbd85 Issue #2532 - Fix a null pointer crash while doing dialog form submission
See Bug 1652699
2024-06-15 17:56:20 +02:00
Moonchild c44020f188 Issue #2532 - Default pref check to true 2024-06-15 17:56:15 +02:00
Moonchild 35e7a695af Issue #2532 - Implement form[method=dialog]
See bug 1557303
2024-06-15 17:56:08 +02:00
Moonchild 7a55055d22 Merge branch 'master' into release 2024-06-13 21:31:39 +02:00
Moonchild 061900b87f [gfx] Use calloc for cairo font-creation functions. 2024-05-23 13:48:18 +02:00
Moonchild abe32f7309 [gfx] Ensure font entry's unitsPerEm and font extents are initialized when gfxFont is created. 2024-05-23 13:48:11 +02:00
Moonchild 7bfd4c7fe7 [DOM] Clean up ReportLoadError and normalize error messages. 2024-05-23 13:48:04 +02:00
Moonchild 859d6a3e2c [gfx] Clear mSharedBlobData if blob creation failed. 2024-05-23 13:47:58 +02:00
Moonchild c2f05f99af [network] Make http digest auth cnonce length configurable. 2024-05-23 13:47:50 +02:00
Moonchild 55b33fb02b Merge branch 'master' into release 2024-04-19 22:05:10 +02:00
Moonchild c247e40d41 Revert "Update NSS to 3.90.2"
This reverts commit b1cb7e0a8f.
2024-03-23 07:45:56 +01:00
Moonchild 05c58f159d Revert "Undo build system change from NSS update to fix missing command-line utils."
This reverts commit 67d5fefcf2.
2024-03-23 07:45:40 +01:00
Moonchild 67d5fefcf2 Undo build system change from NSS update to fix missing command-line utils. 2024-03-21 21:53:57 +01:00
Moonchild aad017be9e [MFBT] Make move assignment of RefPtr have the same behavior as nsCOMPtr 2024-03-20 19:52:30 +01:00
Moonchild 4543dbf3ff [parser] Specialize AddAttributes for <html>/<body>. 2024-03-20 19:52:24 +01:00
Moonchild b1cb7e0a8f Update NSS to 3.90.2 2024-03-20 19:52:08 +01:00
Moonchild 1c6d21c97d [network] Block set-cookie from multipart/x-mixed-replace 2024-02-22 23:20:07 +01:00
Eitan Isaacson fc42fb38c9 [layout] Process pairs in coord list in PolyArea.
Range -1 assures the array is even with a step size of 2, avoiding lone
value processing.
2024-02-22 23:19:59 +01:00
Jens Stutte 618068c15b [DOM] Check if WorkerRunnable::Run runs on top of WorkerThreadPrimaryRunnable::Run in a worker thread. 2024-02-22 23:19:53 +01:00
FranklinDM 808516a0a8 No issue - Replacing location might throw NS_ERROR_UNEXPECTED while the developer tools window is being destroyed 2024-02-22 23:19:45 +01:00
FranklinDM 7d6b806040 No issue - Remove leftover doorhanger code from the developer tools
Partially based on reverting https://bugzilla.mozilla.org/show_bug.cgi?id=1078539
2024-02-22 23:19:38 +01:00
Martok 6b4e2c9d73 Issue #2453 - Follow-Up: Use hard-coded minimum timer interval in workers.
From the spec: "If nesting level is greater than 5, and timeout is less than 4, then set timeout to 4.",
therefore not having it user-configurable doesn't really break anything.
2024-02-22 23:19:20 +01:00
Moonchild 787883f6a4 Disable URL-paste content loading by default.
See https://repo.palemoon.org/MoonchildProductions/Pale-Moon/issues/1957
2024-02-22 23:18:36 +01:00
Moonchild 7f02753c04 Issue #2465 - Do not use our in-tree metrics hints if using system-cairo
Use a somewhat equivalent font-options instance when using the
system-supplied cairo lib, instead of our in-tree extension.

Resolves #2465
2024-02-07 21:40:55 +01:00
Moonchild 8fa38b3445 Issue #618 - Follow-up: Fix missed constant refactor preventing ExportEntries from working. 2024-02-07 21:40:29 +01:00
Moonchild 541c5f9f45 Merge branch 'master' into release 2024-01-25 15:55:20 +01:00
Moonchild 4b6bd4976a Merge branch 'master' into release
# Conflicts:
#	modules/libpref/init/all.js
2024-01-25 09:09:51 +01:00
Moonchild a0843d52b4 Revert "[XPCOM] Compare return value of readlink in nsLocalFileUnix::GetNativeTarget"
This reverts commit 188f61505f.
2023-12-21 14:03:31 +01:00
Kershaw Chang 977a8cbed8 Bug 1736385 - Make sure thread is alive in CacheIOThread::ThreadFunc 2023-12-21 11:44:50 +01:00
Moonchild 1e85085305 [dom] Better handling of aborted websocket workers.
Catch the case where we are in worker-shutdown but are still connecting
and make filing and closing connections a bit more robust with a RefPtr.
2023-12-21 11:44:42 +01:00
Barret Rennie 188f61505f [XPCOM] Compare return value of readlink in nsLocalFileUnix::GetNativeTarget 2023-12-21 11:44:32 +01:00
Moonchild a514d7f6a4 [layout] Always check against fragment length in nsTextFrame 2023-12-21 11:44:21 +01:00
Moonchild 47c2c75ceb Bug 1868901 2023-12-21 11:44:12 +01:00
Moonchild 7082ec8a9a No issue - Allow redirects for requests that require preflight
Spec update, see Bug 1312864
2023-12-21 11:43:58 +01:00
Brian Smith 2907a84362 Issue #2387 - Remove a missed AddRef() which could cause leaks.
Update comments explaining how the reference counting works.
2023-12-10 23:58:08 +01:00
Brian Smith b8d1ee05c3 Issue #2387 - Collection of fixes related to a crash while canceling a dynamic import.
Add AddRef/Release hooks for embedding's script or module private value and set this script source object where appropriate.
https://bugzilla.mozilla.org/show_bug.cgi?id=1519140 Partial, no Value passing changes.
Clear the list of dynamic import requests after cancelling them in ScriptLoader::ParsingComplete as we do for other requests.
https://bugzilla.mozilla.org/show_bug.cgi?id=1291535
ScriptLoader::OnStreamComplete never returns a failure.
https://bugzilla.mozilla.org/show_bug.cgi?id=1627275
Also cancel the correct kind of parser for Modules.
2023-12-10 23:57:54 +01:00
Moonchild 0b625e624a [DOM] Fix double-free crash in MessagePort.cpp 2023-12-10 17:02:28 +01:00
Moonchild a4da712f91 Issue #2281 - Exclude throw wrapping on modern libcpp.
As discussed.
2023-11-25 18:17:35 +01:00
Moonchild 185f124e87 Issue #2381 - Remove system-nspr/nss leftovers (release port) 2023-11-25 17:15:01 +01:00
Moonchild 8633077691 [WebGL] Flip the validation state for gl_KHR_no_validation.
The original state was inverted due to confusion due to a double
negative (not:no_error).
This validation should only be enabled on Windows (for now).
Future tracking and discussion in BZ 1862039
2023-11-24 12:24:55 +01:00
Moonchild 39a1899045 [DOM] Improve MessagePort state machine. 2023-11-24 12:24:32 +01:00
Moonchild 4dc011a187 [Network] Fix relative URL path starting with multiple slashes 2023-11-24 12:24:19 +01:00
Moonchild ccb12e1dda [DOM] Check if rootDoc is secure context for web compat 2023-11-24 12:24:04 +01:00
Moonchild 63f0d3e295 [WebGL] Turn on more validation/error checking in webgl (when not on Win) 2023-11-24 12:23:49 +01:00
Moonchild 09d598c496 Revert "No Issue - add mutex in EventSource"
This reverts commit 10b3237e52.

Apparently causes deadlocks in Linux.
2023-11-15 12:22:11 +01:00
Moonchild 7e60482d80 No issue - Stop supporting data: scheme in SVG <use> elements. 2023-11-14 12:42:58 +01:00
Moonchild 10b3237e52 No Issue - add mutex in EventSource
Potentially avoids a gc crash when load is high.
2023-11-14 12:42:26 +01:00
athenian200 99af7cc028 Issue #1824 - Support SunOS Linker mapfiles.
Generating OS-appropriate mapfiles from a provided SYMBOL_FILE is
apparently required to work with newer ffvpx. Nothing else in our
codebase actually seemed to require it. Also seems to reduce the amount
of console spam I see relating to symbol visibility during the build
process, and I think it even makes libxul.so link a bit faster.
2023-11-04 01:47:00 -05:00
athenian200 76b360b5d1 Issue #1824 - Move to GCC 10.
It seems to work, but it is a lot slower than compiling with GCC 7.
2023-11-04 01:38:20 -05:00
Moonchild 4001b58a3e [DOM] For now, use C++11 static_asserts only.
Single-param static_assert is C++17 or later.
Follow-up to 3d92b82125
2023-10-27 14:20:10 +02:00
Moonchild 134a8aac87 Issue #35 - Follow-up: undo locale changes so they aren't pre-processed.
Pre-processing loses our localization notes and licensing headers for
l10n which is not a good thing. It's not a big deal having a few unused
strings in these files in the resulting locales.
2023-10-26 22:47:13 +02:00
Moonchild 3e2e48872a Merge branch 'master' into release 2023-10-25 22:51:58 +02:00
Moonchild 622b43cbc5 Merge branch 'master' into release 2023-10-25 22:49:37 +02:00
Moonchild 75b44ef620 Merge branch 'master' into release
# Conflicts:
#	js/src/wasm/WasmBinaryIterator.cpp
#	media/libvpx/vp8/encoder/onyx_if.c
2023-10-05 23:43:10 +02:00
Basilisk-Dev 00084ea49c Cherry-pick upstream libvpx fix
Backport of https://hg.mozilla.org/releases/mozilla-esr115/rev/5241232a3292943bd59ff1704eab60fee3cbc9d1
Addresses CVE-2023-5217
2023-09-28 16:18:01 +02:00
Moonchild b6fae24296 [network] Refactor TransactionObserver::OnDataAvailable() 2023-09-27 21:55:28 +02:00
André Bargull 13c6b7422d [js] Handle dead wrappers 2023-09-27 21:55:19 +02:00
Moonchild 24f2e663cd Restore incorrect SIMD Op removals. 2023-09-25 10:48:42 +02:00
Brian Smith f96b155988 Issue #2313 - Implement WebAssembly sign extension opcodes. (uplift) 2023-09-25 10:46:25 +02:00
Brian Smith d5cc24e916 Issue #2308 & #1240 Follow-up - Fill in missing JSOP_INC/DEC cases for Doubles in Ion. 2023-09-20 03:34:06 +02:00
Brian Smith 8eba271c5f Issue #2308 & #1240 Follow-up - Replace JSOP_POS in ++/-- with JSOP_TONUMERIC.
https://bugzilla.mozilla.org/show_bug.cgi?id=1519135
2023-09-20 03:33:57 +02:00
Brian Smith 19955c82b3 Issue #2308 & #1240 Follow-up - Fill in missing JSOP_INC/DEC cases for Ion on Intel32/64. 2023-09-20 03:33:50 +02:00
Brian Smith 80ae8aec7c Issue #2308 & #1240 Follow-up - Add BigInt support to JSOP_INC and JSOP_DEC.
https://bugzilla.mozilla.org/show_bug.cgi?id=1526309
2023-09-20 03:33:41 +02:00
Brian Smith d8441d7c81 Issue #2308 & #1240 Follow-up - Introduce new increment and decrement operations.
https://bugzilla.mozilla.org/show_bug.cgi?id=1508521
2023-09-20 03:33:33 +02:00
Brian Smith c2446f2478 Issue #2308 - Fix JSON BigInt regressions.
https://bugzilla.mozilla.org/show_bug.cgi?id=1522433
2023-09-20 03:33:23 +02:00
Brian Smith 6efb7a1904 Issue #2282 - Performance observer safety checks.
Both fixes from later revisions, without the Dispatch API changes.
2023-09-20 03:33:14 +02:00
Brian Smith fa0b03a10f Issue #2026 Follow-up: Fill in missing BigInt64 cases in js::IsTypedArrayConstructor().
Hopefully fixes RSA errors on ProtonMail.
2023-09-20 03:32:41 +02:00
Moonchild 3ae2972950 Issue #2309 - Cherry-pick upstream libwebp fix.
Backport of: https://chromium.googlesource.com/webm/libwebp.git/+/2af26267cdfcb63a88e5c74a85927a12d6ca1d76

Resolves #2309
2023-09-13 10:22:50 +02:00
Moonchild 2d48de9998 Merge branch 'master' into release 2023-09-01 15:44:29 +02:00
Moonchild 3b029cdfe4 Merge branch 'master' into release 2023-07-15 16:01:39 +02:00
Moonchild ea9077a8a5 Merge branch 'master' into release 2023-07-07 19:41:06 +02:00
Moonchild b4af6b6265 No issue - Set the default for incremental cycle collector to be off.
Negative performance impact if enabled.
2023-06-05 21:17:24 +02:00
Moonchild ae1d53ceb1 Issue #2257 - Remove rematerialized frames after bailouts and exceptions.
This ensures that rematerialized frames used by the devtools debugger
are properly removed so that no stale data is used during bailouts.
2023-06-05 21:17:13 +02:00
Brian Smith c3f4709d5e Issue #2252 - Prevent crash when attempting to load a script with execution disallowed.
This issue is due to the ExecutionContext added in Issue #1691 not handling GetScript()
in a context where script execution is not allowed.  This expressed itself in crashes when
playing MP4s with the NoScript extension installed and enabled.
2023-06-05 21:16:57 +02:00
FranklinDM a7bb3fc175 Issue #1592 - Follow-up: Ensure topmost scope marker is cleaned up 2023-06-05 21:16:43 +02:00
FranklinDM 6a0203f25f Issue #2250 - Part 2: Ignore the ancestor filter assertion if rule matching is restricted or if the current element is under a shadow host
This only affects debug builds.
2023-06-05 21:16:31 +02:00
FranklinDM b0dfcb147f Issue #2250 - Part 1: Return early if the element being tested for is likely an ancestor and does not have an assigned slot 2023-06-05 21:16:22 +02:00
Job Bautista 06fd4c9357 Issue #2221 - Follow-up: Simplify jit_ioncheck{1|2|3}_deunified_sources assignment. 2023-06-05 21:15:52 +02:00
Job Bautista b9ea7fd9ee Issue #2221 - Follow-up: Ensure jit_ioncheck{1|2|3}_deunified_sources is defined.
Should fix build bustage in armhf, as well as prevent bustage in mips32.
2023-06-05 21:15:33 +02:00
Moonchild 58308a5c7a Merge branch 'master' into release
# Conflicts:
#	python/mozbuild/mozpack/dmg.py
2023-05-11 17:35:14 +02:00
Brian Smith 88c7d54975 No Issue - Fix FreeBSD build failure with WebRTC enabled. (release uplift)
Tag #2227
2023-05-01 22:12:11 +02:00
Timothy Valldeperas eadb5678b3 Issue #2175 - Fix build bustage in WebRTC. (release uplift)
Resolves #2227
2023-05-01 19:04:57 +02:00
Moonchild 54e3e60796 Revert "[devtools] Don't allow sourcemap URLs to redirect"
This reverts commit 2a05494abe.
2023-04-17 10:25:45 +02:00
Moonchild 2a05494abe [devtools] Don't allow sourcemap URLs to redirect 2023-04-13 10:54:34 +02:00
Moonchild bc89e58def [network] Improve checks while parsing MIME parameters. 2023-04-13 10:54:27 +02:00
Moonchild 3a009b97f6 Issue #1911 - Follow-up: Filter out illegal characters in more locations. 2023-04-13 10:54:10 +02:00
Moonchild a105f6d5e9 No issue - Fix off-by-one of kLargeDatasetSize 2023-04-13 10:54:02 +02:00
Sandra 5db241c0c0 Increase size of data over which we write the data to disk rather than keep it around in memory 2023-04-13 10:53:53 +02:00
Sandra d38dca10e5 Use nsAnonymousTemporaryFile for clipboard cache
Base on https://github.com/mozilla/gecko-dev/commit/ecc04a9245b409d7eed7df63ba733cd2073180de
2023-04-13 10:53:14 +02:00
Moonchild 54fc723126 Issue #2180 - Follow-up: Move sentinel check up a bit. 2023-04-02 15:39:05 +02:00
Moonchild 9b8ca17ee4 Issue #2180 - Add pref to control NSS TLS 1.3 protocol downgrade sentinel 2023-04-02 15:38:57 +02:00
Moonchild cddc95b39b Issue #2176 - Don't reconstruct the parent when tearing down
display:contents nodes with pseudo-elements.

We need to use StyleChildrenIterator which iterates over them, instead.
This is a bit of a hack but we can't always have our cake.

We need to be a bit careful though, since ::before and ::after are owned
by their own frame, and thus could be unbound from the tree or even dead
after removing the frame.

This basically ports bugs 1435566 and 1438467
2023-04-02 15:38:31 +02:00
Moonchild 5676529793 Issue #2171 - Skip over shadow nodes that don't have an owning node.
Resolves #2171
2023-04-02 15:37:44 +02:00
Moonchild ce68156cf4 Revert "[widget] Linux GTK3: Detach accessible from moz_container before it's deleted"
This reverts commit 465a18f342.
Resolves #2168
2023-03-18 19:57:56 +01:00
Moonchild 5032ad9593 Issue #2117 - Follow-up: Run precomplete cmd during package staging
We rely on this for all OSes except Mac where precomplete should not
be in the root (it uses Mozilla's fallback packaging that places it in
$RESPATH)
2023-03-17 22:11:30 +01:00
Moonchild b55f765f2e Issue #1911 - Follow-up: Filter out illegal file extensions also.
We already did this for file names, just not extensions.
2023-03-17 12:02:55 +01:00
Moonchild 856078d435 [widget] Linux GTK3: Detach accessible from moz_container before it's deleted 2023-03-17 12:02:46 +01:00
Moonchild c74c262d2f [GFX] Add some sanity checks and clamps to SurfaceData calculations. 2023-03-17 12:02:38 +01:00
Moonchild 787e29e374 No Issue - Ensure more OsiSpace
ensureOsiSpace(); was very much under-used. This adds more instances
where it makes sense to ensure Osi space before placing masm calls.
2023-03-17 12:02:31 +01:00
FranklinDM e439896c9b Issue #2148 - Shrink Vector from (usually) four pointers in size to three
when no inline storage is used.

See Bug 1338374
2023-03-17 12:02:20 +01:00
FranklinDM 15b508f1fb Issue #2148 - Make Vector not use AlignedStorage for its inline element storage
See Bug 1338374 1/2
2023-03-17 12:02:12 +01:00
Job Bautista 5651ebfc76 Issue #2148 - Discard RegExpShared data tables when discarding regexp JIT code.
Based on Mozilla bug 1378736's part 2.
Should fix the double-free.
Follow-up for #2083
2023-03-17 12:02:04 +01:00
Job Bautista 593bfc1ce8 Issue #2148 - Don't null out RegExpObject -> RegExpShared pointer on GC.
Follow-up for issue #2083.
Taken from Mozilla bug 1378736.
2023-03-17 12:01:50 +01:00
Brian Smith 28953cda7a Issue #2160 - Initial support for notarizing during DMG package.
Added --with-macbundle-idenity configure option to set a codesign identity.
If no identity is set or cross-compiling from Linux no codesigning will be
done. Currently doing a full deep bundle v2 sign, instead of limited v1.
2023-03-15 15:10:52 +01:00
Moonchild 516f3f545d Merge branch 'master' into release
# Conflicts:
#	CLOBBER
#	js/src/vm/RegExpObject.cpp
#	security/nss/lib/nss/nss.h
#	security/nss/lib/pkcs12/p12d.c
#	security/nss/lib/softoken/softkver.h
#	security/nss/lib/util/nssutil.h
2023-03-13 13:11:20 +01:00
Moonchild 83aff65a42 Force clobber 2023-02-19 17:53:31 +01:00
Moonchild 5bd97df957 [NSS] Update NSS to 3.52.9 to pick up fixes. 2023-02-19 17:51:26 +01:00
Moonchild 8772711181 [DOM] Check whether module load request was already cancelled when a load fails 2023-02-19 17:51:18 +01:00
Moonchild dc9526f4c6 [widget] Properly test for and handle errors in target-surface creation
and mapping.
2023-02-19 17:51:10 +01:00
Moonchild 9ab36e7ae0 Issue #2103 - Fix typo in RegExp Parser
This corrects the typo where the left-hand character would determine if
the right-hand character would be added or not.

Resolves #2103
2023-02-02 10:50:47 +01:00
Job Bautista e8d30841e7 Issue #2091 - Parse \p{Extended_Pictographic} too.
This is essentially a follow up to Issue #1286. We already have
 UCHAR_EXTENDED_PICTOGRAPHIC in our in-tree ICU, so there's no reason to comment
 this case out.
2023-01-27 05:01:53 +01:00
Martok 9faf29374e Issue #2093 - Trace HeapPtr<RegExpShared::groupsTemplate_> for GC move/compact events, regression from #2072 2023-01-26 20:11:28 +01:00
Moonchild 75e4818d36 Merge branch 'master' into release 2023-01-19 00:42:00 +01:00
Moonchild a65144e9e0 Fix merge conflicts. 2023-01-13 12:55:52 +01:00
Moonchild 4f29548526 Merge branch 'master' into release
# Conflicts:
#	image/decoders/nsJXLDecoder.cpp
#	js/src/irregexp/NativeRegExpMacroAssembler.cpp
#	js/src/irregexp/RegExpAST.h
#	js/src/irregexp/RegExpEngine.cpp
#	js/src/irregexp/RegExpParser.cpp
#	js/src/irregexp/RegExpParser.h
#	xpcom/io/nsLocalFileUnix.cpp
2023-01-13 12:11:56 +01:00
Moonchild 528db2cbd8 Issue #1818 - Remove obsolete path hack in widget code. 2022-12-16 09:13:48 +00:00
Moonchild 84e6bcc1e6 [network] Align cookie checks with RFC 6265 (bis) 2022-12-16 09:13:38 +00:00
Moonchild 0dc9ff518d [libjar] Add some extra sanity checks to our Zip reader. 2022-12-16 09:13:25 +00:00
Moonchild a2e3bd44aa [network] move some generic websocket code to the baseclass 2022-12-16 09:13:09 +00:00
Moonchild 163a0e7caf Revert "Issue #1279 - Implement regular expressions lookbehind (v2)"
This reverts commit d10e8a5b06.
2022-12-15 09:11:02 +00:00
Moonchild 49a86db5f3 Issue #2040 - Pre-multiply the alpha values in our JXL decode buffer. (uplift)
Using selective calculation (only if not opaque) and fast integer
math here should optimize well in compilers.
2022-12-15 09:09:19 +00:00
Moonchild 2640953d8b Issue #2019 - Follow-up: Make nsPluginInstanceOwner also listen to keypress events in the system event group.
nsPluginInstanceOwner only listens to keypress events in the default event group.
However, in our changed operating mode, keypress events are not fired in the
default event group if the key does not result in something printable.
This means that nsPluginInstanceOwner should also listen to keypress events
in the system event group and should handle each keypress that way, but
only once. I.e., if a printable keypress event is received in the system event
group, it should be ignored, since it would've already been handled in the
default event group in that case.
2022-11-26 18:18:09 +00:00
Moonchild 7eb7d67f7a Issue #2033 - Temporary fix of R<->B channel swap.
We have a BGR/RGB channel ordering mismatch here. to at least
provide proper display, a quick&dirty byte swap on the output
buffer will fix this for now, but we should look into seeing where
the surface mismatch is caused.
std::swap() should optimize pretty well in any of the used
compilers, but if necessary, a full buffer ASM routine can be
slotted in (although on current hardware I doubt this will be
even noticeable as it is)
2022-11-26 02:43:18 +00:00
Moonchild e28860ba7f Revert "[XPCOM] Deal with lstat potentially lying in nsLocalFileUnix."
This reverts commit c127f58ef3.
2022-11-20 14:14:48 +00:00
Moonchild 49a96b1d91 Merge branch 'master' into release 2022-11-19 20:15:23 +00:00
Moonchild 3130812693 Merge branch 'master' into release 2022-11-12 18:34:07 +00:00
Moonchild 71ae69aea8 [WebGL] Implement webgl.max-size-per-texture-mib 2022-10-26 14:50:05 +00:00
Moonchild 9e34d697c7 [XPCOM] Fix Base64 off-by-one issue and safeguard against this mistake in the future. 2022-10-26 14:49:55 +00:00
Moonchild 8fa9125d02 [No issue] Hold some strong references on nsRefreshDriver 2022-10-26 14:49:46 +00:00
Brian Smith 4b4488c3e4 Issue #2022 - Part 2 - Add Ventura version detection.
Also add Monterey and Ventura to the graphics driver blocklist.
2022-10-26 14:49:33 +00:00
Brian Smith 248db7d301 Issue #2022 - Part 1 - Fix transparent windows on MacOS 13 Ventura.
During the BaseWindow creation contenView is nil on Ventura...
So create a NSView with the requested dimensions and set is as the contenView.
2022-10-26 14:49:23 +00:00
Moonchild e199f2949b [No issue] Ensure LockImpl::Try() returns the correct bool value. 2022-10-26 14:45:39 +00:00
Moonchild 456b5450a4 Issue #2010 - Ensure raw tagnames are safe exiting internalEntityParser
This resolves #2010
2022-09-28 13:50:10 +00:00
Moonchild d8e629c4a3 Merge branch 'master' into release 2022-09-27 20:12:40 +00:00
Moonchild 4898c4f297 Merge branch 'master' into release 2022-09-24 12:16:59 +00:00
Moonchild 7cd578bbc6 Merge branch 'master' into release 2022-09-22 13:16:48 +00:00
Moonchild 1e91df628a Merge branch 'master' into release 2022-09-22 11:52:16 +00:00
Moonchild b110549cbd Merge branch 'master' into release 2022-07-27 06:07:45 +00:00
Moonchild 971047835a Merge branch 'master' into release
# Conflicts:
#	config/milestone.txt
#	toolkit/mozapps/extensions/internal/XPIProvider.jsm
2022-07-25 20:47:06 +00:00
Moonchild dd4d9eb032 [XPCOM] Crash safely when TArray replacements are OOB.
In the unlikely event of TArray element replacement calls are OOB, crash safely
with a debug breakpoint instead of corrupting memory.
2022-07-03 15:49:44 +00:00
Moonchild 8b94f1e480 [DOM] use the sanitizer to restrict href in svg:use to fragment-only URLs 2022-07-03 15:49:34 +00:00
Moonchild c89610a5c7 [network] Clear PAC loader when the load failed 2022-07-03 15:49:23 +00:00
Moonchild 217963cbed Update NSS to 3.52.7 2022-07-03 15:49:14 +00:00
Moonchild c4f4e18340 [DOM media] Remove potentially unsafe type accesses when debug logging 2022-07-03 15:49:04 +00:00
Moonchild 8a7c0e7345 [network] Clean up and update the list of external protocol handlers. 2022-07-03 15:48:54 +00:00
Moonchild 52e304d450 Issue #1053 - Follow-up: Correct conditional define on POSIX systems. (uplift)
This conditional was incorrectly changed when removing Android support.
This potentially causes issues on Linux systems by not using pthreads correctly,
which may lead to high idle CPU usage.
2022-06-28 13:28:20 +00:00
Moonchild cfc0eeca53 Revert "Issue #1909 - Guard against empty update manifest URL"
This reverts commit d7fadcdef9.
2022-06-07 11:59:07 +00:00
Moonchild ebd3dd9228 Merge branch 'master' into release 2022-06-03 21:50:44 +00:00
Moonchild cb40e4e7ef Merge branch 'master' into release 2022-06-01 13:54:11 +00:00
Moonchild 662dba55fd Merge branch 'master' into release 2022-05-29 11:13:44 +00:00
Moonchild 8760ce023c Issue #1895 - Implement queueMicroTask(callback()) (uplift) 2022-05-07 14:40:14 +00:00
Moonchild b86e148bb7 Roll back milestone version to release. 2022-05-06 12:43:43 +00:00
Moonchild 9e83721e5e Merge branch 'master' into release 2022-05-06 12:43:00 +00:00
Moonchild dc2d6c2e60 Revert "No Issue - Make content-type on JAR channels behave the same as HTTP channels."
This reverts commit 425677ada7.
2022-05-03 17:38:19 +00:00
Moonchild 4ada6f6762 Update 7zSD for v31 2022-05-03 17:38:12 +00:00
739 changed files with 347351 additions and 10773 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 Python 3 migration
Clobber for Idle GC backout
+8
View File
@@ -0,0 +1,8 @@
TRADEMARK NOTICE
================
The name "Goanna" and visual representations (logo) have not been
registered by the Copyright owners as a trademark in any jurisdiction.
However, because Goanna has been distributed and maintained world-wide,
continually since 2015, the Copyright owners claim "common-law trademark
protection" in any jurisdiction where common-law trademark is recognized.
+1
View File
@@ -152,6 +152,7 @@ def old_configure_options(*options):
'--enable-jitspew',
'--enable-js-lto',
'--enable-leak-sanitizer',
'--enable-libaom',
'--enable-libjpeg-turbo',
'--enable-libproxy',
'--enable-llvm-hacks',
+38
View File
@@ -61,6 +61,44 @@ set_config('HAVE_YASM', have_yasm)
# Until the YASM variable is not necessary in old-configure.
add_old_configure_assignment('YASM', have_yasm)
# nasm detection
# ==============================================================
nasm = check_prog('NASM', ['nasm'], allow_missing=True)
@depends_if(nasm)
@checking('nasm version')
def nasm_version(nasm):
version = check_cmd_output(
nasm, '-v',
onerror=lambda: die('Failed to get nasm version.')
).splitlines()[0].split()[2]
return Version(version)
@depends(nasm, nasm_version)
def have_nasm(nasm, version):
if nasm and version >= Version('2.14'):
return True
set_config('HAVE_NASM', have_nasm)
@depends(have_nasm, target)
def nasm_asflags(have_nasm, target):
if have_nasm:
asflags = {
('OSX', 'x86'): '-f macho32',
('OSX', 'x86_64'): '-f macho64',
('WINNT', 'x86'): '-f win32',
('WINNT', 'x86_64'): '-f win64',
}.get((target.os, target.cpu), None)
if asflags is None:
if target.cpu == 'x86':
asflags = '-f elf32'
elif target.cpu == 'x86_64':
asflags = '-f elf64'
return asflags
set_config('NASM_ASFLAGS', nasm_asflags)
# MacOS deployment target version
# ==============================================================
# This needs to happen before any compilation test is done.
+4 -1
View File
@@ -29,7 +29,10 @@ if CONFIG['MOZ_WEBM_ENCODER']:
external_dirs += ['media/libvpx']
if CONFIG['MOZ_AV1']:
external_dirs += ['media/libaom']
if CONFIG['AV1_USE_AOM']:
external_dirs += ['media/libaom']
else:
external_dirs += ['media/libdav1d']
external_dirs += ['media/libpng']
+2 -2
View File
@@ -210,10 +210,10 @@ function initialHTML(doc) {
let style = doc.createElement("link");
style.rel = "stylesheet";
style.type = "text/css";
style.href = "css/main.css";
style.href = base.href +"css/main.css";
let script = doc.createElement("script");
script.src = "lib/require.js";
script.src = base.href + "lib/require.js";
script.dataset.main = "viewer-config";
script.defer = true;
@@ -103,12 +103,6 @@ function StyleSheetEditor(styleSheet, win, file, isNew, walker, highlighter) {
}
};
this._styleSheetFilePath = null;
if (styleSheet.href &&
Services.io.extractScheme(this.styleSheet.href) == "file") {
this._styleSheetFilePath = this.styleSheet.href;
}
this._onPropertyChange = this._onPropertyChange.bind(this);
this._onError = this._onError.bind(this);
this._onMediaRuleMatchesChange = this._onMediaRuleMatchesChange.bind(this);
@@ -664,8 +658,7 @@ StyleSheetEditor.prototype = {
if (this._friendlyName) {
defaultName = OS.Path.basename(this._friendlyName);
}
showFilePicker(file || this._styleSheetFilePath, true, this._window,
onFile, defaultName);
showFilePicker(file, true, this._window, onFile, defaultName);
},
/**
@@ -1,98 +1,112 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that 'Save' function works.
const TESTCASE_URI_HTML = TEST_BASE_HTTP + "simple.html";
const TESTCASE_URI_CSS = TEST_BASE_HTTP + "simple.css";
var tempScope = {};
Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
var FileUtils = tempScope.FileUtils;
var NetUtil = tempScope.NetUtil;
add_task(function* () {
let htmlFile = yield copy(TESTCASE_URI_HTML, "simple.html");
yield copy(TESTCASE_URI_CSS, "simple.css");
let uri = Services.io.newFileURI(htmlFile);
let filePath = uri.resolve("");
let { ui } = yield openStyleEditorForURL(filePath);
let editor = ui.editors[0];
yield editor.getSourceEditor();
info("Editing the style sheet.");
let dirty = editor.sourceEditor.once("dirty-change");
let beginCursor = {line: 0, ch: 0};
editor.sourceEditor.replaceText("DIRTY TEXT", beginCursor, beginCursor);
yield dirty;
is(editor.sourceEditor.isClean(), false, "Editor is dirty.");
ok(editor.summary.classList.contains("unsaved"),
"Star icon is present in the corresponding summary.");
info("Saving the changes.");
dirty = editor.sourceEditor.once("dirty-change");
editor.saveToFile(null, function (file) {
ok(file, "file should get saved directly when using a file:// URI");
});
yield dirty;
is(editor.sourceEditor.isClean(), true, "Editor is clean.");
ok(!editor.summary.classList.contains("unsaved"),
"Star icon is not present in the corresponding summary.");
});
function copy(srcChromeURL, destFileName) {
let deferred = defer();
let destFile = FileUtils.getFile("ProfD", [destFileName]);
write(read(srcChromeURL), destFile, deferred.resolve);
return deferred.promise;
}
function read(srcChromeURL) {
let scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"]
.getService(Ci.nsIScriptableInputStream);
let channel = NetUtil.newChannel({
uri: srcChromeURL,
loadUsingSystemPrincipal: true
});
let input = channel.open2();
scriptableStream.init(input);
let data = "";
while (input.available()) {
data = data.concat(scriptableStream.read(input.available()));
}
scriptableStream.close();
input.close();
return data;
}
function write(data, file, callback) {
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
let istream = converter.convertToInputStream(data);
let ostream = FileUtils.openSafeFileOutputStream(file);
NetUtil.asyncCopy(istream, ostream, function (status) {
if (!Components.isSuccessCode(status)) {
info("Couldn't write to " + file.path);
return;
}
callback(file);
});
}
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that 'Save' function works.
const TESTCASE_URI_HTML = TEST_BASE_HTTP + "simple.html";
const TESTCASE_URI_CSS = TEST_BASE_HTTP + "simple.css";
var tempScope = {};
Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
var FileUtils = tempScope.FileUtils;
var NetUtil = tempScope.NetUtil;
add_task(function* () {
let htmlFile = yield copy(TESTCASE_URI_HTML, "simple.html");
const cssFile = await copy(TESTCASE_URI_CSS, "simple.css");
let uri = Services.io.newFileURI(htmlFile);
let filePath = uri.resolve("");
let { ui } = yield openStyleEditorForURL(filePath);
let editor = ui.editors[0];
yield editor.getSourceEditor();
is(
editor.savedFile,
null,
"savedFile should not be pre-populated from the source file"
);
info("Editing the style sheet.");
let dirty = editor.sourceEditor.once("dirty-change");
let beginCursor = {line: 0, ch: 0};
editor.sourceEditor.replaceText("DIRTY TEXT", beginCursor, beginCursor);
yield dirty;
is(editor.sourceEditor.isClean(), false, "Editor is dirty.");
ok(editor.summary.classList.contains("unsaved"),
"Star icon is present in the corresponding summary.");
info(
"Saving the changes with an explicit file (simulating a user-chosen save location)."
);
dirty = editor.sourceEditor.once("dirty-change");
editor.saveToFile(cssFile, function (file) {
ok(file, "file should get saved when explicitly passing a file");
});
yield dirty;
is(editor.sourceEditor.isClean(), true, "Editor is clean.");
ok(!editor.summary.classList.contains("unsaved"),
"Star icon is not present in the corresponding summary.");
is(
editor.savedFile?.path,
cssFile.path,
"savedFile should now be set on the editor"
);
});
function copy(srcChromeURL, destFileName) {
let deferred = defer();
let destFile = FileUtils.getFile("ProfD", [destFileName]);
write(read(srcChromeURL), destFile, deferred.resolve);
return deferred.promise;
}
function read(srcChromeURL) {
let scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"]
.getService(Ci.nsIScriptableInputStream);
let channel = NetUtil.newChannel({
uri: srcChromeURL,
loadUsingSystemPrincipal: true
});
let input = channel.open2();
scriptableStream.init(input);
let data = "";
while (input.available()) {
data = data.concat(scriptableStream.read(input.available()));
}
scriptableStream.close();
input.close();
return data;
}
function write(data, file, callback) {
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
let istream = converter.convertToInputStream(data);
let ostream = FileUtils.openSafeFileOutputStream(file);
NetUtil.asyncCopy(istream, ostream, function (status) {
if (!Components.isSuccessCode(status)) {
info("Couldn't write to " + file.path);
return;
}
callback(file);
});
}
@@ -28,7 +28,10 @@ add_task(function* () {
let HTMLFile = yield copy(TESTCASE_URI_HTML, ["sourcemaps.html"]);
let CSSFile = yield copy(TESTCASE_URI_CSS,
["sourcemap-css", "sourcemaps.css"]);
yield copy(TESTCASE_URI_SCSS, ["sourcemap-sass", "sourcemaps.scss"]);
const SCSSFile = await copy(TESTCASE_URI_SCSS, [
"sourcemap-sass",
"sourcemaps.scss",
]);
yield copy(TESTCASE_URI_MAP, ["sourcemap-css", "sourcemaps.css.map"]);
yield copy(TESTCASE_URI_REG_CSS, ["simple.css"]);
@@ -59,7 +62,7 @@ add_task(function* () {
// Edit and save Sass in the editor. This will start off a file-watching
// process waiting for the CSS file to change.
yield editSCSS(editor);
yield editSCSS(SCSSFile, editor);
// We can't run Sass or another compiler, so we fake it by just
// directly changing the CSS file.
@@ -73,12 +76,12 @@ add_task(function* () {
is(color, "rgb(0, 0, 255)", "div is blue after saving file");
});
function editSCSS(editor) {
function editSCSS(SCSSFile, editor) {
let deferred = defer();
editor.sourceEditor.setText(CSS_TEXT);
editor.saveToFile(null, function (file) {
editor.saveToFile(SCSSFile, function (file) {
ok(file, "Scss file should be saved");
deferred.resolve();
});
+1 -1
View File
@@ -196,7 +196,7 @@ public:
{
MOZ_ASSERT(!NS_IsMainThread());
int32_t written = PR_Write(mFD, mData, mLength);
int32_t written = mLength < INT32_MAX ? PR_Write(mFD, mData, mLength) : -1;
if (NS_WARN_IF(written < 0 || uint32_t(written) != mLength)) {
return NS_DispatchToMainThread(
new ErrorPropagationRunnable(mBlobStorage, NS_ERROR_FAILURE));
+1
View File
@@ -1004,6 +1004,7 @@ GK_ATOM(parameter, "parameter")
GK_ATOM(parent, "parent")
GK_ATOM(parentfocused, "parentfocused")
GK_ATOM(parsetype, "parsetype")
GK_ATOM(part, "part")
GK_ATOM(password, "password")
GK_ATOM(pattern, "pattern")
GK_ATOM(patternSeparator, "pattern-separator")
+2 -2
View File
@@ -97,7 +97,7 @@ ToJSValue(JSContext* aCx,
return true;
}
// accept floating point types
// Accept floating point types
inline bool
ToJSValue(JSContext* aCx,
float aArgument,
@@ -106,7 +106,7 @@ ToJSValue(JSContext* aCx,
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
aValue.setNumber(aArgument);
aValue.set(JS_NumberValue(double(aArgument)));
return true;
}
+46 -30
View File
@@ -39,6 +39,44 @@ WebGLTransformFeedback::Delete()
////////////////////////////////////////
// Validation helper for beginning/resuming the TF and computing the
// vertex capacity.
bool
WebGLTransformFeedback::PrepareTransformFeedback() {
const auto& prog = mContext->mCurrentProgram;
if (!prog ||
!prog->IsLinked() ||
!prog->LinkInfo()->componentsPerTFVert.size()) {
mContext->ErrorInvalidOperation("Current program not valid for transform feedback.");
return false;
}
const auto& linkInfo = prog->LinkInfo();
const auto& componentsPerTFVert = linkInfo->componentsPerTFVert;
mActive_VertCapacity = 0;
size_t minVertCapacity = SIZE_MAX;
for (size_t i = 0; i < componentsPerTFVert.size(); i++) {
const auto& indexedBinding = mIndexedBindings[i];
const auto& componentsPerVert = componentsPerTFVert[i];
const auto& buffer = indexedBinding.mBufferBinding;
if (!buffer) {
mContext->ErrorInvalidOperation("No buffer attached to required transform feedback index %u.",
(uint32_t)i);
return false;
}
const size_t vertCapacity = buffer->ByteLength() / 4 / componentsPerVert;
minVertCapacity = std::min(minVertCapacity, vertCapacity);
}
mActive_VertCapacity = minVertCapacity;
return true;
}
void
WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
{
@@ -59,37 +97,10 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
return;
}
const auto& prog = mContext->mCurrentProgram;
if (!prog ||
!prog->IsLinked() ||
!prog->LinkInfo()->componentsPerTFVert.size())
{
mContext->ErrorInvalidOperation("%s: Current program not valid for transform"
" feedback.",
funcName);
if (!PrepareTransformFeedback()) {
return;
}
const auto& linkInfo = prog->LinkInfo();
const auto& componentsPerTFVert = linkInfo->componentsPerTFVert;
size_t minVertCapacity = SIZE_MAX;
for (size_t i = 0; i < componentsPerTFVert.size(); i++) {
const auto& indexedBinding = mIndexedBindings[i];
const auto& componentsPerVert = componentsPerTFVert[i];
const auto& buffer = indexedBinding.mBufferBinding;
if (!buffer) {
mContext->ErrorInvalidOperation("%s: No buffer attached to required transform"
" feedback index %u.",
funcName, (uint32_t)i);
return;
}
const size_t vertCapacity = buffer->ByteLength() / 4 / componentsPerVert;
minVertCapacity = std::min(minVertCapacity, vertCapacity);
}
////
const auto& gl = mContext->gl;
@@ -101,10 +112,9 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
mIsActive = true;
MOZ_ASSERT(!mIsPaused);
mActive_Program = prog;
mActive_Program = mContext->mCurrentProgram;
mActive_PrimMode = primMode;
mActive_VertPosition = 0;
mActive_VertCapacity = minVertCapacity;
////
@@ -173,6 +183,12 @@ WebGLTransformFeedback::ResumeTransformFeedback()
return;
}
// Re-run prepare in case some of the buffers have been modified
// while the TF was paused.
if (!PrepareTransformFeedback()) {
return;
}
////
const auto& gl = mContext->gl;
+1
View File
@@ -44,6 +44,7 @@ public:
WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
private:
~WebGLTransformFeedback();
bool PrepareTransformFeedback();
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
-1
View File
@@ -26,7 +26,6 @@ support-files =
image_yellow75.png
imagebitmap_bug1239300.js
imagebitmap_bug1239752.js
imagebitmap_extensions.html
imagebitmap_on_worker.js
imagebitmap_structuredclone.js
imagebitmap_structuredclone_iframe.html
+1
View File
@@ -63,6 +63,7 @@ EncodingUtils::IsAsciiCompatible(const nsACString& aPreferredName)
aPreferredName.LowerCaseEqualsLiteral("utf-16be") ||
aPreferredName.LowerCaseEqualsLiteral("utf-16le") ||
aPreferredName.LowerCaseEqualsLiteral("replacement") ||
aPreferredName.LowerCaseEqualsLiteral("iso-2022-jp") ||
aPreferredName.LowerCaseEqualsLiteral("hz-gb-2312") ||
aPreferredName.LowerCaseEqualsLiteral("utf-7") ||
aPreferredName.LowerCaseEqualsLiteral("x-imap4-modified-utf7"));
+1 -1
View File
@@ -652,7 +652,7 @@ nsresult nsGeolocationService::Init()
#endif
#ifdef MOZ_WIDGET_COCOA
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
if (Preferences::GetBool("geo.provider.use_corelocation", true)) {
mProvider = new CoreLocationLocationProvider();
}
+2 -10
View File
@@ -876,20 +876,12 @@ HTMLImageElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLImageElementBinding::Wrap(aCx, this, aGivenProto);
}
#ifdef DEBUG
nsIDOMHTMLFormElement*
HTMLImageElement::GetForm() const
{
return mForm;
}
#endif
void
HTMLImageElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
mForm = static_cast<HTMLFormElement*>(aForm);
}
+2 -3
View File
@@ -216,9 +216,8 @@ public:
SetHTMLAttr(nsGkAtoms::lowsrc, aLowsrc, aError);
}
#ifdef DEBUG
nsIDOMHTMLFormElement* GetForm() const;
#endif
HTMLFormElement* GetForm() const { return mForm; };
void SetForm(nsIDOMHTMLFormElement* aForm);
void ClearForm(bool aRemoveFromForm);
+5 -1
View File
@@ -18,6 +18,8 @@
#include "nsContentUtils.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIProtocolHandler.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Shared)
@@ -186,6 +188,8 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
newBaseURI = nullptr;
}
if (csp && newBaseURI) {
bool isLocalResource = false;
rv = NS_URIChainHasFlags(newBaseURI, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &isLocalResource);
// base-uri is only enforced if explicitly defined in the
// policy - do *not* consult default-src, see:
// http://www.w3.org/TR/CSP2/#directive-default-src
@@ -193,7 +197,7 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
rv = csp->Permits(newBaseURI, nsIContentSecurityPolicy::BASE_URI_DIRECTIVE,
true /* aSpecific */, true /* aSendViolationReports */,
&cspPermitsBaseURI);
if (NS_FAILED(rv) || !cspPermitsBaseURI) {
if ((NS_FAILED(rv) || !cspPermitsBaseURI) && !isLocalResource) {
newBaseURI = nullptr;
}
}
+2 -2
View File
@@ -1824,8 +1824,8 @@ void
nsGenericHTMLFormElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
// keep a *weak* ref to the form here
mForm = static_cast<HTMLFormElement*>(aForm);
+5 -17
View File
@@ -105,8 +105,6 @@ gDownMixMatrices[CUSTOM_CHANNEL_LAYOUTS*(CUSTOM_CHANNEL_LAYOUTS - 1)/2] =
* Given an array of input channels, downmix to aOutputChannelCount, and copy
* the results to the channel buffers in aOutputChannels. Don't call this with
* input count <= output count.
* Each of aOutputChannels must be non-null.
* aChannelArray elements may be null.
*/
template<typename T>
void AudioChannelsDownMix(const nsTArray<const T*>& aChannelArray,
@@ -121,11 +119,7 @@ void AudioChannelsDownMix(const nsTArray<const T*>& aChannelArray,
if (inputChannelCount > 6) {
// Just drop the unknown channels.
for (uint32_t o = 0; o < aOutputChannelCount; ++o) {
if (inputChannels[o]) {
PodCopy(aOutputChannels[o], inputChannels[o], aDuration);
} else {
std::fill_n(aOutputChannels[o], aDuration, static_cast<T>(0));
}
PodCopy(aOutputChannels[o], inputChannels[o], aDuration);
}
return;
}
@@ -144,19 +138,13 @@ void AudioChannelsDownMix(const nsTArray<const T*>& aChannelArray,
// want an input channel to contribute to nothing
T outputChannels[CUSTOM_CHANNEL_LAYOUTS + 1] = {0};
for (uint32_t c = 0; c < inputChannelCount; ++c) {
if (inputChannels[c]) {
outputChannels[m.mInputDestination[c]] +=
m.mInputCoefficient[c] *
(static_cast<const T*>(inputChannels[c]))[s];
}
outputChannels[m.mInputDestination[c]] +=
m.mInputCoefficient[c]*(static_cast<const T*>(inputChannels[c]))[s];
}
// Utilize the fact that in every layout, C is the third channel.
if (m.mCExtraDestination != IGNORE) {
if (inputChannels[SURROUND_C]) {
outputChannels[m.mCExtraDestination] +=
m.mInputCoefficient[SURROUND_C] *
(static_cast<const T*>(inputChannels[SURROUND_C]))[s];
}
outputChannels[m.mCExtraDestination] +=
m.mInputCoefficient[SURROUND_C]*(static_cast<const T*>(inputChannels[SURROUND_C]))[s];
}
for (uint32_t c = 0; c < aOutputChannelCount; ++c) {
+26 -8
View File
@@ -7,6 +7,7 @@
#include <speex/speex_resampler.h>
#include <string.h>
#include <cmath>
#include "mozilla/CheckedInt.h"
/*
* Parts derived from MythTV AudioConvert Class
@@ -262,8 +263,15 @@ AudioConverter::ResampleAudio(void* aOut, const void* aIn, size_t aFrames)
if (!mResampler) {
return 0;
}
uint32_t outframes = ResampleRecipientFrames(aFrames);
uint32_t inframes = aFrames;
uint32_t outframes;
if (!ResampleRecipientFrames(aFrames, &outframes)) {
return 0;
}
CheckedUint32 inframesChecked(aFrames);
if (!inframesChecked.isValid()) {
return 0;
}
uint32_t inframes = inframesChecked.value();
int error;
if (mOut.Format() == AudioConfig::FORMAT_FLT) {
@@ -288,7 +296,7 @@ AudioConverter::ResampleAudio(void* aOut, const void* aIn, size_t aFrames)
mResampler = nullptr;
return 0;
}
MOZ_ASSERT(inframes == aFrames, "Some frames will be dropped");
MOZ_ASSERT(static_cast<size_t>(inframes) == aFrames, "Some frames will be dropped");
return outframes;
}
@@ -373,17 +381,27 @@ AudioConverter::UpmixAudio(void* aOut, const void* aIn, size_t aFrames) const
return aFrames;
}
size_t
AudioConverter::ResampleRecipientFrames(size_t aFrames) const
{
bool AudioConverter::ResampleRecipientFrames(size_t aFrames,
uint32_t* aOutFrames) const {
if (!aFrames && mIn.Rate() != mOut.Rate()) {
if (!mResampler) {
return 0;
*aOutFrames = 0;
return true;
}
// We drain by pushing in get_input_latency() samples of 0
aFrames = speex_resampler_get_input_latency(mResampler);
}
return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1;
CheckedInt<uint64_t> numerator = CheckedInt<uint64_t>(aFrames) * mOut.Rate();
if (!numerator.isValid()) {
return false;
}
CheckedUint32 outFrames(numerator.value() / mIn.Rate());
outFrames += 1u;
if (!outFrames.isValid()) {
return false;
}
*aOutFrames = outFrames.value();
return true;
}
size_t
+9 -2
View File
@@ -7,6 +7,7 @@
#define AudioConverter_h
#include "MediaInfo.h"
#include "mozilla/CheckedInt.h"
// Forward declaration
typedef struct SpeexResamplerState_ SpeexResamplerState;
@@ -163,9 +164,15 @@ public:
AlignedBuffer<Value>* outputBuffer = &temp1;
AlignedBuffer<Value> temp2;
if (!frames || mOut.Rate() > mIn.Rate()) {
uint32_t resampledFrames;
// We are upsampling or about to drain, we can't work in place.
// Allocate another temporary buffer where the upsampling will occur.
if (!temp2.SetLength(FramesOutToSamples(ResampleRecipientFrames(frames)))) {
if (!ResampleRecipientFrames(frames, &resampledFrames)) {
return AudioDataBuffer<Format, Value>(std::move(temp2));
}
CheckedInt<size_t> outputSamples =
CheckedInt<size_t>(resampledFrames) * mOut.Channels();
if (!outputSamples.isValid() || !temp2.SetLength(outputSamples.value())) {
return AudioDataBuffer<Format, Value>(Move(temp2));
}
outputBuffer = &temp2;
@@ -229,7 +236,7 @@ private:
// Resampler context.
SpeexResamplerState* mResampler;
size_t ResampleAudio(void* aOut, const void* aIn, size_t aFrames);
size_t ResampleRecipientFrames(size_t aFrames) const;
bool ResampleRecipientFrames(size_t aFrames, uint32_t* aOutFrames) const;
void RecreateResampler();
size_t DrainResampler(void* aOut);
};
+3 -9
View File
@@ -121,19 +121,13 @@ AudioSegment::Mix(AudioMixer& aMixer, uint32_t aOutputChannels,
}
if (channelData.Length() < aOutputChannels) {
// Up-mix.
AudioChannelsUpMix(&channelData, aOutputChannels, static_cast<const AudioDataValue*>(nullptr));
AudioChannelsUpMix(&channelData, aOutputChannels, SilentChannel::ZeroChannel<AudioDataValue>());
for (uint32_t channel = 0; channel < aOutputChannels; channel++) {
AudioDataValue* ptr =
PointerForOffsetInChannel(buf.Elements(), outBufferLength,
aOutputChannels, channel, offsetSamples);
if (channelData[channel]) {
PodCopy(
ptr,
reinterpret_cast<const AudioDataValue*>(channelData[channel]),
frames);
} else {
PodZero(ptr, frames);
}
PodCopy(ptr, reinterpret_cast<const AudioDataValue*>(channelData[channel]),
frames);
}
MOZ_ASSERT(channelData.Length() == aOutputChannels);
} else if (channelData.Length() > aOutputChannels) {
+9 -16
View File
@@ -61,22 +61,15 @@ template <typename SrcT, typename DestT>
static void
InterleaveAndConvertBuffer(const SrcT* const* aSourceChannels,
uint32_t aLength, float aVolume,
uint32_t aChannelCount,
uint32_t aChannels,
DestT* aOutput)
{
for (size_t channel = 0; channel < aChannelCount; ++channel) {
DestT* output = aOutput;
if (aSourceChannels[channel]) {
for (size_t i = 0; i < aLength; ++i) {
float v = AudioSampleToFloat(aSourceChannels[channel][i])*aVolume;
*output = FloatToAudioSample<DestT>(v);
output += aChannelCount;
}
} else {
for (size_t i = 0; i < aLength; ++i) {
*output = static_cast<DestT>(0);
output += aChannelCount;
}
DestT* output = aOutput;
for (size_t i = 0; i < aLength; ++i) {
for (size_t channel = 0; channel < aChannels; ++channel) {
float v = AudioSampleToFloat(aSourceChannels[channel][i])*aVolume;
*output = FloatToAudioSample<DestT>(v);
++output;
}
}
}
@@ -100,7 +93,7 @@ DeinterleaveAndConvertBuffer(const SrcT* aSourceBuffer,
class SilentChannel
{
public:
static const int AUDIO_PROCESSING_FRAMES = 640; /* > 10ms of 48KHz audio */
static const int AUDIO_PROCESSING_FRAMES = 4096; /* > 10ms of 48KHz audio */
static const uint8_t gZeroChannel[MAX_AUDIO_SAMPLE_SIZE*AUDIO_PROCESSING_FRAMES];
// We take advantage of the fact that zero in float and zero in int have the
// same all-zeros bit layout.
@@ -415,7 +408,7 @@ void WriteChunk(AudioChunk& aChunk,
if (channelData.Length() < aOutputChannels) {
// Up-mix. Note that this might actually make channelData have more
// than aOutputChannels temporarily.
AudioChannelsUpMix(&channelData, aOutputChannels, static_cast<const SrcT*>(nullptr));
AudioChannelsUpMix(&channelData, aOutputChannels, SilentChannel::ZeroChannel<SrcT>());
}
if (channelData.Length() > aOutputChannels) {
// Down-mix.
+2 -1
View File
@@ -367,12 +367,13 @@ public:
{
}
static const uint32_t MIN_RATE = 8000;
static const uint32_t MAX_RATE = 640000;
bool IsValid() const override
{
return mChannels > 0 && mChannels <= MAX_AUDIO_CHANNELS
&& mRate > 0 && mRate <= MAX_RATE;
&& mRate >= MIN_RATE && mRate <= MAX_RATE;
}
AudioInfo* GetAsAudioInfo() override
+1 -1
View File
@@ -111,7 +111,7 @@ private:
DECL_MEDIA_PREF("media.ffvpx.enabled", PDMFFVPXEnabled, bool, true);
#endif
#ifdef MOZ_AV1
DECL_MEDIA_PREF("media.av1.enabled", AV1Enabled, bool, false);
DECL_MEDIA_PREF("media.av1.enabled", AV1Enabled, bool, true);
#endif
#ifdef XP_WIN
DECL_MEDIA_PREF("media.wmf.enabled", PDMWMFEnabled, bool, true);
+6
View File
@@ -179,12 +179,18 @@ IsValidVideoRegion(const nsIntSize& aFrame, const nsIntRect& aPicture,
aFrame.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aFrame.width * aFrame.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aFrame.width * aFrame.height != 0 &&
aPicture.width > 0 &&
aPicture.width <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x >= 0 &&
aPicture.x < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x + aPicture.width < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.XMost() <= aFrame.width &&
aPicture.height > 0 &&
aPicture.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y >= 0 &&
aPicture.y < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y + aPicture.height < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.YMost() <= aFrame.height &&
aPicture.width * aPicture.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aPicture.width * aPicture.height != 0 &&
aDisplay.width <= PlanarYCbCrImage::MAX_DIMENSION &&
+1 -1
View File
@@ -439,7 +439,7 @@ private:
Maybe<size_t> mInitOffset;
Maybe<size_t> mMediaOffset;
bool mValid = true;
char mLastInvalidBox[5];
char mLastInvalidBox[5]{};
};
public:
@@ -13,7 +13,11 @@
#include "TheoraDecoder.h"
#ifdef MOZ_AV1
#ifdef AV1_USE_AOM
#include "AOMDecoder.h"
#else
#include "Dav1dDecoder.h"
#endif
#endif
namespace mozilla {
@@ -30,7 +34,11 @@ AgnosticDecoderModule::SupportsMimeType(const nsACString& aMimeType,
TheoraDecoder::IsTheora(aMimeType);
#ifdef MOZ_AV1
if (MediaPrefs::AV1Enabled()) {
#ifdef AV1_USE_AOM
supports |= AOMDecoder::IsAV1(aMimeType);
#else
supports |= Dav1dDecoder::IsAV1(aMimeType);
#endif
}
#endif
MOZ_LOG(sPDMLog, LogLevel::Debug, ("Agnostic decoder %s requested type",
@@ -47,10 +55,17 @@ AgnosticDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
m = new VPXDecoder(aParams);
}
#ifdef MOZ_AV1
#ifdef AV1_USE_AOM
else if (AOMDecoder::IsAV1(aParams.mConfig.mMimeType) &&
MediaPrefs::AV1Enabled()) {
m = new AOMDecoder(aParams);
}
#else
else if (Dav1dDecoder::IsAV1(aParams.mConfig.mMimeType) &&
MediaPrefs::AV1Enabled()) {
m = new Dav1dDecoder(aParams);
}
#endif
#endif
else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) {
m = new TheoraDecoder(aParams);
@@ -0,0 +1,376 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Dav1dDecoder.h"
#include "MediaResult.h"
#include "TimeUnits.h"
#include "dav1d/dav1d.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/PodOperations.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsError.h"
#include "prsystem.h"
#include <algorithm>
#include <errno.h>
#include <string.h>
#undef LOG
#define LOG(arg, ...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, ("Dav1dDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
namespace mozilla {
using namespace gfx;
using namespace layers;
Dav1dDecoder::Dav1dDecoder(const CreateDecoderParams& aParams)
: mImageContainer(aParams.mImageContainer)
, mTaskQueue(aParams.mTaskQueue)
, mCallback(aParams.mCallback)
, mIsFlushing(false)
, mDecoder(nullptr)
, mInfo(aParams.VideoConfig())
{
}
Dav1dDecoder::~Dav1dDecoder()
{
}
void
Dav1dDecoder::Shutdown()
{
if (mDecoder) {
dav1d_close(&mDecoder);
}
}
RefPtr<MediaDataDecoder::InitPromise>
Dav1dDecoder::Init()
{
int decodeThreads = 2;
if (mInfo.mDisplay.width >= 2048) {
decodeThreads = 8;
} else if (mInfo.mDisplay.width >= 1024) {
decodeThreads = 4;
}
decodeThreads = std::min(decodeThreads, PR_GetNumberOfProcessors());
Dav1dSettings settings;
dav1d_default_settings(&settings);
settings.n_threads = decodeThreads;
settings.logger.callback = nullptr;
if (dav1d_open(&mDecoder, &settings) < 0) {
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
}
return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
}
void
Dav1dDecoder::Flush()
{
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
mIsFlushing = true;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([this] () {
if (mDecoder) {
dav1d_flush(mDecoder);
}
});
SyncRunnable::DispatchToThread(mTaskQueue, r);
mIsFlushing = false;
}
static bool
GetPlaneSize(int aWidth, int aHeight, size_t* aSize)
{
CheckedInt<size_t> size = aWidth;
size *= aHeight;
if (!size.isValid()) {
return false;
}
*aSize = size.value();
return true;
}
static void
DownshiftPlane(uint8_t* aDst, int aDstStride, const uint8_t* aSrc,
ptrdiff_t aSrcStride, int aWidth, int aHeight, int aShift)
{
for (int y = 0; y < aHeight; y++) {
const uint16_t* src =
reinterpret_cast<const uint16_t*>(aSrc + y * aSrcStride);
uint8_t* dst = aDst + y * aDstStride;
for (int x = 0; x < aWidth; x++) {
dst[x] = (src[x] >> aShift) & 0xff;
}
}
}
MediaResult
Dav1dDecoder::OutputPicture(const Dav1dPicture& aPicture)
{
const int width = aPicture.p.w;
const int height = aPicture.p.h;
if (width <= 0 || height <= 0) {
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("dav1d returned invalid AV1 picture size"));
}
int chromaWidth = width;
int chromaHeight = height;
switch (aPicture.p.layout) {
case DAV1D_PIXEL_LAYOUT_I420:
chromaWidth = (width + 1) >> 1;
chromaHeight = (height + 1) >> 1;
break;
case DAV1D_PIXEL_LAYOUT_I422:
chromaWidth = (width + 1) >> 1;
chromaHeight = height;
break;
case DAV1D_PIXEL_LAYOUT_I444:
break;
default:
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("dav1d returned unsupported AV1 pixel layout: %d",
int(aPicture.p.layout)));
}
const int planeWidths[3] = { width, chromaWidth, chromaWidth };
const int planeHeights[3] = { height, chromaHeight, chromaHeight };
const ptrdiff_t srcStrides[3] = {
aPicture.stride[0],
aPicture.stride[1],
aPicture.stride[1]
};
uint8_t* planeData[3] = {
static_cast<uint8_t*>(aPicture.data[0]),
static_cast<uint8_t*>(aPicture.data[1]),
static_cast<uint8_t*>(aPicture.data[2])
};
uint32_t planeStrides[3] = { 0, 0, 0 };
UniquePtr<uint8_t[]> downshifted[3];
if (aPicture.p.bpc > 8) {
const int shift = aPicture.p.bpc - 8;
for (int plane = 0; plane < 3; plane++) {
size_t planeSize;
if (!GetPlaneSize(planeWidths[plane], planeHeights[plane], &planeSize)) {
return MediaResult(NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("AV1 downshift plane size overflow"));
}
downshifted[plane] = MakeUniqueFallible<uint8_t[]>(planeSize);
if (!downshifted[plane]) {
return MediaResult(NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("Couldn't allocate AV1 conversion buffer"));
}
DownshiftPlane(downshifted[plane].get(), planeWidths[plane],
planeData[plane], srcStrides[plane],
planeWidths[plane], planeHeights[plane], shift);
planeData[plane] = downshifted[plane].get();
planeStrides[plane] = planeWidths[plane];
}
} else {
for (int plane = 0; plane < 3; plane++) {
CheckedInt<uint32_t> stride(srcStrides[plane]);
if (srcStrides[plane] < 0 || !stride.isValid()) {
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("dav1d returned invalid AV1 stride"));
}
planeStrides[plane] = stride.value();
}
}
VideoData::YCbCrBuffer b;
for (int plane = 0; plane < 3; plane++) {
b.mPlanes[plane].mData = planeData[plane];
b.mPlanes[plane].mStride = planeStrides[plane];
b.mPlanes[plane].mHeight = planeHeights[plane];
b.mPlanes[plane].mWidth = planeWidths[plane];
b.mPlanes[plane].mOffset = 0;
b.mPlanes[plane].mSkip = 0;
}
if (aPicture.seq_hdr) {
switch (aPicture.seq_hdr->mtrx) {
case DAV1D_MC_BT601:
case DAV1D_MC_BT470BG:
b.mYUVColorSpace = YUVColorSpace::BT601;
break;
case DAV1D_MC_BT709:
b.mYUVColorSpace = YUVColorSpace::BT709;
break;
case DAV1D_MC_IDENTITY:
b.mYUVColorSpace = YUVColorSpace::IDENTITY;
break;
default:
LOG("Unhandled colorspace %d", aPicture.seq_hdr->mtrx);
break;
}
b.mColorRange = aPicture.seq_hdr->color_range ? ColorRange::FULL
: ColorRange::LIMITED;
}
const int64_t time =
aPicture.m.timestamp == INT64_MIN ? 0 : aPicture.m.timestamp;
const int64_t duration = aPicture.m.duration;
const int64_t offset = aPicture.m.offset;
const bool keyframe =
aPicture.frame_hdr &&
aPicture.frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY;
RefPtr<VideoData> v =
VideoData::CreateAndCopyData(mInfo,
mImageContainer,
offset,
time,
duration,
b,
keyframe,
time,
mInfo.ScaledImageRect(width, height));
if (!v) {
LOG("Image allocation error source %dx%d display %ux%u picture %ux%u",
width, height, mInfo.mDisplay.width, mInfo.mDisplay.height,
mInfo.mImage.width, mInfo.mImage.height);
return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
}
mCallback->Output(v);
return NS_OK;
}
MediaResult
Dav1dDecoder::DrainOutput()
{
while (true) {
Dav1dPicture picture;
PodZero(&picture);
const int res = dav1d_get_picture(mDecoder, &picture);
if (res == DAV1D_ERR(EAGAIN)) {
return NS_OK;
}
if (res < 0) {
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("dav1d error getting AV1 picture: %d",
res));
}
MediaResult rv = OutputPicture(picture);
dav1d_picture_unref(&picture);
if (NS_FAILED(rv)) {
return rv;
}
}
}
MediaResult
Dav1dDecoder::DoDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
Dav1dData data;
PodZero(&data);
uint8_t* dst = dav1d_data_create(&data, aSample->Size());
if (!dst) {
return MediaResult(NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("Couldn't allocate dav1d AV1 input buffer"));
}
memcpy(dst, aSample->Data(), aSample->Size());
data.m.timestamp = aSample->mTime;
data.m.duration = aSample->mDuration;
data.m.offset = aSample->mOffset;
data.m.size = aSample->Size();
while (data.sz) {
const int res = dav1d_send_data(mDecoder, &data);
if (res == DAV1D_ERR(EAGAIN)) {
MediaResult rv = DrainOutput();
if (NS_FAILED(rv)) {
dav1d_data_unref(&data);
return rv;
}
continue;
}
if (res < 0) {
dav1d_data_unref(&data);
return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("dav1d error decoding AV1 sample: %d",
res));
}
}
dav1d_data_unref(&data);
return DrainOutput();
}
void
Dav1dDecoder::ProcessDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mIsFlushing) {
return;
}
MediaResult rv = DoDecode(aSample);
if (NS_FAILED(rv)) {
mCallback->Error(rv);
} else {
mCallback->InputExhausted();
}
}
void
Dav1dDecoder::Input(MediaRawData* aSample)
{
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>(
this, &Dav1dDecoder::ProcessDecode, aSample));
}
void
Dav1dDecoder::ProcessDrain()
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
MediaResult rv = DrainOutput();
if (NS_FAILED(rv)) {
mCallback->Error(rv);
} else {
mCallback->DrainComplete();
}
}
void
Dav1dDecoder::Drain()
{
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
mTaskQueue->Dispatch(NewRunnableMethod(this, &Dav1dDecoder::ProcessDrain));
}
/* static */
bool
Dav1dDecoder::IsAV1(const nsACString& aMimeType)
{
return aMimeType.EqualsLiteral("video/webm; codecs=av1") ||
aMimeType.EqualsLiteral("video/av1");
}
/* static */
nsIntSize
Dav1dDecoder::GetFrameSize(Span<const uint8_t> aBuffer)
{
Dav1dSequenceHeader seqHdr;
PodZero(&seqHdr);
if (dav1d_parse_sequence_header(&seqHdr,
aBuffer.Elements(),
aBuffer.Length()) < 0) {
return nsIntSize(0, 0);
}
return nsIntSize(seqHdr.max_width, seqHdr.max_height);
}
} // namespace mozilla
#undef LOG
@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(Dav1dDecoder_h_)
#define Dav1dDecoder_h_
#include "PlatformDecoderModule.h"
#include "mozilla/Span.h"
#include <stdint.h>
typedef struct Dav1dContext Dav1dContext;
typedef struct Dav1dPicture Dav1dPicture;
namespace mozilla {
class Dav1dDecoder : public MediaDataDecoder
{
public:
explicit Dav1dDecoder(const CreateDecoderParams& aParams);
RefPtr<InitPromise> Init() override;
void Input(MediaRawData* aSample) override;
void Flush() override;
void Drain() override;
void Shutdown() override;
const char* GetDescriptionName() const override
{
return "dav1d (AV1) video decoder";
}
// Return true if aMimeType is a one of the strings used
// by our demuxers to identify AV1 streams.
static bool IsAV1(const nsACString& aMimeType);
// Return the frame dimensions from a sequence header, when one is present.
static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer);
private:
~Dav1dDecoder();
void ProcessDecode(MediaRawData* aSample);
MediaResult DoDecode(MediaRawData* aSample);
MediaResult DrainOutput();
MediaResult OutputPicture(const Dav1dPicture& aPicture);
void ProcessDrain();
const RefPtr<layers::ImageContainer> mImageContainer;
const RefPtr<TaskQueue> mTaskQueue;
MediaDataDecoderCallback* mCallback;
Atomic<bool> mIsFlushing;
Dav1dContext* mDecoder;
const VideoInfo& mInfo;
};
} // namespace mozilla
#endif // Dav1dDecoder_h_
+14 -6
View File
@@ -55,12 +55,20 @@ if CONFIG['MOZ_FFMPEG']:
]
if CONFIG['MOZ_AV1']:
EXPORTS += [
'agnostic/AOMDecoder.h',
]
UNIFIED_SOURCES += [
'agnostic/AOMDecoder.cpp',
]
if CONFIG['AV1_USE_AOM']:
EXPORTS += [
'agnostic/AOMDecoder.h',
]
UNIFIED_SOURCES += [
'agnostic/AOMDecoder.cpp',
]
else:
EXPORTS += [
'agnostic/Dav1dDecoder.h',
]
UNIFIED_SOURCES += [
'agnostic/Dav1dDecoder.cpp',
]
if CONFIG['MOZ_APPLEMEDIA']:
EXPORTS += [
+1 -1
View File
@@ -26,7 +26,7 @@ ThreadSharedFloatArrayBufferList::Create(uint32_t aChannelCount,
new ThreadSharedFloatArrayBufferList(aChannelCount);
for (uint32_t i = 0; i < aChannelCount; ++i) {
float* channelData = js_pod_malloc<float>(aLength);
float* channelData = js_pod_calloc<float>(aLength);
if (!channelData) {
return nullptr;
}
+2 -2
View File
@@ -40,8 +40,8 @@ public:
}
/**
* Create with buffers suitable for transfer to
* JS_NewArrayBufferWithContents(). The buffer contents are uninitialized
* and so should be set using GetDataForWrite().
* JS_NewArrayBufferWithContents(). The buffer contents are
* zero-initialized; callers should set them using GetDataForWrite().
*/
static already_AddRefed<ThreadSharedFloatArrayBufferList>
Create(uint32_t aChannelCount, size_t aLength, const mozilla::fallible_t&);
+1 -2
View File
@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Preferences.h"
#ifdef MOZ_AV1
#if defined(MOZ_AV1) && defined(AV1_USE_AOM)
#include "AOMDecoder.h"
#endif
#include "MediaPrefs.h"
@@ -136,4 +136,3 @@ WebMDecoder::GetMozDebugReaderData(nsAString& aString)
}
} // namespace mozilla
File diff suppressed because it is too large. Load diff
+5
View File
@@ -24,6 +24,11 @@ if CONFIG['MOZ_WEBM_ENCODER']:
'WebMWriter.cpp',
]
if CONFIG['MOZ_AV1']:
LOCAL_INCLUDES += [
'/dom/media/platforms/agnostic',
]
CXXFLAGS += CONFIG['MOZ_LIBVPX_CFLAGS']
FINAL_LIBRARY = 'xul'
@@ -293,6 +293,12 @@ SpeechSynthesis::ForceEnd()
}
}
void SpeechSynthesis::DisconnectFromOwner() {
Pause();
Cancel();
DOMEventTargetHelper::DisconnectFromOwner();
}
NS_IMETHODIMP
SpeechSynthesis::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
@@ -58,6 +58,8 @@ public:
void GetVoices(nsTArray< RefPtr<SpeechSynthesisVoice> >& aResult);
void ForceEnd();
void DisconnectFromOwner() override;
IMPL_EVENT_HANDLER(voiceschanged)
@@ -325,12 +325,12 @@ nsSynthVoiceRegistry::RemoveVoice(nsISpeechService* aService,
(XRE_IsContentProcess()) ? "child" : "parent"));
bool found = false;
VoiceData* retval = mUriVoiceMap.GetWeak(aUri, &found);
RefPtr<VoiceData> retval = mUriVoiceMap.GetWeak(aUri, &found);
if(NS_WARN_IF(!(found))) {
if(NS_WARN_IF(!found)) {
return NS_ERROR_NOT_AVAILABLE;
}
if(NS_WARN_IF(!(aService == retval->mService))) {
if(NS_WARN_IF(aService != retval->mService)) {
return NS_ERROR_INVALID_ARG;
}
+6 -4
View File
@@ -294,7 +294,7 @@ UDPSocketParent::DoConnect(nsCOMPtr<nsIUDPSocket>& aSocket,
const UDPAddressInfo& aAddressInfo)
{
UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));
if (NS_FAILED(ConnectInternal(aAddressInfo.addr(), aAddressInfo.port()))) {
if (NS_FAILED(ConnectInternal(aSocket, aAddressInfo.addr(), aAddressInfo.port()))) {
SendInternalError(aReturnThread, __LINE__);
return;
}
@@ -320,13 +320,15 @@ UDPSocketParent::DoConnect(nsCOMPtr<nsIUDPSocket>& aSocket,
}
nsresult
UDPSocketParent::ConnectInternal(const nsCString& aHost, const uint16_t& aPort)
UDPSocketParent::ConnectInternal(const nsCOMPtr<nsIUDPSocket>& aSocket,
const nsCString& aHost,
const uint16_t& aPort)
{
nsresult rv;
UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));
if (!mSocket) {
if (!aSocket) {
return NS_ERROR_NOT_AVAILABLE;
}
@@ -340,7 +342,7 @@ UDPSocketParent::ConnectInternal(const nsCString& aHost, const uint16_t& aPort)
mozilla::net::NetAddr addr;
PRNetAddrToNetAddr(&prAddr, &addr);
rv = mSocket->Connect(&addr);
rv = aSocket->Connect(&addr);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
+3 -1
View File
@@ -62,7 +62,9 @@ private:
const bool& aAddressReuse, const bool& aLoopback,
const uint32_t& recvBufferSize,
const uint32_t& sendBufferSize);
nsresult ConnectInternal(const nsCString& aHost, const uint16_t& aPort);
nsresult ConnectInternal(const nsCOMPtr<nsIUDPSocket>& aSocket,
const nsCString& aHost,
const uint16_t& aPort);
void FireInternalError(uint32_t aLineNo);
void SendInternalError(nsIEventTarget *aThread,
uint32_t aLineNo);
+14 -5
View File
@@ -1789,17 +1789,26 @@ URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
return URLWorker::IsValidURL(aGlobal, aURL, aRv);
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase) {
already_AddRefed<URL>
URL::Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
ErrorResult rv;
RefPtr<URL> parsed = URL::Constructor(aGlobal, aURL, aBase, rv);
if (rv.Failed() || !parsed) {
rv.SuppressException();
return false;
return nullptr;
}
return true;
return parsed.forget();
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
RefPtr<URL> parsed = URL::Parse(aGlobal, aURL, aBase);
return !!parsed;
}
already_AddRefed<URLSearchParams>
+4
View File
@@ -88,6 +88,10 @@ public:
IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
ErrorResult& aRv);
static already_AddRefed<URL>
Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
static bool
CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
+28
View File
@@ -448,6 +448,34 @@
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
var parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(parsed.href, "x:/static/client/runtime.js", "URL.parse resolves against a base");
is(URL.parse("/static/client/runtime.js"), null, "URL.parse returns null for invalid input");
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
var conversionOrder = [];
parsed = URL.parse(
{ toString: function() { conversionOrder.push("url"); return "child"; } },
{ toString: function() { conversionOrder.push("base"); return "https://example.com/root/"; } },
);
is(conversionOrder.join(","), "url,base", "URL.parse converts its arguments in order");
is(parsed.href, "https://example.com/root/child", "URL.parse uses converted arguments");
var sentinel = {};
var thrown;
try {
URL.parse({ toString: function() { throw sentinel; } });
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
SimpleTest.doesThrow(() => {
new URL("/static/client/runtime.js", "mailto:test@example.com");
}, "constructor rejects root-relative input against opaque mailto: base");
+58
View File
@@ -301,6 +301,64 @@ onmessage = function () {
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
let parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(
parsed.href,
"x:/static/client/runtime.js",
"URL.parse resolves against a base",
);
is(
URL.parse("/static/client/runtime.js"),
null,
"URL.parse returns null for invalid input",
);
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
const conversionOrder = [];
parsed = URL.parse(
{
toString() {
conversionOrder.push("url");
return "child";
},
},
{
toString() {
conversionOrder.push("base");
return "https://example.com/root/";
},
},
);
is(
conversionOrder.join(","),
"url,base",
"URL.parse converts its arguments in order",
);
is(
parsed.href,
"https://example.com/root/child",
"URL.parse uses converted arguments",
);
const sentinel = {};
let thrown;
try {
URL.parse({
toString() {
throw sentinel;
},
});
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
let mailtoRelativeFailed = false;
try {
new URL("/static/client/runtime.js", "mailto:test@example.com");
+1
View File
@@ -13,6 +13,7 @@ enum CSSStyleSheetParsingMode {
"agent"
};
[Constructor]
interface CSSStyleSheet : StyleSheet {
[Pure]
readonly attribute CSSRule? ownerRule;
+1 -2
View File
@@ -34,7 +34,6 @@ interface Element : Node {
[SameObject]
readonly attribute NamedNodeMap attributes;
[Pure]
sequence<DOMString> getAttributeNames();
[Pure]
DOMString? getAttribute(DOMString name);
@@ -159,7 +158,7 @@ interface Element : Node {
* this property returns an object with computed values for grid
* tracks and lines.
*/
[ChromeOnly, Pure]
[ChromeOnly]
sequence<Grid> getGridFragments();
};
+1 -1
View File
@@ -23,7 +23,7 @@ interface HTMLElement : Element {
[CEReactions, SetterThrows, Pure]
attribute DOMString dir;
[CEReactions, GetterThrows, Pure]
[CEReactions, GetterThrows]
attribute [TreatNullAs=EmptyString] DOMString innerText;
// user interaction
+1 -1
View File
@@ -51,7 +51,7 @@ interface HTMLInputElement : HTMLElement {
attribute boolean formNoValidate;
[CEReactions, Pure, SetterThrows]
attribute DOMString formTarget;
[CEReactions, Pure, SetterThrows]
[CEReactions, SetterThrows]
attribute unsigned long height;
[Pure]
attribute boolean indeterminate;
+1
View File
@@ -23,6 +23,7 @@ interface URL {
[Throws]
stringifier;
static URL? parse(USVString url, optional USVString base);
static boolean canParse(USVString url, optional USVString base);
[Throws]
-1
View File
@@ -301,7 +301,6 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */)
.setAsyncStack(GetWorkerPref<bool>(NS_LITERAL_CSTRING("asyncstack")))
.setWerror(GetWorkerPref<bool>(NS_LITERAL_CSTRING("werror")))
.setStreams(GetWorkerPref<bool>(NS_LITERAL_CSTRING("streams")))
.setWeakRefs(GetWorkerPref<bool>(NS_LITERAL_CSTRING("weakrefs")))
.setExtraWarnings(GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict")))
.setArrayProtoValues(GetWorkerPref<bool>(
NS_LITERAL_CSTRING("array_prototype_values")));
-1
View File
@@ -35,7 +35,6 @@ WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, O
WORKER_SIMPLE_PREF("dom.storageManager.enabled", StorageManagerEnabled, STORAGEMANAGER_ENABLED)
WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED)
WORKER_SIMPLE_PREF("dom.streams.enabled", StreamsEnabled, STREAMS_ENABLED)
WORKER_SIMPLE_PREF("javascript.options.weakrefs", WeakRefsEnabled, WEAKREFS_ENABLED)
WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED)
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
WORKER_SIMPLE_PREF("dom.webkitBlink.dirPicker.enabled", WebkitBlinkDirectoryPickerEnabled, DOM_WEBKITBLINK_DIRPICKER_WEBKITBLINK)
+28 -7
View File
@@ -823,16 +823,37 @@ nsBindingManager::WalkAllRules(nsIStyleRuleProcessor::EnumFunc aFunc,
}
}
// The approach in WalkAllShadowRootHostRules seems reasonable on the surface and reminds me of what is done with mScopedRoot elsewhere. But something important is missing, either here or in the code that would normally use it.
void
nsBindingManager::WalkAllShadowRootHostRules(nsIStyleRuleProcessor::EnumFunc aFunc,
ElementDependentRuleProcessorData* aData)
{
aData->mTreeMatchContext.mOnlyMatchHostPseudo = true;
WalkAllRules(aFunc, aData, true);
aData->mTreeMatchContext.mOnlyMatchHostPseudo = false;
}
{
if (!mBoundContentSet) {
return;
}
bool oldOnlyMatchHostPseudo = aData->mTreeMatchContext.mOnlyMatchHostPseudo;
nsIContent* oldScopedRoot = aData->mTreeMatchContext.mScopedRoot;
aData->mTreeMatchContext.mOnlyMatchHostPseudo = true;
for (auto iter = mBoundContentSet->Iter(); !iter.Done(); iter.Next()) {
nsIContent* boundContent = iter.Get()->GetKey();
ShadowRoot* shadowRoot = boundContent->GetShadowRoot();
if (!shadowRoot) {
continue;
}
nsXBLBinding* binding = shadowRoot->GetAssociatedBinding();
if (!binding) {
continue;
}
aData->mTreeMatchContext.mScopedRoot = boundContent;
binding->WalkRules(aFunc, aData);
}
aData->mTreeMatchContext.mScopedRoot = oldScopedRoot;
aData->mTreeMatchContext.mOnlyMatchHostPseudo = oldOnlyMatchHostPseudo;
}
nsresult
nsBindingManager::MediumFeaturesChanged(nsPresContext* aPresContext,
@@ -7,8 +7,6 @@ UNIFIED_SOURCES += [
'CharDistribution.cpp',
'JpCntx.cpp',
'nsCharSetProber.cpp',
'nsEscCharsetProber.cpp',
'nsEscSM.cpp',
'nsEUCJPProber.cpp',
'nsLatin1Prober.cpp',
'nsMBCSGroupProber.cpp',
@@ -1,46 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsEscCharsetProber.h"
#include "nsUniversalDetector.h"
nsEscCharSetProber::nsEscCharSetProber()
{
mCodingSM = new nsCodingStateMachine(&ISO2022JPSMModel);
mState = eDetecting;
mDetectedCharset = nullptr;
}
nsEscCharSetProber::~nsEscCharSetProber(void)
{
}
void nsEscCharSetProber::Reset(void)
{
mState = eDetecting;
mCodingSM->Reset();
mDetectedCharset = nullptr;
}
nsProbingState nsEscCharSetProber::HandleData(const char* aBuf, uint32_t aLen)
{
nsSMState codingState;
uint32_t i;
for ( i = 0; i < aLen && mState == eDetecting; i++)
{
codingState = mCodingSM->NextState(aBuf[i]);
if (codingState == eItsMe)
{
mState = eFoundIt;
mDetectedCharset = mCodingSM->GetCodingStateMachine();
return mState;
}
}
return mState;
}
@@ -1,32 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsEscCharSetProber_h__
#define nsEscCharSetProber_h__
#include "nsCharSetProber.h"
#include "nsCodingStateMachine.h"
#include "nsAutoPtr.h"
class nsEscCharSetProber: public nsCharSetProber {
public:
nsEscCharSetProber();
virtual ~nsEscCharSetProber(void);
nsProbingState HandleData(const char* aBuf, uint32_t aLen);
const char* GetCharSetName() {return mDetectedCharset;}
nsProbingState GetState(void) {return mState;}
void Reset(void);
float GetConfidence(void){return (float)0.99;}
protected:
void GetDistribution(uint32_t aCharLen, const char* aStr);
nsAutoPtr<nsCodingStateMachine> mCodingSM;
nsProbingState mState;
const char * mDetectedCharset;
};
#endif /* nsEscCharSetProber_h__ */
@@ -1,63 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCodingStateMachine.h"
static const uint32_t ISO2022JP_cls [ 256 / 8 ] = {
PCK4BITS(2,0,0,0,0,0,0,0), // 00 - 07
PCK4BITS(0,0,0,0,0,0,2,2), // 08 - 0f
PCK4BITS(0,0,0,0,0,0,0,0), // 10 - 17
PCK4BITS(0,0,0,1,0,0,0,0), // 18 - 1f
PCK4BITS(0,0,0,0,7,0,0,0), // 20 - 27
PCK4BITS(3,0,0,0,0,0,0,0), // 28 - 2f
PCK4BITS(0,0,0,0,0,0,0,0), // 30 - 37
PCK4BITS(0,0,0,0,0,0,0,0), // 38 - 3f
PCK4BITS(6,0,4,0,8,0,0,0), // 40 - 47
PCK4BITS(0,9,5,0,0,0,0,0), // 48 - 4f
PCK4BITS(0,0,0,0,0,0,0,0), // 50 - 57
PCK4BITS(0,0,0,0,0,0,0,0), // 58 - 5f
PCK4BITS(0,0,0,0,0,0,0,0), // 60 - 67
PCK4BITS(0,0,0,0,0,0,0,0), // 68 - 6f
PCK4BITS(0,0,0,0,0,0,0,0), // 70 - 77
PCK4BITS(0,0,0,0,0,0,0,0), // 78 - 7f
PCK4BITS(2,2,2,2,2,2,2,2), // 80 - 87
PCK4BITS(2,2,2,2,2,2,2,2), // 88 - 8f
PCK4BITS(2,2,2,2,2,2,2,2), // 90 - 97
PCK4BITS(2,2,2,2,2,2,2,2), // 98 - 9f
PCK4BITS(2,2,2,2,2,2,2,2), // a0 - a7
PCK4BITS(2,2,2,2,2,2,2,2), // a8 - af
PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7
PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf
PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7
PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf
PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7
PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df
PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7
PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef
PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7
PCK4BITS(2,2,2,2,2,2,2,2) // f8 - ff
};
static const uint32_t ISO2022JP_st [ 9] = {
PCK4BITS(eStart, 3,eError,eStart,eStart,eStart,eStart,eStart),//00-07
PCK4BITS(eStart,eStart,eError,eError,eError,eError,eError,eError),//08-0f
PCK4BITS(eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe),//10-17
PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eError),//18-1f
PCK4BITS(eError, 5,eError,eError,eError, 4,eError,eError),//20-27
PCK4BITS(eError,eError,eError, 6,eItsMe,eError,eItsMe,eError),//28-2f
PCK4BITS(eError,eError,eError,eError,eError,eError,eItsMe,eItsMe),//30-37
PCK4BITS(eError,eError,eError,eItsMe,eError,eError,eError,eError),//38-3f
PCK4BITS(eError,eError,eError,eError,eItsMe,eError,eStart,eStart) //40-47
};
static const uint32_t ISO2022JPCharLenTable[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const SMModel ISO2022JPSMModel = {
{eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_cls },
10,
{eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_st },
CHAR_LEN_TABLE(ISO2022JPCharLenTable),
"ISO-2022-JP",
};
@@ -8,7 +8,6 @@
#include "nsUniversalDetector.h"
#include "nsMBCSGroupProber.h"
#include "nsEscCharsetProber.h"
#include "nsLatin1Prober.h"
nsUniversalDetector::nsUniversalDetector()
@@ -16,7 +15,6 @@ nsUniversalDetector::nsUniversalDetector()
mDone = false;
mBestGuess = -1; //illegal value as signal
mInTag = false;
mEscCharSetProber = nullptr;
mStart = true;
mDetectedCharset = nullptr;
@@ -33,8 +31,6 @@ nsUniversalDetector::~nsUniversalDetector()
{
for (int32_t i = 0; i < NUM_OF_CHARSET_PROBERS; i++)
delete mCharSetProbers[i];
delete mEscCharSetProber;
}
void
@@ -50,9 +46,6 @@ nsUniversalDetector::Reset()
mInputState = ePureAscii;
mLastChar = '\0';
if (mEscCharSetProber)
mEscCharSetProber->Reset();
uint32_t i;
for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++)
if (mCharSetProbers[i])
@@ -117,12 +110,6 @@ nsresult nsUniversalDetector::HandleData(const char* aBuf, uint32_t aLen)
//adjust state
mInputState = eHighbyte;
//kill mEscCharSetProber if it is active
if (mEscCharSetProber) {
delete mEscCharSetProber;
mEscCharSetProber = nullptr;
}
//start multibyte and singlebyte charset prober
if (nullptr == mCharSetProbers[0])
{
@@ -140,12 +127,6 @@ nsresult nsUniversalDetector::HandleData(const char* aBuf, uint32_t aLen)
}
else
{
//ok, just pure ascii so far
if ((ePureAscii == mInputState) && (aBuf[i] == '\033'))
{
//found escape character
mInputState = eEscAscii;
}
mLastChar = aBuf[i];
}
}
@@ -153,19 +134,6 @@ nsresult nsUniversalDetector::HandleData(const char* aBuf, uint32_t aLen)
nsProbingState st;
switch (mInputState)
{
case eEscAscii:
if (nullptr == mEscCharSetProber) {
mEscCharSetProber = new nsEscCharSetProber();
if (nullptr == mEscCharSetProber)
return NS_ERROR_OUT_OF_MEMORY;
}
st = mEscCharSetProber->HandleData(aBuf, aLen);
if (st == eFoundIt)
{
mDone = true;
mDetectedCharset = mEscCharSetProber->GetCharSetName();
}
break;
case eHighbyte:
for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++)
{
@@ -231,8 +199,6 @@ void nsUniversalDetector::DataEnd()
Report(mCharSetProbers[maxProber]->GetCharSetName());
}
break;
case eEscAscii:
break;
default:
;
}
@@ -12,8 +12,7 @@ class nsCharSetProber;
typedef enum {
ePureAscii = 0,
eEscAscii = 1,
eHighbyte = 2
eHighbyte = 1
} nsInputState;
class nsUniversalDetector {
@@ -37,7 +36,6 @@ protected:
uint32_t mLanguageFilter;
nsCharSetProber *mCharSetProbers[NUM_OF_CHARSET_PROBERS];
nsCharSetProber *mEscCharSetProber;
};
#endif
+120 -105
View File
@@ -805,6 +805,10 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
}
operand = decode_integer (operand, &size);
decode_integer (operand, &offset);
if (unlikely (offset < 0 || (unsigned long)offset > font->data_length)) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto fail;
}
status = cff_dict_init (&font->fd_private_dict[i]);
if (unlikely (status))
goto fail;
@@ -866,6 +870,8 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
decode_integer (operand, &offset);
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cff_index_read (&font->charstrings_index, &p, font->data_end);
if (unlikely (status))
goto fail;
@@ -874,49 +880,58 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
if (font->is_cid) {
operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
decode_integer (operand, &offset);
status = cairo_cff_font_read_fdselect (font, font->data + offset);
if (unlikely (status))
goto fail;
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cairo_cff_font_read_fdselect (font, p);
if (unlikely (status))
goto fail;
operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
decode_integer (operand, &offset);
status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
if (unlikely (status))
goto fail;
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cairo_cff_font_read_cid_fontdict (font, p);
if (unlikely (status))
goto fail;
} else {
operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
operand = decode_integer (operand, &size);
decode_integer (operand, &offset);
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cairo_cff_font_read_private_dict (font,
font->private_dict,
&font->local_sub_index,
font->data + offset,
size);
if (unlikely (status))
goto fail;
&font->local_sub_index,
p,
size);
if (unlikely (status))
goto fail;
}
/* Use maximum sized encoding to reserve space for later modification. */
end_buf = encode_integer_max (buf, 0);
status = cff_dict_set_operands (font->top_dict,
CHARSTRINGS_OP, buf, end_buf - buf);
CHARSTRINGS_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
status = cff_dict_set_operands (font->top_dict,
FDSELECT_OP, buf, end_buf - buf);
FDSELECT_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
status = cff_dict_set_operands (font->top_dict,
FDARRAY_OP, buf, end_buf - buf);
FDARRAY_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
status = cff_dict_set_operands (font->top_dict,
CHARSET_OP, buf, end_buf - buf);
CHARSET_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
cff_dict_remove (font->top_dict, ENCODING_OP);
cff_dict_remove (font->top_dict, PRIVATE_OP);
@@ -985,26 +1000,26 @@ cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
(unsigned char *)registry,
strlen(registry));
if (unlikely (status))
return status;
return status;
sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
status = cff_index_append_copy (&font->strings_subset_index,
(unsigned char *)ordering,
strlen(ordering));
strlen(ordering));
if (unlikely (status))
return status;
return status;
p = encode_integer (buf, sid1);
p = encode_integer (p, sid2);
p = encode_integer (p, 0);
status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
if (unlikely (status))
return status;
return status;
p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
if (unlikely (status))
return status;
return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1038,7 +1053,7 @@ cairo_cff_font_subset_dict_string(cairo_cff_font_t *font,
p = encode_integer (buf, sid);
status = cff_dict_set_operands (dict, operator, buf, p - buf);
if (unlikely (status))
return status;
return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1101,19 +1116,19 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
sizeof (int));
if (unlikely (font->fdselect_subset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
if (unlikely (font->fd_subset_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
if (unlikely (font->private_dict_offset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
reverse_map = calloc (font->num_fontdicts, sizeof (int));
if (unlikely (reverse_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
for (i = 0; i < font->num_fontdicts; i++)
reverse_map[i] = -1;
@@ -1143,22 +1158,22 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
font->num_fontdicts = 1;
font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
if (unlikely (font->fd_dict == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (cff_dict_init (&font->fd_dict[0])) {
free (font->fd_dict);
font->fd_dict = NULL;
font->num_fontdicts = 0;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
free (font->fd_dict);
font->fd_dict = NULL;
font->num_fontdicts = 0;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
font->fd_subset_map = malloc (sizeof (int));
if (unlikely (font->fd_subset_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->private_dict_offset = malloc (sizeof (int));
if (unlikely (font->private_dict_offset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->fd_subset_map[0] = 0;
font->num_subset_fontdicts = 1;
@@ -1169,7 +1184,7 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
end_buf = encode_integer_max (end_buf, 0);
status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1208,7 +1223,7 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
status = cairo_cff_font_set_ros_strings (font);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_subset_charstrings (font);
if (unlikely (status))
@@ -1219,7 +1234,7 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
else
status = cairo_cff_font_create_cid_fontdict (font);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_subset_strings (font);
if (unlikely (status))
@@ -1271,7 +1286,7 @@ cairo_cff_font_write_name (cairo_cff_font_t *font)
(unsigned char *) font->subset_font_name,
strlen(font->subset_font_name));
if (unlikely (status))
goto FAIL;
goto FAIL;
status = cff_index_write (&index, &font->output);
if (unlikely (status))
@@ -1464,9 +1479,9 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
if (unlikely (status))
return status;
offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array);
offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array);
*offset_array_ptr = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
offset_array += sizeof(uint32_t);
offset_array += sizeof(uint32_t);
}
return CAIRO_STATUS_SUCCESS;
@@ -1566,15 +1581,15 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
0,
font->fd_dict[0],
font->private_dict);
if (unlikely (status))
return status;
if (unlikely (status))
return status;
status = cairo_cff_font_write_local_sub (font,
0,
font->private_dict,
&font->local_sub_index);
if (unlikely (status))
return status;
if (unlikely (status))
return status;
}
return CAIRO_STATUS_SUCCESS;
@@ -1698,7 +1713,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
backend = scaled_font_subset->scaled_font->backend;
if (!backend->load_truetype_table)
return CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_INT_STATUS_UNSUPPORTED;
data_length = 0;
status = backend->load_truetype_table( scaled_font_subset->scaled_font,
@@ -1736,12 +1751,12 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
_cairo_array_init (&font->output, sizeof (char));
status = _cairo_array_grow_by (&font->output, 4096);
if (unlikely (status))
goto fail2;
goto fail2;
font->subset_font_name = strdup (subset_name);
if (unlikely (font->subset_font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
goto fail2;
}
font->x_min = (int16_t) be16_to_cpu (head.x_min);
font->y_min = (int16_t) be16_to_cpu (head.y_min);
@@ -1755,18 +1770,18 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->font_name = NULL;
status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
&font->ps_name,
&font->font_name);
&font->ps_name,
&font->font_name);
if (_cairo_status_is_error (status))
goto fail3;
goto fail3;
/* If the PS name is not found, create a CairoFont-x-y name. */
if (font->ps_name == NULL) {
font->ps_name = malloc (30);
if (unlikely (font->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
}
snprintf(font->ps_name, 30, "CairoFont-%u-%u",
scaled_font_subset->font_id,
@@ -1781,7 +1796,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
status = cairo_cff_font_create_set_widths (font);
if (unlikely (status))
goto fail5;
goto fail5;
font->data_length = data_length;
font->data = malloc (data_length);
@@ -1799,11 +1814,11 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
status = cff_dict_init (&font->top_dict);
if (unlikely (status))
goto fail6;
goto fail6;
status = cff_dict_init (&font->private_dict);
if (unlikely (status))
goto fail7;
goto fail7;
cff_index_init (&font->strings_index);
cff_index_init (&font->charstrings_index);
@@ -1831,7 +1846,7 @@ fail5:
free (font->widths);
fail4:
if (font->font_name)
free (font->font_name);
free (font->font_name);
fail3:
free (font->subset_font_name);
fail2:
@@ -1848,7 +1863,7 @@ cairo_cff_font_destroy (cairo_cff_font_t *font)
free (font->widths);
if (font->font_name)
free (font->font_name);
free (font->font_name);
free (font->ps_name);
free (font->subset_font_name);
_cairo_array_fini (&font->output);
@@ -1902,7 +1917,7 @@ cairo_cff_font_destroy (cairo_cff_font_t *font)
cairo_status_t
_cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
const char *subset_name,
const char *subset_name,
cairo_scaled_font_subset_t *font_subset)
{
cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
@@ -1913,32 +1928,32 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
status = _cairo_cff_font_create (font_subset, &font, subset_name);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_generate (font, &data, &length);
if (unlikely (status))
goto fail1;
goto fail1;
cff_subset->ps_name = strdup (font->ps_name);
if (unlikely (cff_subset->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
if (font->font_name) {
cff_subset->font_name = strdup (font->font_name);
if (cff_subset->font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
cff_subset->font_name = strdup (font->font_name);
if (cff_subset->font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
} else {
cff_subset->font_name = NULL;
cff_subset->font_name = NULL;
}
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
@@ -1952,8 +1967,8 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
cff_subset->data = malloc (length);
if (unlikely (cff_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
memcpy (cff_subset->data, data, length);
@@ -1967,7 +1982,7 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
free (cff_subset->widths);
fail3:
if (cff_subset->font_name)
free (cff_subset->font_name);
free (cff_subset->font_name);
fail2:
free (cff_subset->ps_name);
fail1:
@@ -1981,7 +1996,7 @@ _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
{
free (subset->ps_name);
if (subset->font_name)
free (subset->font_name);
free (subset->font_name);
free (subset->widths);
free (subset->data);
}
@@ -1996,7 +2011,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
font = calloc (1, sizeof (cairo_cff_font_t));
if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->backend = NULL;
font->scaled_font_subset = scaled_font_subset;
@@ -2004,18 +2019,18 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
_cairo_array_init (&font->output, sizeof (char));
status = _cairo_array_grow_by (&font->output, 4096);
if (unlikely (status))
goto fail1;
goto fail1;
font->subset_font_name = strdup (subset_name);
if (unlikely (font->subset_font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
goto fail1;
}
font->ps_name = strdup (subset_name);
if (unlikely (font->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
goto fail2;
}
font->font_name = NULL;
@@ -2038,11 +2053,11 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
status = cff_dict_init (&font->top_dict);
if (unlikely (status))
goto fail4;
goto fail4;
status = cff_dict_init (&font->private_dict);
if (unlikely (status))
goto fail5;
goto fail5;
cff_index_init (&font->strings_index);
cff_index_init (&font->charstrings_index);
@@ -2068,7 +2083,7 @@ fail4:
free (font->widths);
fail3:
if (font->font_name)
free (font->font_name);
free (font->font_name);
free (font->ps_name);
fail2:
free (font->subset_font_name);
@@ -2105,39 +2120,39 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
end_buf = encode_integer (end_buf, type2_subset->x_max);
end_buf = encode_integer (end_buf, type2_subset->y_max);
status = cff_dict_set_operands (font->top_dict,
FONTBBOX_OP, buf, end_buf - buf);
FONTBBOX_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
end_buf = encode_integer_max (buf, 0);
status = cff_dict_set_operands (font->top_dict,
CHARSTRINGS_OP, buf, end_buf - buf);
CHARSTRINGS_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cff_dict_set_operands (font->top_dict,
FDSELECT_OP, buf, end_buf - buf);
FDSELECT_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cff_dict_set_operands (font->top_dict,
FDARRAY_OP, buf, end_buf - buf);
FDARRAY_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cff_dict_set_operands (font->top_dict,
CHARSET_OP, buf, end_buf - buf);
CHARSET_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_set_ros_strings (font);
if (unlikely (status))
return status;
return status;
/* Create CID FD dictionary */
status = cairo_cff_font_create_cid_fontdict (font);
if (unlikely (status))
return status;
return status;
/* Create charstrings */
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
@@ -2163,7 +2178,7 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
cairo_status_t
_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
const char *subset_name,
const char *subset_name,
cairo_scaled_font_subset_t *font_subset)
{
cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
@@ -2175,27 +2190,27 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
if (unlikely (status))
return status;
return status;
status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
if (unlikely (status))
goto fail1;
goto fail1;
status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
if (unlikely (status))
goto fail2;
goto fail2;
cff_subset->font_name = NULL;
cff_subset->ps_name = strdup (font->ps_name);
if (unlikely (cff_subset->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
@@ -2210,8 +2225,8 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
cff_subset->data = malloc (length);
if (unlikely (cff_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
memcpy (cff_subset->data, data, length);
-4
View File
@@ -5,8 +5,6 @@
#ifndef CAIRO_DEPRECATED_H
#define CAIRO_DEPRECATED_H
#define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ
/* Obsolete functions. These definitions exist to coerce the compiler
* into providing a little bit of guidance with its error
* messages. The idea is to help users port their old code without
@@ -59,8 +57,6 @@
#define cairo_ps_surface_set_dpi cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_pdf_surface_set_dpi cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_svg_surface_set_dpi cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_atsui_font_face_create_for_atsu_font_id cairo_atsui_font_face_create_for_atsu_font_id_REPLACED_BY_cairo_quartz_font_face_create_for_atsu_font_id
#define cairo_current_path cairo_current_path_DEPRECATED_BY_cairo_copy_path
#define cairo_current_path_flat cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat
#define cairo_get_path cairo_get_path_DEPRECATED_BY_cairo_copy_path
-42
View File
@@ -767,45 +767,3 @@ _cairo_quartz_scaled_font_get_ct_font_ref (cairo_scaled_font_t *abstract_font)
return ffont->ctFont;
}
#if !defined(__LP64__) && !TARGET_OS_IPHONE
/*
* compat with old ATSUI backend
*/
/**
* cairo_quartz_font_face_create_for_atsu_font_id
* @font_id: an ATSUFontID for the font.
*
* Creates a new font for the Quartz font backend based on an
* #ATSUFontID. This font can then be used with
* cairo_set_font_face() or cairo_scaled_font_create().
*
* Return value: a newly created #cairo_font_face_t. Free with
* cairo_font_face_destroy() when you are done using it.
*
* Since: 1.6
**/
cairo_font_face_t *
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id)
{
ATSFontRef atsFont = FMGetATSFontRefFromFont (font_id);
CGFontRef cgFont = CGFontCreateWithPlatformFont (&atsFont);
cairo_font_face_t *ff;
ff = cairo_quartz_font_face_create_for_cgfont (cgFont);
CGFontRelease (cgFont);
return ff;
}
/* This is the old name for the above function, exported for compat purposes */
cairo_font_face_t *cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
cairo_font_face_t *
cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
{
return cairo_quartz_font_face_create_for_atsu_font_id (font_id);
}
#endif
-5
View File
@@ -63,11 +63,6 @@ cairo_quartz_surface_get_image (cairo_surface_t *surface);
cairo_public cairo_font_face_t *
cairo_quartz_font_face_create_for_cgfont (CGFontRef font);
#if !defined(__LP64__) && !TARGET_OS_IPHONE
cairo_public cairo_font_face_t *
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id);
#endif
#endif /* CAIRO_HAS_QUARTZ_FONT */
CAIRO_END_DECLS
-2
View File
@@ -213,8 +213,6 @@
#define cairo_qpainter_surface_create_with_qpixmap _moz_cairo_qpainter_surface_create_with_qpixmap
#define cairo_qpainter_surface_get_image _moz_cairo_qpainter_surface_get_image
#define cairo_qpainter_surface_get_qimage _moz_cairo_qpainter_surface_get_qimage
#define cairo_qpainter_surface_get_qpainter _moz_cairo_qpainter_surface_get_qpainter
#define cairo_quartz_font_face_create_for_atsu_font_id _moz_cairo_quartz_font_face_create_for_atsu_font_id
#define cairo_quartz_font_face_create_for_cgfont _moz_cairo_quartz_font_face_create_for_cgfont
#define cairo_quartz_image_surface_create _moz_cairo_quartz_image_surface_create
#define cairo_quartz_image_surface_get_image _moz_cairo_quartz_image_surface_get_image
+5 -1
View File
@@ -50,6 +50,10 @@
#include "gfxWindowsPlatform.h"
#endif
#ifdef XP_MACOSX
#include <AvailabilityMacros.h>
#endif
#include "harfbuzz/hb.h"
#include "harfbuzz/hb-ot.h"
#include "graphite2/Font.h"
@@ -884,7 +888,7 @@ gfxFont::GetGlyphHAdvance(DrawTarget* aDrawTarget, uint16_t aGID)
if (!SetupCairoFont(aDrawTarget)) {
return 0;
}
#if !defined(XP_MACOSX) || (defined(XP_MACOSX) && !(defined(__ppc__) || defined(__ppc64__)))
#if !defined(XP_MACOSX) || (defined(XP_MACOSX) && (defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6))
if (ProvidesGlyphWidths()) {
return GetGlyphWidth(*aDrawTarget, aGID) / 65536.0;
}
+14 -1
View File
@@ -336,7 +336,20 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
// not a one-to-one mapping with simple metrics: use DetailedGlyph
AutoTArray<gfxShapedText::DetailedGlyph,8> details;
float clusterLoc;
for (uint32_t j = c.baseGlyph; j < c.baseGlyph + c.nGlyphs; ++j) {
uint32_t glyph_start = c.baseGlyph;
uint32_t glyph_end = glyph_start + c.nGlyphs;
if (glyph_end < glyph_start) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (glyph_end - glyph_start > 0xFFFF) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (!details.SetCapacity(glyph_end - glyph_start, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t j = glyph_start; j < glyph_end; ++j) {
gfxShapedText::DetailedGlyph* d = details.AppendElement();
d->mGlyphID = gids[j];
d->mYOffset = roundY ? NSToIntRound(-yLocs[j]) * dev2appUnits :
+5 -1
View File
@@ -19,6 +19,10 @@
#include "unicode/unorm.h"
#include "unicode/utext.h"
#ifdef XP_MACOSX
#include <AvailabilityMacros.h>
#endif
static const UNormalizer2 * sNormalizer = nullptr;
#include <algorithm>
@@ -327,7 +331,7 @@ gfxHarfBuzzShaper::GetGlyphHAdvance(hb_codepoint_t glyph) const
glyph = mNumLongHMetrics - 1;
}
#if defined(XP_MACOSX) && (defined(__ppc__) || defined(__ppc64__))
#if defined(XP_MACOSX) && !(defined(MAC_OS_X_VERSION_10_6) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6))
if (MOZ_UNLIKELY(mFont->mSpacingKludge && glyph == mFont->GetSpaceGlyph())) {
// This is one of the fonts where the spacing went awry,
// invariably on an nbsp character that escaped into the run.
+6 -15
View File
@@ -23,6 +23,8 @@
#include "cairo-quartz.h"
#include "nsCocoaFeatures.h"
using namespace mozilla;
using namespace mozilla::gfx;
@@ -474,25 +476,11 @@ gfxMacFont::InitMetrics()
// If we are dealing with a weird font (Apple is notorious), we could have
// the situation where we wind up with space == maxAdvance due to a 10.4 bug.
// In that case, kludge a reasonable upper limit (TenFourFox issue 355).
//fprintf(stderr, "glyph: %i sB=%s width=%f avg=%f max=%f cgf=%f mAS=%f\n", glyphID, (IsSyntheticBold() ? "Y" : "n"), mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.maxAdvance, cgConvFactor, mAdjustedSize);
if (MOZ_UNLIKELY(!hasX && mMetrics.spaceWidth >= mMetrics.maxAdvance)) {
mMetrics.spaceWidth = std::min((float)mMetrics.emDescent * 1.4f,
(float)mMetrics.maxAdvance * 0.4f);
mSpacingKludge = true;
}
//fprintf(stderr, "glyph: %i sB=%s ......%f avg=%f max=%f cgf=%f mAS=%f\n", glyphID, (IsSyntheticBold() ? "Y" : "n"), mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.maxAdvance, cgConvFactor, mAdjustedSize);
#if 0
fprintf (stderr, "Font: %p (%s) size: %f\n", this,
NS_ConvertUTF16toUTF8(GetName()).get(), mStyle.size);
// fprintf (stderr, " fbounds.origin.x %f y %f size.width %f height %f\n", fbounds.origin.x, fbounds.origin.y, fbounds.size.width, fbounds.size.height);
fprintf (stderr, " emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
fprintf (stderr, " maxAscent: %f maxDescent: %f maxAdvance: %f\n", mMetrics.maxAscent, mMetrics.maxDescent, mMetrics.maxAdvance);
fprintf (stderr, " internalLeading: %f externalLeading: %f\n", mMetrics.internalLeading, mMetrics.externalLeading);
fprintf (stderr, " spaceWidth: %f aveCharWidth: %f xHeight: %f capHeight: %f\n", mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.xHeight, mMetrics.capHeight);
fprintf (stderr, " uOff: %f uSize: %f stOff: %f stSize: %f\n", mMetrics.underlineOffset, mMetrics.underlineSize, mMetrics.strikeoutOffset, mMetrics.strikeoutSize);
#endif
}
gfxFloat
@@ -527,7 +515,10 @@ gfxMacFont::CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont,
CGFloat aSize,
CTFontDescriptorRef aFontDesc)
{
CFDictionaryRef variations = ::CGFontCopyVariations(aCGFont);
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
// versions (see bug 1331683)
CFDictionaryRef variations = nsCocoaFeatures::OnSierraOrLater() ?
::CGFontCopyVariations(aCGFont) : 0;
CTFontRef ctFont;
if (variations) {
CFDictionaryRef varAttr =
+4 -1
View File
@@ -42,7 +42,10 @@ public:
// with embedded color bitmaps (Apple Color Emoji), as Core Text renders
// the glyphs with non-linear scaling at small pixel sizes.
virtual bool ProvidesGlyphWidths() const override {
return mVariationFont ||
return
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
mVariationFont ||
#endif
mFontEntry->HasFontTable(TRUETYPE_TAG('s','b','i','x'));
}
+27 -47
View File
@@ -147,7 +147,6 @@ gfxTextRun::gfxTextRun(const gfxTextRunFactory::Parameters *aParams,
: gfxShapedText(aLength, aFlags, aParams->mAppUnitsPerDevUnit)
, mUserData(aParams->mUserData)
, mFontGroup(aFontGroup)
, mReleasedFontGroup(false)
, mShapingState(eShapingState_Normal)
{
NS_ASSERTION(mAppUnitsPerDevUnit > 0, "Invalid app unit scale");
@@ -184,30 +183,18 @@ gfxTextRun::~gfxTextRun()
mFlags = 0xFFFFFFFF;
#endif
// The cached ellipsis textrun (if any) in a fontgroup will have already
// been told to release its reference to the group, so we mustn't do that
// again here.
if (!mReleasedFontGroup) {
#ifdef DEBUG
gfxTextPerfMetrics *tp = mFontGroup->GetTextPerfMetrics();
if (tp) {
tp->current.textrunDestr++;
}
#endif
NS_RELEASE(mFontGroup);
gfxTextPerfMetrics* tp = mFontGroup->GetTextPerfMetrics();
if (tp) {
tp->current.textrunDestr++;
}
#endif
NS_RELEASE(mFontGroup);
MOZ_COUNT_DTOR(gfxTextRun);
}
void
gfxTextRun::ReleaseFontGroup()
{
NS_ASSERTION(!mReleasedFontGroup, "doubly released!");
NS_RELEASE(mFontGroup);
mReleasedFontGroup = true;
}
bool
gfxTextRun::SetPotentialLineBreaks(Range aRange, const uint8_t* aBreakBefore)
{
@@ -244,11 +231,13 @@ gfxTextRun::ComputeLigatureData(Range aPartRange,
LigatureData result;
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
uint32_t i;
for (i = aPartRange.start; !charGlyphs[i].IsLigatureGroupStart(); --i) {
NS_ASSERTION(i > 0, "Ligature at the start of the run??");
uint32_t i = aPartRange.start;
while (i && !charGlyphs[i].IsLigatureGroupStart()) {
--i;
}
NS_ASSERTION(charGlyphs[i].IsLigatureGroupStart(), "Ligature at run start?");
result.mRange.start = i;
for (i = aPartRange.start + 1;
i < GetLength() && !charGlyphs[i].IsLigatureGroupStart(); ++i) {
}
@@ -1717,21 +1706,27 @@ gfxFontGroup::GetFontAt(int32_t i, uint32_t aCh)
RefPtr<gfxFont> font = ff.Font();
if (!font) {
gfxFontEntry* fe = mFonts[i].FontEntry();
gfxCharacterMap* unicodeRangeMap = nullptr;
RefPtr<gfxFontEntry> fe = ff.FontEntry();
if (!fe) {
return nullptr;
}
RefPtr<gfxCharacterMap> unicodeRangeMap;
if (fe->mIsUserFontContainer) {
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe);
// This raw pointer is OK because fe holds a strong ref to the object.
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe.get());
if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED &&
ufe->CharacterInUnicodeRange(aCh) &&
!FontLoadingForFamily(ff.Family(), aCh)) {
ufe->Load();
ff.CheckState(mSkipDrawing);
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
// Update fe to refer to the actual platform font entry, rather than the
// webfont wrapper. After this, we no longer have a strong ref to ufe.
fe = ufe->GetPlatformFontEntry();
if (!fe) {
return nullptr;
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
}
font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold(),
unicodeRangeMap);
@@ -2541,17 +2536,11 @@ gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget,
}
}
gfxTextRun *
gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags,
LazyReferenceDrawTargetGetter& aRefDrawTargetGetter)
{
already_AddRefed<gfxTextRun>
gfxFontGroup::MakeEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags,
DrawTarget* aRefDrawTarget) {
MOZ_ASSERT(!(aFlags & ~TEXT_ORIENT_MASK),
"flags here should only be used to specify orientation");
if (mCachedEllipsisTextRun &&
(mCachedEllipsisTextRun->GetFlags() & TEXT_ORIENT_MASK) == aFlags &&
mCachedEllipsisTextRun->GetAppUnitsPerDevUnit() == aAppUnitsPerDevPixel) {
return mCachedEllipsisTextRun.get();
}
// Use a Unicode ellipsis if the font supports it,
// otherwise use three ASCII periods as fallback.
@@ -2562,20 +2551,11 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags,
: nsDependentString(kASCIIPeriodsChar,
ArrayLength(kASCIIPeriodsChar) - 1);
RefPtr<DrawTarget> refDT = aRefDrawTargetGetter.GetRefDrawTarget();
Parameters params = {
refDT, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel
aRefDrawTarget, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel
};
mCachedEllipsisTextRun =
MakeTextRun(ellipsis.get(), ellipsis.Length(), &params,
aFlags | TEXT_IS_PERSISTENT, nullptr);
if (!mCachedEllipsisTextRun) {
return nullptr;
}
// don't let the presence of a cached ellipsis textrun prolong the
// fontgroup's life
mCachedEllipsisTextRun->ReleaseFontGroup();
return mCachedEllipsisTextRun.get();
return MakeTextRun(ellipsis.get(), ellipsis.Length(), &params,
aFlags | TEXT_IS_PERSISTENT, nullptr);
}
already_AddRefed<gfxFont>
+5 -18
View File
@@ -755,8 +755,6 @@ private:
bool mSkipDrawing; // true if the font group we used had a user font
// download that's in progress, so we should hide text
// until the download completes (or timeout fires)
bool mReleasedFontGroup; // we already called NS_RELEASE on
// mFontGroup, so don't do it again
// shaping state for handling variant fallback features
// such as subscript/superscript variant glyphs
@@ -897,7 +895,6 @@ public:
mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET;
mSkipDrawing = false;
mHyphenWidth = -1;
mCachedEllipsisTextRun = nullptr;
}
// If there is a user font set, check to see whether the font list or any
@@ -911,17 +908,11 @@ public:
return mSkipDrawing;
}
class LazyReferenceDrawTargetGetter {
public:
virtual already_AddRefed<DrawTarget> GetRefDrawTarget() = 0;
};
// The gfxFontGroup keeps ownership of this textrun.
// It is only guaranteed to exist until the next call to GetEllipsisTextRun
// (which might use a different appUnitsPerDev value or flags) for the font
// group, or until UpdateUserFonts is called, or the fontgroup is destroyed.
// Get it/use it/forget it :) - don't keep a reference that might go stale.
gfxTextRun* GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags,
LazyReferenceDrawTargetGetter& aRefDrawTargetGetter);
// Make a textrun for the ellipsis character (with fallback to "..." if
// ellipsis is not supported by the font).
already_AddRefed<gfxTextRun> MakeEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
uint32_t aFlags,
DrawTarget* aRefDrawTarget);
protected:
// search through pref fonts for a character, return nullptr if no matching pref font
@@ -1093,10 +1084,6 @@ protected:
gfxTextPerfMetrics *mTextPerf;
// Cache a textrun representing an ellipsis (useful for CSS text-overflow)
// at a specific appUnitsPerDevPixel size and orientation
RefPtr<gfxTextRun> mCachedEllipsisTextRun;
// cache the most recent pref font to avoid general pref font lookup
RefPtr<gfxFontFamily> mLastPrefFamily;
RefPtr<gfxFont> mLastPrefFont;
+7 -4
View File
@@ -1637,10 +1637,13 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) &&
mHasBeenDecoded && mAnimationState) {
// We've finished a full decode of all animation frames and our AnimationState
// has been notified about them all, so let it know not to expect anymore.
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
// If we've successfully finished a full decode of all animation frames
// then let our animation state know it's complete and to not to expect
// any more frames.
if (aStatus.mFinished && !aStatus.mHadError) {
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
}
}
// Only act on errors if we have no usable frames from the decoder.
+1 -1
View File
@@ -446,7 +446,7 @@ for (k = 0; k < 2; k++) {
while ((c = fgetc(f)) != '\n' && c != EOF);
/* issue warning if not a comment */
if (buf[0] != '%') {
fprintf(stderr, "Warning: skipping too long pattern (more than %lu chars)\n", sizeof(buf));
fprintf(stderr, "Warning: skipping too long pattern (more than %zu chars)\n", sizeof(buf));
}
continue;
}
+459 -40
View File
@@ -47,10 +47,12 @@
#include "builtin/AtomicsObject.h"
#include "mozilla/Atomics.h"
#include "mozilla/Casting.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/Maybe.h"
#include "mozilla/Unused.h"
#include "builtin/Promise.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "jsnum.h"
@@ -58,7 +60,9 @@
#include "jit/AtomicOperations.h"
#include "jit/InlinableNatives.h"
#include "js/Class.h"
#include "vm/BigIntType.h"
#include "vm/GlobalObject.h"
#include "vm/HelperThreads.h"
#include "vm/Time.h"
#include "vm/TypedArrayObject.h"
#include "wasm/WasmInstance.h"
@@ -121,6 +125,68 @@ GetTypedArrayIndex(JSContext* cx, HandleValue v, Handle<TypedArrayObject*> view,
return true;
}
static bool
IsWaitableTypedArray(Scalar::Type viewType)
{
return viewType == Scalar::Int32 || viewType == Scalar::BigInt64;
}
static uint32_t
GetWaiterByteOffset(Handle<TypedArrayObject*> view, uint32_t offset)
{
return view->byteOffset() + offset * TypedArrayElemSize(view->type());
}
static uint64_t
BigIntToRawBits(Scalar::Type viewType, BigInt* value)
{
if (viewType == Scalar::BigInt64)
return uint64_t(BigInt::toInt64(value));
MOZ_ASSERT(viewType == Scalar::BigUint64);
return BigInt::toUint64(value);
}
static bool
BigIntToRawBits(JSContext* cx, Scalar::Type viewType, HandleValue value, uint64_t* bits)
{
MOZ_ASSERT(Scalar::isBigIntType(viewType));
RootedBigInt bigint(cx, ToBigInt(cx, value));
if (!bigint)
return false;
*bits = BigIntToRawBits(viewType, bigint);
return true;
}
static bool
SetBigIntResult(JSContext* cx, Scalar::Type viewType, uint64_t bits, MutableHandleValue result)
{
MOZ_ASSERT(Scalar::isBigIntType(viewType));
BigInt* bigint = viewType == Scalar::BigInt64
? BigInt::createFromInt64(cx, mozilla::BitwiseCast<int64_t>(bits))
: BigInt::createFromUint64(cx, bits);
if (!bigint)
return false;
result.setBigInt(bigint);
return true;
}
static bool
WaitValueMatches(Handle<TypedArrayObject*> view, uint32_t offset, uint64_t expected)
{
SharedMem<void*> viewData = view->viewDataShared();
if (view->type() == Scalar::BigInt64) {
return jit::AtomicOperations::loadSafeWhenRacy(viewData.cast<uint64_t*>() + offset) ==
expected;
}
return uint32_t(jit::AtomicOperations::loadSafeWhenRacy(viewData.cast<int32_t*>() + offset)) ==
uint32_t(expected);
}
static int32_t
CompareExchange(Scalar::Type viewType, int32_t oldCandidate, int32_t newCandidate,
SharedMem<void*> viewData, uint32_t offset, bool* badArrayType = nullptr)
@@ -191,6 +257,20 @@ js::atomics_compareExchange(JSContext* cx, unsigned argc, Value* vp)
uint32_t offset;
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
return false;
if (Scalar::isBigIntType(view->type())) {
uint64_t oldCandidate;
if (!BigIntToRawBits(cx, view->type(), oldv, &oldCandidate))
return false;
uint64_t newCandidate;
if (!BigIntToRawBits(cx, view->type(), newv, &newCandidate))
return false;
uint64_t result = jit::AtomicOperations::compareExchangeSeqCst(
view->viewDataShared().cast<uint64_t*>() + offset, oldCandidate, newCandidate);
return SetBigIntResult(cx, view->type(), result, r);
}
int32_t oldCandidate;
if (!ToInt32(cx, oldv, &oldCandidate))
return false;
@@ -259,6 +339,22 @@ js::atomics_load(JSContext* cx, unsigned argc, Value* vp)
r.setNumber(v);
return true;
}
case Scalar::BigInt64: {
int64_t v = jit::AtomicOperations::loadSeqCst(viewData.cast<int64_t*>() + offset);
BigInt* bigint = BigInt::createFromInt64(cx, v);
if (!bigint)
return false;
r.setBigInt(bigint);
return true;
}
case Scalar::BigUint64: {
uint64_t v = jit::AtomicOperations::loadSeqCst(viewData.cast<uint64_t*>() + offset);
BigInt* bigint = BigInt::createFromUint64(cx, v);
if (!bigint)
return false;
r.setBigInt(bigint);
return true;
}
default:
return ReportBadArrayType(cx);
}
@@ -337,6 +433,25 @@ ExchangeOrStore(JSContext* cx, unsigned argc, Value* vp)
uint32_t offset;
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
return false;
if (Scalar::isBigIntType(view->type())) {
RootedBigInt bigint(cx, ToBigInt(cx, valv));
if (!bigint)
return false;
uint64_t value = BigIntToRawBits(view->type(), bigint);
if (op == DoStore) {
jit::AtomicOperations::storeSeqCst(view->viewDataShared().cast<uint64_t*>() + offset,
value);
r.setBigInt(bigint);
return true;
}
uint64_t result = jit::AtomicOperations::exchangeSeqCst(
view->viewDataShared().cast<uint64_t*>() + offset, value);
return SetBigIntResult(cx, view->type(), result, r);
}
double integerValue;
if (!ToInteger(cx, valv, &integerValue))
return false;
@@ -380,6 +495,24 @@ AtomicsBinop(JSContext* cx, HandleValue objv, HandleValue idxv, HandleValue valv
uint32_t offset;
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
return false;
if (Scalar::isBigIntType(view->type())) {
uint64_t value;
if (!BigIntToRawBits(cx, view->type(), valv, &value))
return false;
SharedMem<uint64_t*> addr = view->viewDataShared().cast<uint64_t*>() + offset;
uint64_t old = jit::AtomicOperations::loadSeqCst(addr);
for (;;) {
uint64_t replacement = T::operate64(old, value);
uint64_t observed = jit::AtomicOperations::compareExchangeSeqCst(addr, old,
replacement);
if (observed == old)
return SetBigIntResult(cx, view->type(), old, r);
old = observed;
}
}
int32_t numberValue;
if (!ToInt32(cx, valv, &numberValue))
return false;
@@ -434,6 +567,7 @@ class PerformAdd
public:
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchAddSeqCst)
static int32_t perform(int32_t x, int32_t y) { return x + y; }
static uint64_t operate64(uint64_t x, uint64_t y) { return x + y; }
};
bool
@@ -448,6 +582,7 @@ class PerformSub
public:
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchSubSeqCst)
static int32_t perform(int32_t x, int32_t y) { return x - y; }
static uint64_t operate64(uint64_t x, uint64_t y) { return x - y; }
};
bool
@@ -462,6 +597,7 @@ class PerformAnd
public:
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchAndSeqCst)
static int32_t perform(int32_t x, int32_t y) { return x & y; }
static uint64_t operate64(uint64_t x, uint64_t y) { return x & y; }
};
bool
@@ -476,6 +612,7 @@ class PerformOr
public:
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchOrSeqCst)
static int32_t perform(int32_t x, int32_t y) { return x | y; }
static uint64_t operate64(uint64_t x, uint64_t y) { return x | y; }
};
bool
@@ -490,6 +627,7 @@ class PerformXor
public:
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchXorSeqCst)
static int32_t perform(int32_t x, int32_t y) { return x ^ y; }
static uint64_t operate64(uint64_t x, uint64_t y) { return x ^ y; }
};
bool
@@ -693,11 +831,13 @@ js::atomics_cmpxchg_asm_callout(wasm::Instance* instance, int32_t vt, int32_t of
namespace js {
class AtomicsWaitAsyncTask;
// Represents one waiting worker.
//
// The type is declared opaque in SharedArrayObject.h. Instances of
// js::FutexWaiter are stack-allocated and linked onto a list across a
// call to FutexRuntime::wait().
// js::FutexWaiter are linked onto a list across a call to FutexRuntime::wait()
// or an async wait task.
//
// The 'waiters' field of the SharedArrayRawBuffer points to the highest
// priority waiter in the list, and lower priority nodes are linked through
@@ -711,14 +851,34 @@ class FutexWaiter
public:
FutexWaiter(uint32_t offset, JSRuntime* rt)
: offset(offset),
kind(Sync),
rt(rt),
asyncTask(nullptr),
lower_pri(nullptr),
back(nullptr)
{
}
uint32_t offset; // int32 element index within the SharedArrayBuffer
FutexWaiter(uint32_t offset, AtomicsWaitAsyncTask* asyncTask)
: offset(offset),
kind(Async),
rt(nullptr),
asyncTask(asyncTask),
lower_pri(nullptr),
back(nullptr)
{
}
bool isWaiting() const;
void notify();
uint32_t offset; // byte offset within the SharedArrayBuffer
enum WaiterKind {
Sync,
Async
} kind;
JSRuntime* rt; // The runtime of the waiter
AtomicsWaitAsyncTask* asyncTask; // The async waiter task, if any
FutexWaiter* lower_pri; // Lower priority nodes in circular doubly-linked list of waiters
FutexWaiter* back; // Other direction
};
@@ -742,8 +902,195 @@ class AutoLockFutexAPI
js::UniqueLock<js::Mutex>& unique() { return *unique_; }
};
static void
AddWaiter(SharedArrayRawBuffer* sarb, FutexWaiter* waiter)
{
if (FutexWaiter* waiters = sarb->waiters()) {
waiter->lower_pri = waiters;
waiter->back = waiters->back;
waiters->back->lower_pri = waiter;
waiters->back = waiter;
} else {
waiter->lower_pri = waiter->back = waiter;
sarb->setWaiters(waiter);
}
}
static void
RemoveWaiter(SharedArrayRawBuffer* sarb, FutexWaiter* waiter)
{
if (waiter->lower_pri == waiter) {
sarb->setWaiters(nullptr);
} else {
waiter->lower_pri->back = waiter->back;
waiter->back->lower_pri = waiter->lower_pri;
if (sarb->waiters() == waiter)
sarb->setWaiters(waiter->lower_pri);
}
waiter->lower_pri = nullptr;
waiter->back = nullptr;
}
class AtomicsWaitAsyncTask : public PromiseTask
{
enum class State {
Waiting,
Notified,
TimedOut
};
SharedArrayRawBuffer* sarb_;
FutexWaiter waiter_;
mozilla::Maybe<mozilla::TimeDuration> timeout_;
ConditionVariable cond_;
State state_;
bool isInWaiterList_;
public:
AtomicsWaitAsyncTask(JSContext* cx, Handle<PromiseObject*> promise,
SharedArrayRawBuffer* sarb, uint32_t offset,
mozilla::Maybe<mozilla::TimeDuration>& timeout)
: PromiseTask(cx, promise),
sarb_(sarb),
waiter_(offset, this),
timeout_(timeout),
state_(State::Waiting),
isInWaiterList_(false)
{
}
~AtomicsWaitAsyncTask() {
if (isInWaiterList_) {
AutoLockFutexAPI lock;
if (isInWaiterList_)
removeFromWaiterList();
}
sarb_->dropReference();
}
FutexWaiter* waiter() {
return &waiter_;
}
void setInWaiterList() {
isInWaiterList_ = true;
}
bool isWaiting() const {
return state_ == State::Waiting;
}
void notify() {
MOZ_ASSERT(isWaiting());
state_ = State::Notified;
cond_.notify_all();
}
void execute() override {
AutoLockFutexAPI lock;
const bool isTimed = timeout_.isSome();
auto finalEnd = timeout_.map([](mozilla::TimeDuration& timeout) {
return mozilla::TimeStamp::Now() + timeout;
});
auto maxSlice = mozilla::TimeDuration::FromSeconds(4000.0);
while (state_ == State::Waiting) {
if (isTimed) {
auto sliceEnd = finalEnd.map([&](mozilla::TimeStamp& finalEnd) {
auto sliceEnd = mozilla::TimeStamp::Now() + maxSlice;
if (finalEnd < sliceEnd)
sliceEnd = finalEnd;
return sliceEnd;
});
mozilla::Unused << cond_.wait_until(lock.unique(), *sliceEnd);
if (state_ == State::Waiting && mozilla::TimeStamp::Now() >= *finalEnd) {
state_ = State::TimedOut;
break;
}
} else {
cond_.wait(lock.unique());
}
}
if (isInWaiterList_)
removeFromWaiterList();
}
private:
void removeFromWaiterList() {
MOZ_ASSERT(isInWaiterList_);
RemoveWaiter(sarb_, &waiter_);
isInWaiterList_ = false;
}
bool finishPromise(JSContext* cx, Handle<PromiseObject*> promise) override {
RootedValue result(cx);
if (state_ == State::TimedOut)
result.setString(cx->names().futexTimedOut);
else
result.setString(cx->names().futexOK);
return PromiseObject::resolve(cx, promise, result);
}
};
bool
FutexWaiter::isWaiting() const
{
if (kind == Sync)
return rt->fx.isWaiting();
return asyncTask->isWaiting();
}
void
FutexWaiter::notify()
{
if (kind == Sync) {
rt->fx.notify(FutexRuntime::NotifyExplicit);
return;
}
asyncTask->notify();
}
} // namespace js
static bool
GetWaitTimeout(JSContext* cx, HandleValue timeoutv,
mozilla::Maybe<mozilla::TimeDuration>* timeout)
{
timeout->reset();
if (!timeoutv.isUndefined()) {
double timeout_ms;
if (!ToNumber(cx, timeoutv, &timeout_ms))
return false;
if (!mozilla::IsNaN(timeout_ms)) {
if (timeout_ms < 0)
*timeout = mozilla::Some(mozilla::TimeDuration::FromSeconds(0.0));
else if (!mozilla::IsInfinite(timeout_ms))
*timeout = mozilla::Some(mozilla::TimeDuration::FromMilliseconds(timeout_ms));
}
}
return true;
}
static bool
CreateWaitAsyncResult(JSContext* cx, bool isAsync, HandleValue value, MutableHandleValue rval)
{
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
RootedValue asyncValue(cx, BooleanValue(isAsync));
if (!NativeDefineDataProperty(cx, obj, cx->names().async, asyncValue, JSPROP_ENUMERATE))
return false;
if (!NativeDefineDataProperty(cx, obj, cx->names().value, value, JSPROP_ENUMERATE))
return false;
rval.setObject(*obj);
return true;
}
bool
js::atomics_wait(JSContext* cx, unsigned argc, Value* vp)
{
@@ -759,26 +1106,24 @@ js::atomics_wait(JSContext* cx, unsigned argc, Value* vp)
Rooted<TypedArrayObject*> view(cx, nullptr);
if (!GetSharedTypedArray(cx, objv, &view))
return false;
if (view->type() != Scalar::Int32)
if (!IsWaitableTypedArray(view->type()))
return ReportBadArrayType(cx);
uint32_t offset;
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
return false;
int32_t value;
if (!ToInt32(cx, valv, &value))
return false;
mozilla::Maybe<mozilla::TimeDuration> timeout;
if (!timeoutv.isUndefined()) {
double timeout_ms;
if (!ToNumber(cx, timeoutv, &timeout_ms))
uint64_t value = 0;
if (view->type() == Scalar::BigInt64) {
if (!BigIntToRawBits(cx, view->type(), valv, &value))
return false;
if (!mozilla::IsNaN(timeout_ms)) {
if (timeout_ms < 0)
timeout = mozilla::Some(mozilla::TimeDuration::FromSeconds(0.0));
else if (!mozilla::IsInfinite(timeout_ms))
timeout = mozilla::Some(mozilla::TimeDuration::FromMilliseconds(timeout_ms));
}
} else {
int32_t int32Value;
if (!ToInt32(cx, valv, &int32Value))
return false;
value = uint32_t(int32Value);
}
mozilla::Maybe<mozilla::TimeDuration> timeout;
if (!GetWaitTimeout(cx, timeoutv, &timeout))
return false;
if (!rt->fx.canWait())
return ReportCannotWait(cx);
@@ -787,8 +1132,7 @@ js::atomics_wait(JSContext* cx, unsigned argc, Value* vp)
// and it provides the necessary memory fence.
AutoLockFutexAPI lock;
SharedMem<int32_t*> addr = view->viewDataShared().cast<int32_t*>() + offset;
if (jit::AtomicOperations::loadSafeWhenRacy(addr) != value) {
if (!WaitValueMatches(view, offset, value)) {
r.setString(cx->names().futexNotEqual);
return true;
}
@@ -796,16 +1140,8 @@ js::atomics_wait(JSContext* cx, unsigned argc, Value* vp)
Rooted<SharedArrayBufferObject*> sab(cx, view->bufferShared());
SharedArrayRawBuffer* sarb = sab->rawBufferObject();
FutexWaiter w(offset, rt);
if (FutexWaiter* waiters = sarb->waiters()) {
w.lower_pri = waiters;
w.back = waiters->back;
waiters->back->lower_pri = &w;
waiters->back = &w;
} else {
w.lower_pri = w.back = &w;
sarb->setWaiters(&w);
}
FutexWaiter w(GetWaiterByteOffset(view, offset), rt);
AddWaiter(sarb, &w);
FutexRuntime::WaitResult result = FutexRuntime::FutexOK;
bool retval = rt->fx.wait(cx, lock.unique(), timeout, &result);
@@ -820,17 +1156,98 @@ js::atomics_wait(JSContext* cx, unsigned argc, Value* vp)
}
}
if (w.lower_pri == &w) {
sarb->setWaiters(nullptr);
} else {
w.lower_pri->back = w.back;
w.back->lower_pri = w.lower_pri;
if (sarb->waiters() == &w)
sarb->setWaiters(w.lower_pri);
}
RemoveWaiter(sarb, &w);
return retval;
}
bool
js::atomics_waitAsync(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
HandleValue objv = args.get(0);
HandleValue idxv = args.get(1);
HandleValue valv = args.get(2);
HandleValue timeoutv = args.get(3);
MutableHandleValue r = args.rval();
Rooted<TypedArrayObject*> view(cx, nullptr);
if (!GetSharedTypedArray(cx, objv, &view))
return false;
if (!IsWaitableTypedArray(view->type()))
return ReportBadArrayType(cx);
uint32_t offset;
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
return false;
uint64_t value = 0;
if (view->type() == Scalar::BigInt64) {
if (!BigIntToRawBits(cx, view->type(), valv, &value))
return false;
} else {
int32_t int32Value;
if (!ToInt32(cx, valv, &int32Value))
return false;
value = uint32_t(int32Value);
}
mozilla::Maybe<mozilla::TimeDuration> timeout;
if (!GetWaitTimeout(cx, timeoutv, &timeout))
return false;
Rooted<PromiseObject*> promise(cx, PromiseObject::createSkippingExecutor(cx));
if (!promise)
return false;
RootedValue promiseValue(cx, ObjectValue(*promise));
RootedValue result(cx);
if (!CreateWaitAsyncResult(cx, true, promiseValue, &result))
return false;
Rooted<SharedArrayBufferObject*> sab(cx, view->bufferShared());
SharedArrayRawBuffer* sarb = sab->rawBufferObject();
if (!sarb->addReference()) {
JS_ReportErrorASCII(cx, "Reference count overflow on SharedArrayBuffer");
return false;
}
auto task = cx->make_unique<AtomicsWaitAsyncTask>(cx, promise, sarb, offset, timeout);
if (!task) {
sarb->dropReference();
return false;
}
bool isAsync = false;
RootedValue immediateResult(cx);
{
AutoLockFutexAPI lock;
if (!WaitValueMatches(view, offset, value)) {
immediateResult.setString(cx->names().futexNotEqual);
} else if (timeout.isSome() && timeout->ToMilliseconds() == 0.0) {
immediateResult.setString(cx->names().futexTimedOut);
} else {
if (!cx->startAsyncTaskCallback || !cx->finishAsyncTaskCallback ||
!CanUseExtraThreads())
{
JS_ReportErrorASCII(cx, "Atomics.waitAsync not supported in this runtime.");
return false;
}
task->waiter()->offset = GetWaiterByteOffset(view, offset);
AddWaiter(sarb, task->waiter());
task->setInWaiterList();
isAsync = true;
}
}
if (!isAsync)
return CreateWaitAsyncResult(cx, false, immediateResult, r);
if (!StartPromiseTask(cx, Move(task)))
return false;
r.set(result);
return true;
}
bool
js::atomics_notify(JSContext* cx, unsigned argc, Value* vp)
{
@@ -843,11 +1260,12 @@ js::atomics_notify(JSContext* cx, unsigned argc, Value* vp)
Rooted<TypedArrayObject*> view(cx, nullptr);
if (!GetSharedTypedArray(cx, objv, &view))
return false;
if (view->type() != Scalar::Int32)
if (!IsWaitableTypedArray(view->type()))
return ReportBadArrayType(cx);
uint32_t offset;
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
return false;
offset = GetWaiterByteOffset(view, offset);
double count;
if (countv.isUndefined()) {
count = mozilla::PositiveInfinity<double>();
@@ -870,9 +1288,9 @@ js::atomics_notify(JSContext* cx, unsigned argc, Value* vp)
do {
FutexWaiter* c = iter;
iter = iter->lower_pri;
if (c->offset != offset || !c->rt->fx.isWaiting())
if (c->offset != offset || !c->isWaiting())
continue;
c->rt->fx.notify(FutexRuntime::NotifyExplicit);
c->notify();
++woken;
--count;
} while (count > 0 && iter != waiters);
@@ -1106,6 +1524,7 @@ const JSFunctionSpec AtomicsMethods[] = {
JS_INLINABLE_FN("xor", atomics_xor, 3,0, AtomicsXor),
JS_INLINABLE_FN("isLockFree", atomics_isLockFree, 1,0, AtomicsIsLockFree),
JS_FN("wait", atomics_wait, 4,0),
JS_FN("waitAsync", atomics_waitAsync, 4,0),
JS_FN("notify", atomics_notify, 3,0),
JS_FN("wake", atomics_notify, 3,0), //Legacy name
JS_FS_END
+1
View File
@@ -35,6 +35,7 @@ class AtomicsObject : public JSObject
[[nodiscard]] bool atomics_xor(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] bool atomics_isLockFree(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] bool atomics_wait(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] bool atomics_waitAsync(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] bool atomics_notify(JSContext* cx, unsigned argc, Value* vp);
/* asm.js callouts */
@@ -0,0 +1,608 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "builtin/FinalizationRegistryObject.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "builtin/WeakRefObject.h"
#include "gc/Nursery.h"
#include "gc/Tracer.h"
#include "vm/EqualityOperations.h"
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"
#include "vm/Symbol.h"
#include "jswrapper.h"
#include "jsobjinlines.h"
#include "vm/Interpreter-inl.h"
#include "vm/NativeObject-inl.h"
using namespace js;
enum class WeakCellKind {
Empty,
Object,
Symbol
};
static JSObject*
NormalizeWeakObject(JSObject* obj)
{
if (JSObject* unwrapped = CheckedUnwrap(obj, /* stopAtWindowProxy = */ false))
return unwrapped;
return obj;
}
static bool
GetPrototypeFromFinalizationRegistryConstructor(JSContext* cx, HandleObject newTarget,
MutableHandleObject proto)
{
if (!GetPrototypeFromConstructor(cx, newTarget, proto))
return false;
if (proto)
return true;
RootedObject realmObject(cx, CheckedUnwrap(newTarget, /* stopAtWindowProxy = */ false));
if (!realmObject)
return false;
{
JSAutoCompartment ac(cx, realmObject);
Rooted<GlobalObject*> global(cx, &realmObject->global());
if (!GlobalObject::ensureConstructor(cx, global, JSProto_FinalizationRegistry))
return false;
proto.set(&global->getPrototype(JSProto_FinalizationRegistry).toObject());
}
return cx->compartment()->wrap(cx, proto);
}
struct WeakCell {
WeakCellKind kind;
WeakRef<JSObject*> object;
WeakRef<JS::Symbol*> symbol;
WeakCell() : kind(WeakCellKind::Empty), object(nullptr), symbol(nullptr) {}
explicit WeakCell(JSObject* obj) : kind(WeakCellKind::Object), object(obj), symbol(nullptr) {}
explicit WeakCell(JS::Symbol* sym) : kind(WeakCellKind::Symbol), object(nullptr), symbol(sym) {}
void clear() {
kind = WeakCellKind::Empty;
object = nullptr;
symbol = nullptr;
}
bool isEmpty() const { return kind == WeakCellKind::Empty; }
bool isDead() const {
if (kind == WeakCellKind::Object)
return !object.unbarrieredGet();
if (kind == WeakCellKind::Symbol)
return !symbol.unbarrieredGet();
return false;
}
bool sameValue(HandleValue value) const {
if (kind == WeakCellKind::Object)
return value.isObject() && object.get() == NormalizeWeakObject(&value.toObject());
if (kind == WeakCellKind::Symbol)
return value.isSymbol() && symbol.get() == value.toSymbol();
return false;
}
void trace(JSTracer* trc, const char* name) {
if (kind == WeakCellKind::Object) {
JSObject* target = object.unbarrieredGet();
if (!target)
return;
if (IsInsideNursery(target)) {
TraceManuallyBarrieredEdge(trc, object.unsafeGet(), name);
} else {
if (trc->isMarkingTracer() && !target->asTenured().zone()->isCollecting())
return;
TraceWeakEdge(trc, &object, name);
}
} else if (kind == WeakCellKind::Symbol) {
JS::Symbol* target = symbol.unbarrieredGet();
if (target) {
if (trc->isMarkingTracer() && !target->asTenured().zone()->isCollecting())
return;
TraceWeakEdge(trc, &symbol, name);
}
}
}
void traceIfZoneIsCollecting(JSTracer* trc, const char* name) {
if (kind == WeakCellKind::Object) {
JSObject* target = object.unbarrieredGet();
if (!target)
return;
if (IsInsideNursery(target)) {
TraceManuallyBarrieredEdge(trc, object.unsafeGet(), name);
} else if (target->asTenured().zone()->isCollecting()) {
TraceWeakEdge(trc, &object, name);
}
} else if (kind == WeakCellKind::Symbol) {
JS::Symbol* target = symbol.unbarrieredGet();
if (target && target->asTenured().zone()->isCollecting())
TraceWeakEdge(trc, &symbol, name);
}
}
};
struct FinalizationRecord {
WeakCell target;
JS::Heap<Value> heldValue;
WeakCell unregisterToken;
bool active;
bool queued;
FinalizationRecord(HandleValue targetValue, HandleValue heldValue,
HandleValue unregisterTokenValue)
: heldValue(heldValue),
active(true),
queued(false)
{
if (targetValue.isObject())
target = WeakCell(NormalizeWeakObject(&targetValue.toObject()));
else
target = WeakCell(targetValue.toSymbol());
if (unregisterTokenValue.isObject())
unregisterToken = WeakCell(NormalizeWeakObject(&unregisterTokenValue.toObject()));
else if (unregisterTokenValue.isSymbol())
unregisterToken = WeakCell(unregisterTokenValue.toSymbol());
}
void trace(JSTracer* trc) {
if (active || queued)
JS::TraceEdge(trc, &heldValue, "FinalizationRegistry held value");
if (active) {
target.trace(trc, "FinalizationRegistry target");
if (!unregisterToken.isEmpty())
unregisterToken.trace(trc, "FinalizationRegistry unregister token");
}
}
void traceWeakEdgesForCollectedZones(JSTracer* trc) {
if (!active)
return;
target.traceIfZoneIsCollecting(trc, "FinalizationRegistry target");
if (!unregisterToken.isEmpty())
unregisterToken.traceIfZoneIsCollecting(trc,
"FinalizationRegistry unregister token");
}
bool targetIsDead() const {
return active && target.isDead();
}
bool matchesToken(HandleValue token) const {
return active && !queued && !unregisterToken.isEmpty() &&
unregisterToken.sameValue(token);
}
void queueForCleanup() {
MOZ_ASSERT(active);
MOZ_ASSERT(!queued);
active = false;
queued = true;
target.clear();
unregisterToken.clear();
}
void clear() {
active = false;
queued = false;
target.clear();
unregisterToken.clear();
heldValue.setUndefined();
}
};
using FinalizationRecordVector = Vector<FinalizationRecord*, 0, SystemAllocPolicy>;
struct FinalizationRegistryObject::Data {
JS::Heap<JSObject*> cleanupCallback;
JS::Heap<JSObject*> cleanupJob;
FinalizationRecordVector records;
FinalizationRecordVector cleanupQueue;
bool queuedForCleanup;
explicit Data(JSObject* cleanupCallback)
: cleanupCallback(cleanupCallback),
cleanupJob(nullptr),
records(SystemAllocPolicy()),
cleanupQueue(SystemAllocPolicy()),
queuedForCleanup(false)
{}
~Data() {
for (size_t i = 0; i < records.length(); i++)
js_delete(records[i]);
}
void trace(JSTracer* trc) {
JS::TraceEdge(trc, &cleanupCallback, "FinalizationRegistry cleanup callback");
if (cleanupJob.unbarrieredGet())
JS::TraceEdge(trc, &cleanupJob, "FinalizationRegistry cleanup job");
for (size_t i = 0; i < records.length(); i++)
records[i]->trace(trc);
}
bool appendRecord(FinalizationRecord* record) {
return records.append(record);
}
bool appendCleanupRecord(FinalizationRecord* record) {
return cleanupQueue.append(record);
}
void compactRecords() {
for (size_t i = 0; i < records.length();) {
FinalizationRecord* record = records[i];
if (!record->active && !record->queued) {
js_delete(record);
records.erase(records.begin() + i);
continue;
}
i++;
}
}
void unregister(HandleValue token, bool* removed) {
*removed = false;
for (size_t i = 0; i < records.length(); i++) {
FinalizationRecord* record = records[i];
if (record->matchesToken(token)) {
record->clear();
*removed = true;
}
}
compactRecords();
}
};
static FinalizationRegistryObject::Data*
GetData(JSObject* obj)
{
return obj->as<FinalizationRegistryObject>().getData();
}
static MOZ_ALWAYS_INLINE bool
IsFinalizationRegistry(HandleValue v)
{
return v.isObject() && v.toObject().is<FinalizationRegistryObject>();
}
static bool
FinalizationRegistry_register_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsFinalizationRegistry(args.thisv()));
if (!CanBeHeldWeakly(args.get(0))) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_BAD_FINALIZATION_REGISTRY_TARGET);
return false;
}
RootedValue target(cx, args[0]);
RootedValue heldValue(cx, args.get(1));
bool same;
if (!SameValue(cx, target, heldValue, &same))
return false;
if (same) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_BAD_FINALIZATION_REGISTRY_HELD_VALUE);
return false;
}
RootedValue unregisterToken(cx, args.get(2));
if (!CanBeHeldWeakly(unregisterToken)) {
if (!unregisterToken.isUndefined()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_BAD_FINALIZATION_REGISTRY_TOKEN);
return false;
}
unregisterToken.setUndefined();
}
FinalizationRecord* record = cx->new_<FinalizationRecord>(target, heldValue, unregisterToken);
if (!record)
return false;
auto* data = GetData(&args.thisv().toObject());
if (!data->appendRecord(record)) {
js_delete(record);
ReportOutOfMemory(cx);
return false;
}
args.rval().setUndefined();
return true;
}
static bool
FinalizationRegistry_unregister_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsFinalizationRegistry(args.thisv()));
RootedValue unregisterToken(cx, args.get(0));
if (!CanBeHeldWeakly(unregisterToken)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_BAD_FINALIZATION_REGISTRY_TOKEN);
return false;
}
bool removed = false;
auto* data = GetData(&args.thisv().toObject());
data->unregister(unregisterToken, &removed);
args.rval().setBoolean(removed);
return true;
}
const JSPropertySpec FinalizationRegistryObject::properties[] = {
JS_PS_END
};
const JSFunctionSpec FinalizationRegistryObject::methods[] = {
JS_FN("register", FinalizationRegistryObject::register_, 2, 0),
JS_FN("unregister", FinalizationRegistryObject::unregister, 1, 0),
JS_FS_END
};
static JSObject*
InitFinalizationRegistryClass(JSContext* cx, HandleObject obj, bool defineMembers)
{
Handle<GlobalObject*> global = obj.as<GlobalObject>();
RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!proto)
return nullptr;
RootedFunction ctor(cx, GlobalObject::createConstructor(cx, FinalizationRegistryObject::construct,
ClassName(JSProto_FinalizationRegistry, cx), 1));
if (!ctor)
return nullptr;
if (!LinkConstructorAndPrototype(cx, ctor, proto))
return nullptr;
if (defineMembers) {
if (!DefinePropertiesAndFunctions(cx, proto, FinalizationRegistryObject::properties,
FinalizationRegistryObject::methods)) {
return nullptr;
}
if (!DefineToStringTag(cx, proto, cx->names().FinalizationRegistry))
return nullptr;
}
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_FinalizationRegistry, ctor, proto))
return nullptr;
return proto;
}
/* static */ FinalizationRegistryObject*
FinalizationRegistryObject::create(JSContext* cx, HandleObject cleanupCallback,
HandleObject proto /* = nullptr */)
{
Rooted<FinalizationRegistryObject*> obj(cx,
NewObjectWithClassProto<FinalizationRegistryObject>(cx, proto));
if (!obj)
return nullptr;
Data* data = cx->new_<Data>(cleanupCallback);
if (!data)
return nullptr;
obj->setPrivate(data);
RootedAtom funName(cx, cx->names().empty);
RootedFunction cleanupJob(cx, NewNativeFunction(cx, FinalizationRegistryObject::cleanupJob, 0,
funName, gc::AllocKind::FUNCTION_EXTENDED,
GenericObject));
if (!cleanupJob)
return nullptr;
cleanupJob->setExtendedSlot(0, ObjectValue(*obj));
data->cleanupJob = cleanupJob;
if (!cx->zone()->finalizationRegistries.append(WeakRef<JSObject*>(obj))) {
ReportOutOfMemory(cx);
return nullptr;
}
return obj;
}
/* static */ bool
FinalizationRegistryObject::construct(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!ThrowIfNotConstructing(cx, args, "FinalizationRegistry"))
return false;
RootedValue cleanupCallbackValue(cx, args.get(0));
RootedObject cleanupCallback(cx, ValueToCallable(cx, cleanupCallbackValue, 0, NO_CONSTRUCT));
if (!cleanupCallback)
return false;
RootedObject proto(cx);
RootedObject newTarget(cx, &args.newTarget().toObject());
if (!GetPrototypeFromFinalizationRegistryConstructor(cx, newTarget, &proto))
return false;
Rooted<FinalizationRegistryObject*> obj(cx,
FinalizationRegistryObject::create(cx, cleanupCallback, proto));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
/* static */ bool
FinalizationRegistryObject::register_(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<IsFinalizationRegistry, FinalizationRegistry_register_impl>(cx, args);
}
/* static */ bool
FinalizationRegistryObject::unregister(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<IsFinalizationRegistry, FinalizationRegistry_unregister_impl>(cx, args);
}
/* static */ bool
FinalizationRegistryObject::cleanupJob(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedFunction job(cx, &args.callee().as<JSFunction>());
Rooted<FinalizationRegistryObject*> registry(cx,
&job->getExtendedSlot(0).toObject().as<FinalizationRegistryObject>());
Data* data = registry->getData();
if (!data) {
args.rval().setUndefined();
return true;
}
data->queuedForCleanup = false;
RootedValue callback(cx, ObjectValue(*data->cleanupCallback.get()));
RootedValue heldValue(cx);
RootedValue ignored(cx);
RootedValue undefined(cx, UndefinedValue());
while (data->cleanupQueue.length() > 0) {
FinalizationRecord* record = data->cleanupQueue[0];
data->cleanupQueue.erase(data->cleanupQueue.begin());
if (!record->queued) {
data->compactRecords();
continue;
}
heldValue.set(record->heldValue.get());
record->clear();
data->compactRecords();
if (!Call(cx, callback, undefined, heldValue, &ignored))
return false;
}
args.rval().setUndefined();
return true;
}
/* static */ void
FinalizationRegistryObject::trace(JSTracer* trc, JSObject* obj)
{
if (Data* data = GetData(obj))
data->trace(trc);
}
/* static */ void
FinalizationRegistryObject::finalize(FreeOp* fop, JSObject* obj)
{
if (Data* data = GetData(obj))
fop->delete_(data);
}
void
FinalizationRegistryObject::traceWeakEdgesForCollectedZones(JSTracer* trc)
{
Data* data = getData();
if (!data)
return;
for (size_t i = 0; i < data->records.length(); i++)
data->records[i]->traceWeakEdgesForCollectedZones(trc);
}
void
FinalizationRegistryObject::sweepAfterGC(JSRuntime* rt)
{
Data* data = getData();
if (!data)
return;
bool needsCleanupJob = false;
for (size_t i = 0; i < data->records.length(); i++) {
FinalizationRecord* record = data->records[i];
if (!record->targetIsDead())
continue;
record->queueForCleanup();
if (!data->appendCleanupRecord(record)) {
AutoEnterOOMUnsafeRegion oomUnsafe;
oomUnsafe.crash("queueing FinalizationRegistry cleanup record");
}
needsCleanupJob = true;
}
if (needsCleanupJob && !data->queuedForCleanup) {
JSContext* cx = rt->contextFromMainThread();
RootedObject cleanupJob(cx, data->cleanupJob.unbarrieredGet());
if (!rt->enqueueFinalizationRegistryCleanupJob(cx, cleanupJob)) {
AutoEnterOOMUnsafeRegion oomUnsafe;
oomUnsafe.crash("queueing FinalizationRegistry cleanup job");
}
data->queuedForCleanup = true;
}
data->compactRecords();
}
static const ClassOps FinalizationRegistryObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* getProperty */
nullptr, /* setProperty */
nullptr, /* enumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
FinalizationRegistryObject::finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
FinalizationRegistryObject::trace
};
const Class FinalizationRegistryObject::class_ = {
"FinalizationRegistry",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_FinalizationRegistry) |
JSCLASS_FOREGROUND_FINALIZE,
&FinalizationRegistryObjectClassOps
};
/* static */ JSObject*
FinalizationRegistryObject::initClass(JSContext* cx, HandleObject obj)
{
return ::InitFinalizationRegistryClass(cx, obj, true);
}
JSObject*
js::InitFinalizationRegistryClass(JSContext* cx, HandleObject obj)
{
return FinalizationRegistryObject::initClass(cx, obj);
}
JSObject*
js::InitBareFinalizationRegistryCtor(JSContext* cx, HandleObject obj)
{
return ::InitFinalizationRegistryClass(cx, obj, false);
}
@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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/. */
#ifndef builtin_FinalizationRegistryObject_h
#define builtin_FinalizationRegistryObject_h
#include "gc/Barrier.h"
#include "vm/NativeObject.h"
namespace js {
class FinalizationRegistryObject : public NativeObject
{
public:
struct Data;
static const Class class_;
static JSObject* initClass(JSContext* cx, HandleObject obj);
static FinalizationRegistryObject* create(JSContext* cx, HandleObject cleanupCallback,
HandleObject proto = nullptr);
static void trace(JSTracer* trc, JSObject* obj);
static void finalize(FreeOp* fop, JSObject* obj);
void traceWeakEdgesForCollectedZones(JSTracer* trc);
[[nodiscard]] static bool construct(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool register_(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool unregister(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool cleanupJob(JSContext* cx, unsigned argc, Value* vp);
void sweepAfterGC(JSRuntime* rt);
Data* getData() const {
return static_cast<Data*>(getPrivate());
}
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
};
extern JSObject*
InitFinalizationRegistryClass(JSContext* cx, HandleObject obj);
extern JSObject*
InitBareFinalizationRegistryCtor(JSContext* cx, HandleObject obj);
} // namespace js
#endif /* builtin_FinalizationRegistryObject_h */
+43
View File
@@ -55,6 +55,49 @@ function MapForEach(callbackfn, thisArg = undefined) {
}
}
// ES2024
// Map.groupBy ( items, callbackfn )
function MapGroupBy(items, callbackfn) {
// Step 1.
RequireObjectCoercible(items);
// Step 2.
if (!IsCallable(callbackfn))
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn));
// Step 3.
var groups = std_Map_create();
// Step 4.
var k = 0;
// Steps 5-8.
for (var value of allowContentIter(items)) {
// Step 6.a.
if (k >= MAX_NUMERIC_INDEX)
ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
// Step 6.b.
var key = callContentFunction(callbackfn, undefined, value, k);
// Steps 6.c-d.
var elements;
if (callFunction(std_Map_has, groups, key)) {
elements = callFunction(std_Map_get, groups, key);
callFunction(std_Array_push, elements, value);
} else {
elements = [value];
callFunction(std_Map_set, groups, key, elements);
}
// Step 6.e.
k++;
}
// Step 9.
return groups;
}
var iteratorTemp = { mapIterationResultPair : null };
function MapIteratorNext() {
+15 -4
View File
@@ -332,9 +332,15 @@ const JSPropertySpec MapObject::staticProperties[] = {
JS_PS_END
};
const JSFunctionSpec MapObject::staticMethods[] = {
JS_SELF_HOSTED_FN("groupBy", "MapGroupBy", 2, 0),
JS_FS_END
};
static JSObject*
InitClass(JSContext* cx, Handle<GlobalObject*> global, const Class* clasp, JSProtoKey key, Native construct,
const JSPropertySpec* properties, const JSFunctionSpec* methods,
const JSFunctionSpec* staticMethods,
const JSPropertySpec* staticProperties)
{
RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx));
@@ -343,8 +349,13 @@ InitClass(JSContext* cx, Handle<GlobalObject*> global, const Class* clasp, JSPro
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 0));
if (!ctor ||
!JS_DefineProperties(cx, ctor, staticProperties) ||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
!JS_DefineProperties(cx, ctor, staticProperties))
{
return nullptr;
}
if (staticMethods && !JS_DefineFunctions(cx, ctor, staticMethods))
return nullptr;
if (!LinkConstructorAndPrototype(cx, ctor, proto) ||
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
!GlobalObject::initBuiltinConstructor(cx, global, key, ctor, proto))
{
@@ -359,7 +370,7 @@ MapObject::initClass(JSContext* cx, JSObject* obj)
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
RootedObject proto(cx,
InitClass(cx, global, &class_, JSProto_Map, construct, properties, methods,
staticProperties));
staticMethods, staticProperties));
if (proto) {
// Define the "entries" method.
JSFunction* fun = JS_DefineFunction(cx, proto, "entries", entries, 0, 0);
@@ -1084,7 +1095,7 @@ SetObject::initClass(JSContext* cx, JSObject* obj)
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
RootedObject proto(cx,
InitClass(cx, global, &class_, JSProto_Set, construct, properties, methods,
staticProperties));
nullptr, staticProperties));
if (proto) {
// Define the "values" method.
JSFunction* fun = JS_DefineFunction(cx, proto, "values", values, 0, 0);
+3 -2
View File
@@ -110,7 +110,9 @@ class MapObject : public NativeObject {
[[nodiscard]] static bool getKeysAndValuesInterleaved(JSContext* cx, HandleObject obj,
JS::MutableHandle<GCVector<JS::Value>> entries);
[[nodiscard]] static bool entries(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool get(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool has(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool set(JSContext* cx, unsigned argc, Value* vp);
static MapObject* create(JSContext* cx, HandleObject proto = nullptr);
// Publicly exposed Map calls for JSAPI access (webidl maplike/setlike
@@ -137,6 +139,7 @@ class MapObject : public NativeObject {
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];
static const JSFunctionSpec staticMethods[];
static const JSPropertySpec staticProperties[];
ValueMap* getData() { return static_cast<ValueMap*>(getPrivate()); }
static ValueMap& extract(HandleObject o);
@@ -153,10 +156,8 @@ class MapObject : public NativeObject {
[[nodiscard]] static bool size_impl(JSContext* cx, const CallArgs& args);
[[nodiscard]] static bool size(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool get_impl(JSContext* cx, const CallArgs& args);
[[nodiscard]] static bool get(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool has_impl(JSContext* cx, const CallArgs& args);
[[nodiscard]] static bool set_impl(JSContext* cx, const CallArgs& args);
[[nodiscard]] static bool set(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool delete_impl(JSContext* cx, const CallArgs& args);
[[nodiscard]] static bool delete_(JSContext* cx, unsigned argc, Value* vp);
[[nodiscard]] static bool keys_impl(JSContext* cx, const CallArgs& args);
+7 -3
View File
@@ -240,12 +240,16 @@ function ObjectGroupBy(items, callbackfn) {
// Steps 5-8.
for (var value of allowContentIter(items)) {
// Step 6.a.
var key = callContentFunction(callbackfn, undefined, value, k);
if (k >= MAX_NUMERIC_INDEX)
ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
// Step 6.b.
var key = callContentFunction(callbackfn, undefined, value, k);
// Step 6.c.
key = ToPropertyKey(key);
// Steps 6.c-d.
// Steps 6.d-e.
var elements = groups[key];
if (elements === undefined) {
_DefineDataProperty(groups, key, [value]);
@@ -253,7 +257,7 @@ function ObjectGroupBy(items, callbackfn) {
callFunction(std_Array_push, elements, value);
}
// Step 6.e.
// Step 6.f.
k++;
}
+43
View File
@@ -3722,6 +3722,48 @@ Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp)
return true;
}
// ES2024
// Promise.withResolvers ( )
static bool
Promise_static_withResolvers(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
// Step 1.
if (!args.thisv().isObject()) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, -1, args.thisv(), nullptr);
return false;
}
RootedObject C(cx, &args.thisv().toObject());
// Step 2.
Rooted<PromiseCapability> capability(cx);
if (!NewPromiseCapability(cx, C, &capability, false))
return false;
// Step 3.
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
// Steps 4-7.
RootedValue promise(cx, ObjectValue(*capability.promise()));
if (!::JS_DefineProperty(cx, obj, "promise", promise, JSPROP_ENUMERATE))
return false;
RootedValue resolve(cx, ObjectValue(*capability.resolve()));
if (!::JS_DefineProperty(cx, obj, "resolve", resolve, JSPROP_ENUMERATE))
return false;
RootedValue reject(cx, ObjectValue(*capability.reject()));
if (!::JS_DefineProperty(cx, obj, "reject", reject, JSPROP_ENUMERATE))
return false;
// Step 8.
args.rval().setObject(*obj);
return true;
}
/**
* Unforgeable version of ES2016, 25.4.4.5, Promise.resolve.
*/
@@ -5251,6 +5293,7 @@ static const JSFunctionSpec promise_static_methods[] = {
JS_FN("race", Promise_static_race, 1, 0),
JS_FN("reject", Promise_reject, 1, 0),
JS_FN("resolve", Promise_static_resolve, 1, 0),
JS_FN("withResolvers", Promise_static_withResolvers, 0, 0),
JS_FS_END
};
+6 -1
View File
@@ -8,8 +8,11 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/TypeTraits.h"
#include <algorithm>
#include "jscntxt.h"
#include "builtin/SelfHostingDefines.h"
#include "irregexp/RegExpParser.h"
#include "jit/InlinableNatives.h"
#include "vm/RegExpStatics.h"
@@ -1754,7 +1757,9 @@ js::RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLi
// Step 6.
MOZ_ASSERT(position <= string->length());
uint32_t nCaptures = matchResultLength - 1;
// String substitutions can only reference $1 through $99.
uint32_t nCaptures = std::min<uint32_t>(matchResultLength - 1,
REGEXP_MAX_SUBSTITUTION_CAPTURES);
Rooted<CapturesVector> captures(cx, CapturesVector(cx));
if (!captures.reserve(nCaptures))
return false;
+9 -1
View File
@@ -463,6 +463,12 @@ function RegExpGetComplexReplacement(result, matched, S, position,
// Step 14.k.i (reordered).
_DefineDataProperty(captures, capturesLength++, matched);
// String substitutions can only reference $1 through $99. Keep getting and
// stringifying all captures because those operations are observable.
var storedCaptures = functionalReplace ?
nCaptures :
std_Math_min(nCaptures, REGEXP_MAX_SUBSTITUTION_CAPTURES);
// Step 14.g, 14.i, 14.i.iv.
for (var n = 1; n <= nCaptures; n++) {
// Step 14.i.i.
@@ -473,7 +479,9 @@ function RegExpGetComplexReplacement(result, matched, S, position,
capN = ToString(capN);
// Step 14.i.iii.
_DefineDataProperty(captures, capturesLength++, capN);
if (n <= storedCaptures) {
_DefineDataProperty(captures, capturesLength++, capN);
}
}
// Step 14.j.
+2
View File
@@ -79,6 +79,8 @@
#define REGEXP_FLAGS_SLOT 2
#define REGEXP_MAX_SUBSTITUTION_CAPTURES 99
#define REGEXP_IGNORECASE_FLAG 0x01
#define REGEXP_GLOBAL_FLAG 0x02
#define REGEXP_MULTILINE_FLAG 0x04
+76
View File
@@ -654,6 +654,82 @@ function String_repeat(count) {
return T;
}
// ES2024
// String.prototype.isWellFormed ( )
function String_isWellFormed() {
// Steps 1-2.
RequireObjectCoercible(this);
var S = ToString(this);
// Step 3.
var length = S.length;
for (var k = 0; k < length; k++) {
var c = callFunction(std_String_charCodeAt, S, k);
if (c >= 0xD800 && c <= 0xDBFF) {
if (k + 1 >= length)
return false;
var d = callFunction(std_String_charCodeAt, S, k + 1);
if (d < 0xDC00 || d > 0xDFFF)
return false;
k++;
} else if (c >= 0xDC00 && c <= 0xDFFF) {
return false;
}
}
// Step 4.
return true;
}
// ES2024
// String.prototype.toWellFormed ( )
function String_toWellFormed() {
// Steps 1-2.
RequireObjectCoercible(this);
var S = ToString(this);
// Step 3.
var length = S.length;
var result = "";
var copied = 0;
for (var k = 0; k < length; k++) {
var c = callFunction(std_String_charCodeAt, S, k);
var isUnpairedSurrogate = false;
if (c >= 0xD800 && c <= 0xDBFF) {
if (k + 1 < length) {
var d = callFunction(std_String_charCodeAt, S, k + 1);
if (d >= 0xDC00 && d <= 0xDFFF) {
k++;
continue;
}
}
isUnpairedSurrogate = true;
} else if (c >= 0xDC00 && c <= 0xDFFF) {
isUnpairedSurrogate = true;
}
if (isUnpairedSurrogate) {
if (copied < k)
result += callFunction(String_substring, S, copied, k);
result += "\uFFFD";
copied = k + 1;
}
}
if (copied === 0)
return S;
if (copied < length)
result += callFunction(String_substring, S, copied, length);
// Step 4.
return result;
}
// ES6 draft specification, section 21.1.3.27, version 2013-09-27.
function String_iterator() {
RequireObjectCoercible(this);
+26 -2
View File
@@ -41,10 +41,21 @@ function TypedArrayContentTypeIsBigIntMethod() {
return IsBigInt64TypedArray(this) || IsBigUint64TypedArray(this);
}
function ThrowIfTypedArrayOutOfBounds(tarray) {
if (TypedArrayIsOutOfBounds(tarray))
ThrowTypeError(JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
}
function ThrowIfPossiblyWrappedTypedArrayOutOfBounds(tarray) {
if (PossiblyWrappedTypedArrayIsOutOfBounds(tarray))
ThrowTypeError(JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
}
function GetAttachedArrayBuffer(tarray) {
var buffer = ViewedArrayBufferIfReified(tarray);
if (IsDetachedBuffer(buffer))
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
ThrowIfTypedArrayOutOfBounds(tarray);
return buffer;
}
@@ -67,6 +78,7 @@ function IsTypedArrayEnsuringArrayBuffer(arg) {
if (IsObject(arg) && IsPossiblyWrappedTypedArray(arg)) {
if (PossiblyWrappedTypedArrayHasDetachedBuffer(arg))
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
ThrowIfPossiblyWrappedTypedArrayOutOfBounds(arg);
return false;
}
@@ -89,6 +101,7 @@ function ValidateTypedArray(obj, error) {
if (IsPossiblyWrappedTypedArray(obj)) {
if (PossiblyWrappedTypedArrayHasDetachedBuffer(obj))
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
ThrowIfPossiblyWrappedTypedArrayOutOfBounds(obj);
return false;
}
}
@@ -1130,12 +1143,18 @@ function TypedArraySet(overloaded, offset = 0) {
// Steps 9-10.
var targetBuffer = GetAttachedArrayBuffer(target);
ThrowIfTypedArrayOutOfBounds(target);
// Step 11.
var targetLength = TypedArrayLength(target);
// Steps 12 et seq.
if (IsPossiblyWrappedTypedArray(overloaded))
if (IsPossiblyWrappedTypedArray(overloaded)) {
if (PossiblyWrappedTypedArrayHasDetachedBuffer(overloaded))
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
ThrowIfPossiblyWrappedTypedArrayOutOfBounds(overloaded);
return SetFromTypedArray(target, overloaded, targetOffset, targetLength);
}
return SetFromNonTypedArray(target, overloaded, targetOffset, targetLength, targetBuffer);
}
@@ -1472,6 +1491,8 @@ function TypedArraySubarray(begin, end) {
"TypedArraySubarray");
}
GetAttachedArrayBuffer(obj);
// Steps 4-6.
var buffer = TypedArrayBuffer(obj);
var srcLength = TypedArrayLength(obj);
@@ -1952,7 +1973,10 @@ function ArrayBufferSlice(start, end) {
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
// Steps 19-21.
ArrayBufferCopyData(new_, 0, O, first | 0, newLen | 0, isWrapped);
var currentLen = ArrayBufferByteLength(O);
var copyLen = first >= currentLen ? 0 : std_Math_min(newLen, currentLen - first);
if (copyLen > 0)
ArrayBufferCopyData(new_, 0, O, first | 0, copyLen | 0, isWrapped);
// Step 22.
return new_;
+171 -52
View File
@@ -8,6 +8,7 @@
#include "jsapi.h"
#include "jscntxt.h"
#include "builtin/WeakRefObject.h"
#include "vm/SelfHosting.h"
#include "vm/Interpreter-inl.h"
@@ -21,21 +22,80 @@ IsWeakMap(HandleValue v)
return v.isObject() && v.toObject().is<WeakMapObject>();
}
struct WeakMapObject::Data
{
ObjectValueMap objectMap;
SymbolValueMap symbolMap;
Data(JSContext* cx, JSObject* owner)
: objectMap(cx, owner),
symbolMap(cx, owner)
{}
bool init() {
return objectMap.init() && symbolMap.init();
}
};
ObjectValueMap*
WeakMapObject::getMap()
{
Data* data = getData();
return data ? &data->objectMap : nullptr;
}
SymbolValueMap*
WeakMapObject::getSymbolMap()
{
Data* data = getData();
return data ? &data->symbolMap : nullptr;
}
static bool
EnsureWeakMapData(JSContext* cx, Handle<WeakMapObject*> mapObj)
{
if (mapObj->getData())
return true;
auto data = cx->make_unique<WeakMapObject::Data>(cx, mapObj.get());
if (!data)
return false;
if (!data->init()) {
JS_ReportOutOfMemory(cx);
return false;
}
mapObj->setPrivate(data.release());
return true;
}
MOZ_ALWAYS_INLINE bool
WeakMap_has_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsWeakMap(args.thisv()));
if (!args.get(0).isObject()) {
if (!CanBeHeldWeakly(args.get(0))) {
args.rval().setBoolean(false);
return true;
}
if (ObjectValueMap* map = args.thisv().toObject().as<WeakMapObject>().getMap()) {
JSObject* key = &args[0].toObject();
if (map->has(key)) {
args.rval().setBoolean(true);
return true;
WeakMapObject& weakMap = args.thisv().toObject().as<WeakMapObject>();
if (args.get(0).isObject()) {
if (ObjectValueMap* map = weakMap.getMap()) {
JSObject* key = &args[0].toObject();
if (map->has(key)) {
args.rval().setBoolean(true);
return true;
}
}
} else {
if (SymbolValueMap* map = weakMap.getSymbolMap()) {
JS::Symbol* key = args[0].toSymbol();
if (map->has(key)) {
args.rval().setBoolean(true);
return true;
}
}
}
@@ -55,16 +115,27 @@ WeakMap_get_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsWeakMap(args.thisv()));
if (!args.get(0).isObject()) {
if (!CanBeHeldWeakly(args.get(0))) {
args.rval().setUndefined();
return true;
}
if (ObjectValueMap* map = args.thisv().toObject().as<WeakMapObject>().getMap()) {
JSObject* key = &args[0].toObject();
if (ObjectValueMap::Ptr ptr = map->lookup(key)) {
args.rval().set(ptr->value());
return true;
WeakMapObject& weakMap = args.thisv().toObject().as<WeakMapObject>();
if (args.get(0).isObject()) {
if (ObjectValueMap* map = weakMap.getMap()) {
JSObject* key = &args[0].toObject();
if (ObjectValueMap::Ptr ptr = map->lookup(key)) {
args.rval().set(ptr->value());
return true;
}
}
} else {
if (SymbolValueMap* map = weakMap.getSymbolMap()) {
JS::Symbol* key = args[0].toSymbol();
if (SymbolValueMap::Ptr ptr = map->lookup(key)) {
args.rval().set(ptr->value());
return true;
}
}
}
@@ -84,17 +155,29 @@ WeakMap_delete_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsWeakMap(args.thisv()));
if (!args.get(0).isObject()) {
if (!CanBeHeldWeakly(args.get(0))) {
args.rval().setBoolean(false);
return true;
}
if (ObjectValueMap* map = args.thisv().toObject().as<WeakMapObject>().getMap()) {
JSObject* key = &args[0].toObject();
if (ObjectValueMap::Ptr ptr = map->lookup(key)) {
map->remove(ptr);
args.rval().setBoolean(true);
return true;
WeakMapObject& weakMap = args.thisv().toObject().as<WeakMapObject>();
if (args.get(0).isObject()) {
if (ObjectValueMap* map = weakMap.getMap()) {
JSObject* key = &args[0].toObject();
if (ObjectValueMap::Ptr ptr = map->lookup(key)) {
map->remove(ptr);
args.rval().setBoolean(true);
return true;
}
}
} else {
if (SymbolValueMap* map = weakMap.getSymbolMap()) {
JS::Symbol* key = args[0].toSymbol();
if (SymbolValueMap::Ptr ptr = map->lookup(key)) {
map->remove(ptr);
args.rval().setBoolean(true);
return true;
}
}
}
@@ -126,22 +209,13 @@ TryPreserveReflector(JSContext* cx, HandleObject obj)
return true;
}
static MOZ_ALWAYS_INLINE bool
SetWeakMapEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj,
HandleObject key, HandleValue value)
static bool
SetWeakMapObjectEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj,
HandleObject key, HandleValue value)
{
if (!EnsureWeakMapData(cx, mapObj))
return false;
ObjectValueMap* map = mapObj->getMap();
if (!map) {
auto newMap = cx->make_unique<ObjectValueMap>(cx, mapObj.get());
if (!newMap)
return false;
if (!newMap->init()) {
JS_ReportOutOfMemory(cx);
return false;
}
map = newMap.release();
mapObj->setPrivate(map);
}
// Preserve wrapped native keys to prevent wrapper optimization.
if (!TryPreserveReflector(cx, key))
@@ -162,13 +236,28 @@ SetWeakMapEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj,
return true;
}
MOZ_ALWAYS_INLINE bool
WeakMap_set_impl(JSContext* cx, const CallArgs& args)
static bool
SetWeakMapSymbolEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj,
Handle<JS::Symbol*> key, HandleValue value)
{
MOZ_ASSERT(IsWeakMap(args.thisv()));
if (!EnsureWeakMapData(cx, mapObj))
return false;
SymbolValueMap* map = mapObj->getSymbolMap();
if (!args.get(0).isObject()) {
UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, args.get(0), nullptr);
MOZ_ASSERT_IF(value.isObject(), value.toObject().compartment() == mapObj->compartment());
if (!map->put(key, value)) {
JS_ReportOutOfMemory(cx);
return false;
}
return true;
}
static MOZ_ALWAYS_INLINE bool
SetWeakMapEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj,
HandleValue key, HandleValue value)
{
if (!CanBeHeldWeakly(key)) {
UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, key, nullptr);
if (!bytes)
return false;
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
@@ -176,11 +265,24 @@ WeakMap_set_impl(JSContext* cx, const CallArgs& args)
return false;
}
RootedObject key(cx, &args[0].toObject());
if (key.isObject()) {
RootedObject objectKey(cx, &key.toObject());
return SetWeakMapObjectEntryInternal(cx, mapObj, objectKey, value);
}
Rooted<JS::Symbol*> symbolKey(cx, key.toSymbol());
return SetWeakMapSymbolEntryInternal(cx, mapObj, symbolKey, value);
}
MOZ_ALWAYS_INLINE bool
WeakMap_set_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsWeakMap(args.thisv()));
Rooted<JSObject*> thisObj(cx, &args.thisv().toObject());
Rooted<WeakMapObject*> map(cx, &thisObj->as<WeakMapObject>());
if (!SetWeakMapEntryInternal(cx, map, key, args.get(1)))
if (!SetWeakMapEntryInternal(cx, map, args.get(0), args.get(1)))
return false;
args.rval().set(args.thisv());
return true;
@@ -193,6 +295,13 @@ js::WeakMap_set(JSContext* cx, unsigned argc, Value* vp)
return CallNonGenericMethod<IsWeakMap, WeakMap_set_impl>(cx, args);
}
bool
js::SetWeakMapEntryValue(JSContext* cx, HandleObject mapObj, HandleValue key, HandleValue val)
{
Rooted<WeakMapObject*> rootedMap(cx, &mapObj->as<WeakMapObject>());
return SetWeakMapEntryInternal(cx, rootedMap, key, val);
}
JS_FRIEND_API(bool)
JS_NondeterministicGetWeakMapKeys(JSContext* cx, HandleObject objArg, MutableHandleObject ret)
{
@@ -205,11 +314,11 @@ JS_NondeterministicGetWeakMapKeys(JSContext* cx, HandleObject objArg, MutableHan
RootedObject arr(cx, NewDenseEmptyArray(cx));
if (!arr)
return false;
ObjectValueMap* map = obj->as<WeakMapObject>().getMap();
if (map) {
WeakMapObject::Data* data = obj->as<WeakMapObject>().getData();
if (data) {
// Prevent GC from mutating the weakmap while iterating.
AutoSuppressGC suppress(cx);
for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) {
for (ObjectValueMap::Base::Range r = data->objectMap.all(); !r.empty(); r.popFront()) {
JS::ExposeObjectToActiveJS(r.front().key());
RootedObject key(cx, r.front().key());
if (!cx->compartment()->wrap(cx, &key))
@@ -217,6 +326,14 @@ JS_NondeterministicGetWeakMapKeys(JSContext* cx, HandleObject objArg, MutableHan
if (!NewbornArrayPush(cx, arr, ObjectValue(*key)))
return false;
}
for (SymbolValueMap::Base::Range r = data->symbolMap.all(); !r.empty(); r.popFront()) {
gc::ExposeGCThingToActiveJS(JS::GCCellPtr(r.front().key().get()));
RootedValue key(cx, SymbolValue(r.front().key()));
if (!cx->compartment()->wrap(cx, &key))
return false;
if (!NewbornArrayPush(cx, arr, key))
return false;
}
}
ret.set(arr);
return true;
@@ -225,21 +342,23 @@ JS_NondeterministicGetWeakMapKeys(JSContext* cx, HandleObject objArg, MutableHan
static void
WeakMap_mark(JSTracer* trc, JSObject* obj)
{
if (ObjectValueMap* map = obj->as<WeakMapObject>().getMap())
map->trace(trc);
if (WeakMapObject::Data* data = obj->as<WeakMapObject>().getData()) {
data->objectMap.trace(trc);
data->symbolMap.trace(trc);
}
}
static void
WeakMap_finalize(FreeOp* fop, JSObject* obj)
{
MOZ_ASSERT(fop->maybeOffMainThread());
if (ObjectValueMap* map = obj->as<WeakMapObject>().getMap()) {
if (WeakMapObject::Data* data = obj->as<WeakMapObject>().getData()) {
#ifdef DEBUG
map->~ObjectValueMap();
memset(static_cast<void*>(map), 0xdc, sizeof(*map));
fop->free_(map);
data->~Data();
memset(static_cast<void*>(data), 0xdc, sizeof(*data));
fop->free_(data);
#else
fop->delete_(map);
fop->delete_(data);
#endif
}
}
@@ -282,7 +401,8 @@ JS::SetWeakMapEntry(JSContext* cx, HandleObject mapObj, HandleObject key,
CHECK_REQUEST(cx);
assertSameCompartment(cx, key, val);
Rooted<WeakMapObject*> rootedMap(cx, &mapObj->as<WeakMapObject>());
return SetWeakMapEntryInternal(cx, rootedMap, key, val);
RootedValue keyValue(cx, ObjectValue(*key));
return SetWeakMapEntryInternal(cx, rootedMap, keyValue, val);
}
static bool
@@ -386,4 +506,3 @@ js::InitBareWeakMapCtor(JSContext* cx, HandleObject obj)
{
return InitWeakMapClass(cx, obj, false);
}
+5 -1
View File
@@ -16,7 +16,11 @@ class WeakMapObject : public NativeObject
public:
static const Class class_;
ObjectValueMap* getMap() { return static_cast<ObjectValueMap*>(getPrivate()); }
struct Data;
Data* getData() { return static_cast<Data*>(getPrivate()); }
ObjectValueMap* getMap();
SymbolValueMap* getSymbolMap();
};
} // namespace js
+94 -28
View File
@@ -11,7 +11,9 @@
#include "gc/Nursery.h"
#include "gc/Tracer.h"
#include "vm/GlobalObject.h"
#include "vm/Symbol.h"
#include "jswrapper.h"
#include "jsobjinlines.h"
#include "vm/Interpreter-inl.h"
@@ -31,17 +33,64 @@ IsWeakRef(HandleValue v)
return v.isObject() && v.toObject().is<WeakRefObject>();
}
static bool
GetPrototypeFromWeakRefConstructor(JSContext* cx, HandleObject newTarget,
MutableHandleObject proto)
{
if (!GetPrototypeFromConstructor(cx, newTarget, proto))
return false;
if (proto)
return true;
RootedObject realmObject(cx, CheckedUnwrap(newTarget, /* stopAtWindowProxy = */ false));
if (!realmObject)
return false;
{
JSAutoCompartment ac(cx, realmObject);
Rooted<GlobalObject*> global(cx, &realmObject->global());
if (!GlobalObject::ensureConstructor(cx, global, JSProto_WeakRef))
return false;
proto.set(&global->getPrototype(JSProto_WeakRef).toObject());
}
return cx->compartment()->wrap(cx, proto);
}
static bool
WeakRef_deref_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsWeakRef(args.thisv()));
WeakRefObject::Referent* data = GetReferent(&args.thisv().toObject());
JSObject* target = data ? data->target.get() : nullptr;
if (target)
args.rval().setObject(*target);
else
if (!data) {
args.rval().setUndefined();
return true;
}
if (data->isObject()) {
JSObject* target = data->objectTarget.get();
if (target) {
RootedValue kept(cx, ObjectValue(*target));
if (!cx->runtime()->addWeakRefKeptObject(cx, kept))
return false;
args.rval().set(kept);
} else {
args.rval().setUndefined();
}
} else {
MOZ_ASSERT(data->isSymbol());
JS::Symbol* target = data->symbolTarget.get();
if (target) {
RootedValue kept(cx, SymbolValue(target));
if (!cx->runtime()->addWeakRefKeptObject(cx, kept))
return false;
args.rval().set(kept);
} else {
args.rval().setUndefined();
}
}
return true;
}
@@ -83,13 +132,18 @@ InitWeakRefClass(JSContext* cx, HandleObject obj, bool defineMembers)
}
/* static */ WeakRefObject*
WeakRefObject::create(JSContext* cx, HandleObject target, HandleObject proto /* = nullptr */)
WeakRefObject::create(JSContext* cx, HandleValue target, HandleObject proto /* = nullptr */)
{
Rooted<WeakRefObject*> obj(cx, NewObjectWithClassProto<WeakRefObject>(cx, proto));
if (!obj)
return nullptr;
Referent* data = cx->new_<Referent>(target, cx->options().weakRefs());
Referent* data;
if (target.isObject())
data = cx->new_<Referent>(&target.toObject());
else
data = cx->new_<Referent>(target.toSymbol());
if (!data)
return nullptr;
@@ -97,6 +151,18 @@ WeakRefObject::create(JSContext* cx, HandleObject target, HandleObject proto /*
return obj;
}
bool
js::CanBeHeldWeakly(HandleValue target)
{
if (target.isObject())
return true;
if (target.isSymbol())
return target.toSymbol()->code() != JS::SymbolCode::InSymbolRegistry;
return false;
}
/* static */ bool
WeakRefObject::construct(JSContext* cx, unsigned argc, Value* vp)
{
@@ -105,28 +171,25 @@ WeakRefObject::construct(JSContext* cx, unsigned argc, Value* vp)
if (!ThrowIfNotConstructing(cx, args, "WeakRef"))
return false;
if (!args.get(0).isObject()) {
UniqueChars bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, args.get(0), nullptr);
if (!bytes)
return false;
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
bytes.get());
if (!CanBeHeldWeakly(args.get(0))) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_WEAKREF_TARGET);
return false;
}
RootedObject target(cx, &args[0].toObject());
RootedValue target(cx, args[0]);
RootedObject proto(cx);
RootedObject newTarget(cx, &args.newTarget().toObject());
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
if (!GetPrototypeFromWeakRefConstructor(cx, newTarget, &proto))
return false;
Rooted<WeakRefObject*> obj(cx, WeakRefObject::create(cx, target, proto));
if (!obj)
return false;
if (!cx->runtime()->addWeakRefKeptObject(cx, target))
return false;
args.rval().setObject(*obj);
return true;
}
@@ -142,19 +205,23 @@ WeakRefObject::deref(JSContext* cx, unsigned argc, Value* vp)
WeakRefObject::trace(JSTracer* trc, JSObject* obj)
{
if (Referent* data = GetReferent(obj)) {
JSObject* target = data->target.unbarrieredGet();
if (!target)
return;
if (data->isObject()) {
JSObject* target = data->objectTarget.unbarrieredGet();
if (!target)
return;
// When pref-disabled, keep referent alive via strong trace so deref()
// stays usable as a stub without touching GC internals.
if (!data->enabled) {
TraceManuallyBarrieredEdge(trc, data->target.unsafeGet(), "WeakRef stub referent");
} else if (IsInsideNursery(target)) {
// Weak edges must be tenured; trace strongly while referent is in the nursery.
TraceManuallyBarrieredEdge(trc, data->target.unsafeGet(), "WeakRef nursery referent");
if (IsInsideNursery(target)) {
// Weak edges must be tenured; trace strongly while referent is in the nursery.
TraceManuallyBarrieredEdge(trc, data->objectTarget.unsafeGet(),
"WeakRef nursery referent");
} else {
TraceWeakEdge(trc, &data->objectTarget, "WeakRef referent");
}
} else {
TraceWeakEdge(trc, &data->target, "WeakRef referent");
MOZ_ASSERT(data->isSymbol());
JS::Symbol* target = data->symbolTarget.unbarrieredGet();
if (target)
TraceWeakEdge(trc, &data->symbolTarget, "WeakRef symbol referent");
}
}
}
@@ -162,7 +229,6 @@ WeakRefObject::trace(JSTracer* trc, JSObject* obj)
/* static */ void
WeakRefObject::finalize(FreeOp* fop, JSObject* obj)
{
MOZ_ASSERT(!fop->maybeOffMainThread());
if (Referent* data = GetReferent(obj))
fop->delete_(data);
}
+21 -6
View File
@@ -11,20 +11,34 @@
namespace js {
bool CanBeHeldWeakly(HandleValue target);
class WeakRefObject : public NativeObject
{
public:
struct Referent {
explicit Referent(JSObject* obj, bool enabled)
: target(obj), enabled(enabled) {}
WeakRef<JSObject*> target;
bool enabled;
enum class Kind {
Object,
Symbol
};
explicit Referent(JSObject* obj)
: kind(Kind::Object), objectTarget(obj), symbolTarget(nullptr) {}
explicit Referent(JS::Symbol* sym)
: kind(Kind::Symbol), objectTarget(nullptr), symbolTarget(sym) {}
bool isObject() const { return kind == Kind::Object; }
bool isSymbol() const { return kind == Kind::Symbol; }
Kind kind;
WeakRef<JSObject*> objectTarget;
WeakRef<JS::Symbol*> symbolTarget;
};
static const Class class_;
static JSObject* initClass(JSContext* cx, HandleObject obj);
static WeakRefObject* create(JSContext* cx, HandleObject target, HandleObject proto = nullptr);
static WeakRefObject* create(JSContext* cx, HandleValue target, HandleObject proto = nullptr);
static void trace(JSTracer* trc, JSObject* obj);
static void finalize(FreeOp* fop, JSObject* obj);
@@ -37,7 +51,8 @@ class WeakRefObject : public NativeObject
WeakRef<JSObject*>& target() {
MOZ_ASSERT(getData());
return getData()->target;
MOZ_ASSERT(getData()->isObject());
return getData()->objectTarget;
}
static const JSPropertySpec properties[];
+3 -3
View File
@@ -32,7 +32,7 @@ function WeakSet_add(value) {
ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S);
// Step 5.
if (!IsObject(value))
if (!CanBeHeldWeakly(value))
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, DecompileArg(0, value));
// Steps 7-8.
@@ -55,7 +55,7 @@ function WeakSet_delete(value) {
ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S);
// Step 5.
if (!IsObject(value))
if (!CanBeHeldWeakly(value))
return false;
// Steps 7-8.
@@ -75,7 +75,7 @@ function WeakSet_has(value) {
ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S);
// Step 6.
if (!IsObject(value))
if (!CanBeHeldWeakly(value))
return false;
// Steps 7-8.
+3 -4
View File
@@ -12,6 +12,7 @@
#include "builtin/MapObject.h"
#include "builtin/SelfHostingDefines.h"
#include "builtin/WeakMapObject.h"
#include "builtin/WeakRefObject.h"
#include "vm/GlobalObject.h"
#include "vm/SelfHosting.h"
@@ -108,7 +109,6 @@ WeakSetObject::construct(JSContext* cx, unsigned argc, Value* vp)
if (optimized) {
RootedValue keyVal(cx);
RootedObject keyObject(cx);
RootedValue placeholder(cx, BooleanValue(true));
RootedObject map(cx, &obj->getReservedSlot(WEAKSET_MAP_SLOT).toObject());
RootedArrayObject array(cx, &iterable.toObject().as<ArrayObject>());
@@ -116,7 +116,7 @@ WeakSetObject::construct(JSContext* cx, unsigned argc, Value* vp)
keyVal.set(array->getDenseElement(index));
MOZ_ASSERT(!keyVal.isMagic(JS_ELEMENTS_HOLE));
if (keyVal.isPrimitive()) {
if (!CanBeHeldWeakly(keyVal)) {
UniqueChars bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, keyVal, nullptr);
if (!bytes)
@@ -126,8 +126,7 @@ WeakSetObject::construct(JSContext* cx, unsigned argc, Value* vp)
return false;
}
keyObject = &keyVal.toObject();
if (!SetWeakMapEntry(cx, map, keyObject, placeholder))
if (!SetWeakMapEntryValue(cx, map, keyVal, placeholder))
return false;
}
} else {
+4 -1
View File
@@ -939,6 +939,8 @@ class GCRuntime
IncrementalProgress drainMarkStack(SliceBudget& sliceBudget, gcstats::Phase phase);
template <class CompartmentIterT> void markWeakReferences(gcstats::Phase phase);
void markWeakReferencesInCurrentGroup(gcstats::Phase phase);
template <class ZoneIterT> void traceFinalizationRegistryWeakRefs();
void traceFinalizationRegistryWeakRefsInCurrentGroup();
template <class ZoneIterT, class CompartmentIterT> void markGrayReferences(gcstats::Phase phase);
void markBufferedGrayRoots(JS::Zone* zone);
void markGrayReferencesInCurrentGroup(gcstats::Phase phase);
@@ -951,6 +953,7 @@ class GCRuntime
void getNextZoneGroup();
void endMarkingZoneGroup();
void beginSweepingZoneGroup(AutoLockForExclusiveAccess& lock);
void sweepFinalizationRegistries();
bool shouldReleaseObservedTypes();
void endSweepingZoneGroup();
IncrementalProgress performSweepActions(SliceBudget& sliceBudget, AutoLockForExclusiveAccess& lock);
@@ -977,7 +980,7 @@ class GCRuntime
void sweepTypesAfterCompacting(Zone* zone);
void sweepZoneAfterCompacting(Zone* zone);
[[nodiscard]] bool relocateArenas(Zone* zone, JS::gcreason::Reason reason,
Arena*& relocatedListOut, SliceBudget& sliceBudget);
Arena*& relocatedListOut, SliceBudget& sliceBudget);
void updateTypeDescrObjects(MovingTracer* trc, Zone* zone);
void updateCellPointers(MovingTracer* trc, Zone* zone, AllocKinds kinds, size_t bgTaskCount);
void updateAllCellPointers(MovingTracer* trc, Zone* zone);
+5
View File
@@ -12,6 +12,7 @@
#include "jscntxt.h"
#include "ds/SplayTree.h"
#include "gc/Barrier.h"
#include "gc/FindSCCs.h"
#include "gc/GCRuntime.h"
#include "js/GCHashTable.h"
@@ -325,6 +326,10 @@ struct Zone : public JS::shadow::Zone,
using WeakEdges = js::Vector<js::gc::TenuredCell**, 0, js::SystemAllocPolicy>;
WeakEdges gcWeakRefs;
// FinalizationRegistry objects with weakly-held target cells in this zone.
using FinalizationRegistryVector = js::Vector<js::WeakRef<JSObject*>, 0, js::SystemAllocPolicy>;
FinalizationRegistryVector finalizationRegistries;
// List of non-ephemeron weak containers to sweep during beginSweepingZoneGroup.
mozilla::LinkedList<WeakCache<void*>> weakCaches_;
void registerWeakCache(WeakCache<void*>* cachep) {
@@ -1,4 +1,3 @@
// |jit-test| --ion-sink=on
// Sink Algorithm should not move instruction into merge blocks
// which have no corresponding pc.
+13
View File
@@ -1470,6 +1470,12 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_
res.isNumber() &&
!TypedArrayGetElemStubExists(stub, obj))
{
if (obj->is<TypedArrayObject>() &&
obj->as<TypedArrayObject>().hasResizableOrGrowableBuffer())
{
return true;
}
if (!cx->runtime()->jitSupportsFloatingPoint &&
(TypedThingRequiresFloatingPoint(obj) || rhs.isDouble()))
{
@@ -2160,6 +2166,8 @@ ICGetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm)
Register obj = masm.extractObject(R0, ExtractTemp0);
masm.loadPtr(Address(ICStubReg, ICGetElem_TypedArray::offsetOfShape()), scratchReg);
masm.branchTestObjShape(Assembler::NotEqual, obj, scratchReg, &failure);
if (layout_ == Layout_TypedArray)
GuardResizableOrGrowableTypedArray(masm, obj, scratchReg, &failure);
// Ensure the index is an integer.
if (cx->runtime()->jitSupportsFloatingPoint) {
@@ -2631,6 +2639,9 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
bool expectOutOfBounds;
double idx = index.toNumber();
if (obj->is<TypedArrayObject>()) {
if (obj->as<TypedArrayObject>().hasResizableOrGrowableBuffer())
return true;
expectOutOfBounds = (idx < 0 || idx >= double(obj->as<TypedArrayObject>().length()));
} else {
// Typed objects throw on out of bounds accesses. Don't attach
@@ -3221,6 +3232,8 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm)
Register obj = masm.extractObject(R0, ExtractTemp0);
masm.loadPtr(Address(ICStubReg, ICSetElem_TypedArray::offsetOfShape()), scratchReg);
masm.branchTestObjShape(Assembler::NotEqual, obj, scratchReg, &failure);
if (layout_ == Layout_TypedArray)
GuardResizableOrGrowableTypedArray(masm, obj, scratchReg, &failure);
// Ensure the index is an integer.
if (cx->runtime()->jitSupportsFloatingPoint) {
Loaded 100 of 739 files, more files were not shown because too many files have changed in this diff. Show more