Compare commits

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

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

---

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

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

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

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

MI_DEFAULT_GENERIC_COLLECT=50000 - lower background allocator housekeeping overhead on hot allocation paths.
2026-03-10 09:08:14 -04:00
Moonchild 77f8cae06e Issue #2978 - Avoid empty replacements in macro expansion.
If the replacements array is empty, don't attempt to do any work on the
existing macro, and return. This should prevent infinite recursion in
some cases.
Order matters here: we're relying on the `if` statement shortcut so
`collectMacroArgs()` doesn't get called.
2026-03-09 16:04:57 +01:00
86 changed files with 4655 additions and 3638 deletions

No files matched your search

+1 -1
View File
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber for ICU 78.1
Clobber for libvpx changes
-1
View File
@@ -127,7 +127,6 @@ def old_configure_options(*options):
'--enable-alsa',
'--enable-appcompat-guid',
'--enable-av1',
'--enable-jxl',
'--enable-b2g-bt',
'--enable-b2g-camera',
'--enable-b2g-ril',
+1
View File
@@ -16,6 +16,7 @@
#include "mozilla/CORSMode.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/HTMLEditor.h"
#include "mozilla/InternalMutationEvent.h"
#include "mozilla/Likely.h"
#include "mozilla/MemoryReporting.h"
+76 -14
View File
@@ -9,6 +9,7 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsPrintfCString.h"
#include "WebGLActiveInfo.h"
#include "WebGLBuffer.h"
#include "WebGLContextUtils.h"
#include "WebGLFramebuffer.h"
@@ -27,6 +28,30 @@ namespace mozilla {
// For a Tegra workaround.
static const int MAX_DRAW_CALLS_SINCE_FLUSH = 100;
static uint8_t
NumUsedLocationsByElemTypeForDraw(GLenum elemType)
{
switch (elemType) {
case LOCAL_GL_FLOAT_MAT2:
case LOCAL_GL_FLOAT_MAT2x3:
case LOCAL_GL_FLOAT_MAT2x4:
return 2;
case LOCAL_GL_FLOAT_MAT3x2:
case LOCAL_GL_FLOAT_MAT3:
case LOCAL_GL_FLOAT_MAT3x4:
return 3;
case LOCAL_GL_FLOAT_MAT4x2:
case LOCAL_GL_FLOAT_MAT4x3:
case LOCAL_GL_FLOAT_MAT4:
return 4;
default:
return 1;
}
}
////////////////////////////////////////
class ScopedResolveTexturesForDraw
@@ -331,6 +356,7 @@ class ScopedDrawHelper final
{
WebGLContext* const mWebGL;
bool mDidFake;
std::vector<GLuint> mDisabledUnusedAttribs;
public:
ScopedDrawHelper(WebGLContext* webgl, const char* funcName, uint32_t firstVertex,
@@ -367,11 +393,43 @@ public:
}
mDidFake = true;
const auto& linkInfo = mWebGL->mActiveProgramLinkInfo;
#ifdef XP_MACOSX
if (mWebGL->gl->WorkAroundDriverBugs()) {
std::vector<bool> isActiveAttrib(mWebGL->mBoundVertexArray->mAttribs.Length(),
false);
for (const auto& progAttrib : linkInfo->attribs) {
const auto loc = progAttrib.mLoc;
if (loc < 0) {
continue;
}
const auto usedLocs =
NumUsedLocationsByElemTypeForDraw(progAttrib.mActiveInfo->mElemType);
for (uint32_t i = 0; i < usedLocs; ++i) {
const auto usedLoc = static_cast<uint32_t>(loc) + i;
if (usedLoc < isActiveAttrib.size()) {
isActiveAttrib[usedLoc] = true;
}
}
}
for (uint32_t i = 0; i < mWebGL->mBoundVertexArray->mAttribs.Length(); ++i) {
const auto& attrib = mWebGL->mBoundVertexArray->mAttribs[i];
if (!attrib.mEnabled || isActiveAttrib[i]) {
continue;
}
mWebGL->gl->fDisableVertexAttribArray(i);
mDisabledUnusedAttribs.push_back(i);
}
}
#endif
////
// Check UBO sizes.
const auto& linkInfo = mWebGL->mActiveProgramLinkInfo;
for (const auto& cur : linkInfo->uniformBlocks) {
const auto& dataSize = cur->mDataSize;
const auto& binding = cur->mBinding;
@@ -477,6 +535,10 @@ public:
if (mDidFake) {
mWebGL->UndoFakeVertexAttrib0();
}
for (const auto loc : mDisabledUnusedAttribs) {
mWebGL->gl->fEnableVertexAttribArray(loc);
}
}
};
@@ -607,12 +669,12 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
return;
MakeContextCurrent();
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
bool error = false;
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
@@ -855,12 +917,12 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type,
return;
MakeContextCurrent();
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
if (vertCount > mMaxVertIdsPerDraw) {
ErrorOutOfMemory(
"Context's max vertCount is %u, but %u requested. [webgl.max-vert-ids-per-draw]", mMaxVertIdsPerDraw, vertCount);
return;
}
bool error = false;
ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
+7 -12
View File
@@ -613,14 +613,6 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest)
nsresult rv;
{
// Update our current script.
Maybe<AutoCurrentScriptUpdater> masterScriptUpdater;
nsCOMPtr<nsIDocument> master = mDocument->MasterDocument();
if (master != mDocument) {
masterScriptUpdater.emplace(master->ScriptLoader(),
aRequest->Element());
}
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> module(cx);
@@ -2323,8 +2315,14 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
return NS_ERROR_FAILURE;
}
// Update our current script.
// This must be destroyed after destroying nsAutoMicroTask.
nsIScriptElement* currentScript =
aRequest->IsModuleRequest() ? nullptr : aRequest->Element();
AutoCurrentScriptUpdater scriptUpdater(this, currentScript);
// New script entry point required, due to the "Create a script" sub-step of
// http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block
// http://html.spec.whatwg.org/multipage/#execute-the-script-block
nsAutoMicroTask mt;
AutoEntryScript aes(globalObject, "<script> element", true);
JSContext* cx = aes.cx();
@@ -2382,9 +2380,6 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
FinishDynamicImport(cx, request, rv);
}
} else {
// Update our current script.
AutoCurrentScriptUpdater scriptUpdater(this, aRequest->Element());
JS::CompileOptions options(cx);
rv = FillCompileOptionsForRequest(aes, aRequest, global, &options);
+3 -1
View File
@@ -324,7 +324,9 @@ class ScriptLoader final : public nsISupports
: mOldScript(aScriptLoader->mCurrentScript)
, mScriptLoader(aScriptLoader)
{
mScriptLoader->mCurrentScript = aCurrentScript;
nsCOMPtr<nsINode> node = do_QueryInterface(aCurrentScript);
mScriptLoader->mCurrentScript =
node && !node->IsInShadowTree() ? aCurrentScript : nullptr;
}
~AutoCurrentScriptUpdater()
{
+85 -23
View File
@@ -57,7 +57,84 @@ CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
CopyASCIItoUTF16(url, aResult);
}
// The URL implementation for the main-thread
bool
IsRootRelativePathInput(const nsAString& aURL)
{
return !aURL.IsEmpty() && aURL.CharAt(0) == '/' &&
(aURL.Length() == 1 || aURL.CharAt(1) != '/');
}
bool
BuildRootRelativeFallbackSpec(const nsAString& aURL, nsIURI* aBase,
nsACString& aFallbackSpec)
{
MOZ_ASSERT(aBase);
MOZ_ASSERT(IsRootRelativePathInput(aURL));
nsAutoCString baseSpec;
if (NS_FAILED(aBase->GetSpec(baseSpec)) || baseSpec.IsEmpty()) {
return false;
}
int32_t colon = baseSpec.FindChar(':');
if (colon <= 0) {
return false;
}
uint32_t afterColon = static_cast<uint32_t>(colon + 1);
if (afterColon >= baseSpec.Length() || baseSpec.CharAt(afterColon) != '/') {
// Opaque paths (for example mailto:test@example.com) are not valid bases
// for root-relative URL input.
return false;
}
nsAutoCString input;
if (!AppendUTF16toUTF8(aURL, input, fallible)) {
return false;
}
// Preserve authority when present (scheme://authority/path -> scheme://authority/input)
if (afterColon + 1 < baseSpec.Length() && baseSpec.CharAt(afterColon + 1) == '/') {
uint32_t authorityEnd = afterColon + 2;
while (authorityEnd < baseSpec.Length()) {
char c = baseSpec.CharAt(authorityEnd);
if (c == '/' || c == '?' || c == '#') {
break;
}
++authorityEnd;
}
aFallbackSpec.Assign(Substring(baseSpec, 0, authorityEnd));
aFallbackSpec.Append(input);
return true;
}
// Single-slash hierarchical base (scheme:/path -> scheme:/input)
aFallbackSpec.Assign(Substring(baseSpec, 0, afterColon));
aFallbackSpec.Append(input);
return true;
}
bool
TryResolveRootRelativeAgainstBase(const nsAString& aURL, nsIURI* aBase,
nsIURI** aOutURI)
{
MOZ_ASSERT(aOutURI);
if (!aBase || !IsRootRelativePathInput(aURL)) {
return false;
}
nsAutoCString fallbackSpec;
if (!BuildRootRelativeFallbackSpec(aURL, aBase, fallbackSpec)) {
return false;
}
nsresult rv = NS_NewURI(aOutURI, fallbackSpec, nullptr, nullptr,
nsContentUtils::GetIOService());
return NS_SUCCEEDED(rv);
}
class URLMainThread final : public URL
{
public:
@@ -229,7 +306,8 @@ URLMainThread::Constructor(nsISupports* aParent, const nsAString& aURL,
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, nullptr, aBase,
nsContentUtils::GetIOService());
if (NS_FAILED(rv)) {
if (NS_FAILED(rv) &&
!TryResolveRootRelativeAgainstBase(aURL, aBase, getter_AddRefs(uri))) {
// No need to warn in this case. It's common to use the URL constructor
// to determine if a URL is valid and an exception will be propagated.
aRv.ThrowTypeError<MSG_INVALID_URL>(aURL);
@@ -1714,30 +1792,14 @@ URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase) {
nsCOMPtr<nsIURI> baseUri;
if (aBase.WasPassed()) {
// Don't use NS_ConvertUTF16toUTF8 because that doesn't let us handle OOM.
nsAutoCString base;
if (!AppendUTF16toUTF8(aBase.Value(), base, fallible)) {
// Just return false with OOM errors as no ErrorResult.
return false;
}
nsresult rv = NS_NewURI(getter_AddRefs(baseUri), base);
if (NS_FAILED(rv)) {
// Invalid base URL, return false.
return false;
}
}
nsAutoCString urlStr;
if (!AppendUTF16toUTF8(aURL, urlStr, fallible)) {
// Just return false with OOM errors as no ErrorResult.
ErrorResult rv;
RefPtr<URL> parsed = URL::Constructor(aGlobal, aURL, aBase, rv);
if (rv.Failed() || !parsed) {
rv.SuppressException();
return false;
}
nsCOMPtr<nsIURI> uri;
return NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), urlStr, nullptr, baseUri));
return true;
}
URLSearchParams*
+414 -412
View File
@@ -1,460 +1,462 @@
<!DOCTYPE HTML>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test URL API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=887364">Mozilla Bug 887364</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=991471">Mozilla Bug 991471</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=996055">Mozilla Bug 996055</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe name="x" id="x"></iframe>
<iframe name="y" id="y"></iframe>
</div>
<pre id="test">
</pre>
<script type="application/javascript">
<head>
<meta charset="utf-8" />
<title>Test URL API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=887364">Mozilla Bug 887364</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=991471">Mozilla Bug 991471</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=996055">Mozilla Bug 996055</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe name="x" id="x"></iframe>
<iframe name="y" id="y"></iframe>
</div>
<pre id="test"></pre>
<script type="application/javascript">
/** Test for Bug 887364 **/
ok("URL" in window, "window.URL exists");
/** Test for Bug 887364 **/
ok("URL" in window, "window.URL exists");
var tests = [
{
url: "http://www.abc.com",
base: undefined,
error: false,
href: "http://www.abc.com/",
origin: "http://www.abc.com",
protocol: "http:",
username: "",
password: "",
host: "www.abc.com",
hostname: "www.abc.com",
port: "",
pathname: "/",
search: "",
hash: "",
},
{
url: "ftp://auser:apw@www.abc.com",
base: undefined,
error: false,
href: "ftp://auser:apw@www.abc.com/",
origin: "ftp://www.abc.com",
protocol: "ftp:",
username: "auser",
password: "apw",
host: "www.abc.com",
hostname: "www.abc.com",
port: "",
pathname: "/",
search: "",
hash: "",
},
{
url: "http://www.abc.com:90/apath/",
base: undefined,
error: false,
href: "http://www.abc.com:90/apath/",
origin: "http://www.abc.com:90",
protocol: "http:",
username: "",
password: "",
host: "www.abc.com:90",
hostname: "www.abc.com",
port: "90",
pathname: "/apath/",
search: "",
hash: "",
},
{
url: "http://www.abc.com/apath/afile.txt#ahash",
base: undefined,
error: false,
href: "http://www.abc.com/apath/afile.txt#ahash",
origin: "http://www.abc.com",
protocol: "http:",
username: "",
password: "",
host: "www.abc.com",
hostname: "www.abc.com",
port: "",
pathname: "/apath/afile.txt",
search: "",
hash: "#ahash",
},
{
url: "http://example.com/?test#hash",
base: undefined,
error: false,
href: "http://example.com/?test#hash",
origin: "http://example.com",
protocol: "http:",
username: "",
password: "",
host: "example.com",
hostname: "example.com",
port: "",
pathname: "/",
search: "?test",
hash: "#hash",
},
{
url: "http://example.com/?test",
base: undefined,
error: false,
href: "http://example.com/?test",
origin: "http://example.com",
protocol: "http:",
username: "",
password: "",
host: "example.com",
hostname: "example.com",
port: "",
pathname: "/",
search: "?test",
hash: "",
},
{ url: "http://example.com/carrot#question%3f", base: undefined, error: false, hash: "#question%3f" },
{
url: "https://example.com:4443?",
base: undefined,
error: false,
protocol: "https:",
port: "4443",
pathname: "/",
hash: "",
search: "",
},
{
url: "http://www.abc.com/apath/afile.txt#ahash?asearch",
base: undefined,
error: false,
href: "http://www.abc.com/apath/afile.txt#ahash?asearch",
protocol: "http:",
pathname: "/apath/afile.txt",
hash: "#ahash?asearch",
search: "",
},
{
url: "http://www.abc.com/apath/afile.txt?asearch#ahash",
base: undefined,
error: false,
href: "http://www.abc.com/apath/afile.txt?asearch#ahash",
protocol: "http:",
pathname: "/apath/afile.txt",
hash: "#ahash",
search: "?asearch",
},
{
url: "http://abc.com/apath/afile.txt?#ahash",
base: undefined,
error: false,
pathname: "/apath/afile.txt",
hash: "#ahash",
search: "",
},
{
url: "http://auser:apassword@www.abc.com:90/apath/afile.txt?asearch#ahash",
base: undefined,
error: false,
protocol: "http:",
username: "auser",
password: "apassword",
host: "www.abc.com:90",
hostname: "www.abc.com",
port: "90",
pathname: "/apath/afile.txt",
hash: "#ahash",
search: "?asearch",
origin: "http://www.abc.com:90",
},
var tests = [
{ url: 'http://www.abc.com',
base: undefined,
error: false,
href: 'http://www.abc.com/',
origin: 'http://www.abc.com',
protocol: 'http:',
username: '',
password: '',
host: 'www.abc.com',
hostname: 'www.abc.com',
port: '',
pathname: '/',
search: '',
hash: ''
},
{ url: 'ftp://auser:apw@www.abc.com',
base: undefined,
error: false,
href: 'ftp://auser:apw@www.abc.com/',
origin: 'ftp://www.abc.com',
protocol: 'ftp:',
username: 'auser',
password: 'apw',
host: 'www.abc.com',
hostname: 'www.abc.com',
port: '',
pathname: '/',
search: '',
hash: ''
},
{ url: 'http://www.abc.com:90/apath/',
base: undefined,
error: false,
href: 'http://www.abc.com:90/apath/',
origin: 'http://www.abc.com:90',
protocol: 'http:',
username: '',
password: '',
host: 'www.abc.com:90',
hostname: 'www.abc.com',
port: '90',
pathname: '/apath/',
search: '',
hash: ''
},
{ url: 'http://www.abc.com/apath/afile.txt#ahash',
base: undefined,
error: false,
href: 'http://www.abc.com/apath/afile.txt#ahash',
origin: 'http://www.abc.com',
protocol: 'http:',
username: '',
password: '',
host: 'www.abc.com',
hostname: 'www.abc.com',
port: '',
pathname: '/apath/afile.txt',
search: '',
hash: '#ahash'
},
{ url: 'http://example.com/?test#hash',
base: undefined,
error: false,
href: 'http://example.com/?test#hash',
origin: 'http://example.com',
protocol: 'http:',
username: '',
password: '',
host: 'example.com',
hostname: 'example.com',
port: '',
pathname: '/',
search: '?test',
hash: '#hash'
},
{ url: 'http://example.com/?test',
base: undefined,
error: false,
href: 'http://example.com/?test',
origin: 'http://example.com',
protocol: 'http:',
username: '',
password: '',
host: 'example.com',
hostname: 'example.com',
port: '',
pathname: '/',
search: '?test',
hash: ''
},
{ url: 'http://example.com/carrot#question%3f',
base: undefined,
error: false,
hash: '#question%3f'
},
{ url: 'https://example.com:4443?',
base: undefined,
error: false,
protocol: 'https:',
port: '4443',
pathname: '/',
hash: '',
search: ''
},
{ url: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
base: undefined,
error: false,
href: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
protocol: 'http:',
pathname: '/apath/afile.txt',
hash: '#ahash?asearch',
search: ''
},
{ url: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
base: undefined,
error: false,
href: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
protocol: 'http:',
pathname: '/apath/afile.txt',
hash: '#ahash',
search: '?asearch'
},
{ url: 'http://abc.com/apath/afile.txt?#ahash',
base: undefined,
error: false,
pathname: '/apath/afile.txt',
hash: '#ahash',
search: ''
},
{ url: 'http://auser:apassword@www.abc.com:90/apath/afile.txt?asearch#ahash',
base: undefined,
error: false,
protocol: 'http:',
username: 'auser',
password: 'apassword',
host: 'www.abc.com:90',
hostname: 'www.abc.com',
port: '90',
pathname: '/apath/afile.txt',
hash: '#ahash',
search: '?asearch',
origin: 'http://www.abc.com:90'
},
{ url: "/foo#bar", base: "www.test.org", error: true },
{ url: "/foo#bar", base: null, error: true },
{ url: "/foo#bar", base: 42, error: true },
{ url: "ftp://ftp.something.net", base: undefined, error: false, protocol: "ftp:" },
{ url: "file:///tmp/file", base: undefined, error: false, protocol: "file:" },
{ url: "gopher://gopher.something.net", base: undefined, error: false, protocol: "gopher:" },
{ url: "ws://ws.something.net", base: undefined, error: false, protocol: "ws:" },
{ url: "wss://ws.something.net", base: undefined, error: false, protocol: "wss:" },
{ url: "foo://foo.something.net", base: undefined, error: false, protocol: "foo:" },
{ url: '/foo#bar',
base: 'www.test.org',
error: true,
},
{ url: '/foo#bar',
base: null,
error: true,
},
{ url: '/foo#bar',
base: 42,
error: true,
},
{ url: 'ftp://ftp.something.net',
base: undefined,
error: false,
protocol: 'ftp:',
},
{ url: 'file:///tmp/file',
base: undefined,
error: false,
protocol: 'file:',
},
{ url: 'gopher://gopher.something.net',
base: undefined,
error: false,
protocol: 'gopher:',
},
{ url: 'ws://ws.something.net',
base: undefined,
error: false,
protocol: 'ws:',
},
{ url: 'wss://ws.something.net',
base: undefined,
error: false,
protocol: 'wss:',
},
{ url: 'foo://foo.something.net',
base: undefined,
error: false,
protocol: 'foo:',
},
{
url: "about:blank",
base: undefined,
error: false,
protocol: "about:",
pathname: "blank",
skip_setters: false,
},
{ url: 'about:blank',
base: undefined,
error: false,
protocol: 'about:',
pathname: 'blank',
skip_setters: false,
},
{
url: "foo:bar?what#yeah",
base: undefined,
error: false,
protocol: "foo:",
pathname: "bar",
search: "?what",
hash: "#yeah",
skip_setters: false,
},
];
{ url: 'foo:bar?what#yeah',
base: undefined,
error: false,
protocol: 'foo:',
pathname: 'bar',
search: '?what',
hash: '#yeah',
skip_setters: false,
},
];
while (tests.length) {
var test = tests.shift();
while(tests.length) {
var test = tests.shift();
var error = false;
var url;
try {
if (test.base) {
url = new URL(test.url, test.base);
} else {
url = new URL(test.url);
}
} catch (e) {
error = true;
}
var error = false;
var url;
try {
if (test.base) {
url = new URL(test.url, test.base);
} else {
url = new URL(test.url);
}
} catch(e) {
error = true;
}
is(test.error, error, "Error creating URL");
if (test.error) {
continue;
}
is(test.error, error, "Error creating URL");
if (test.error) {
continue;
}
if ("href" in test) is(url.href, test.href, "href");
if ("origin" in test) is(url.origin, test.origin, "origin");
if ("protocol" in test) is(url.protocol, test.protocol, "protocol");
if ("username" in test) is(url.username, test.username, "username");
if ("password" in test) is(url.password, test.password, "password");
if ("host" in test) is(url.host, test.host, "host");
if ("hostname" in test) is(url.hostname, test.hostname, "hostname");
if ("port" in test) is(url.port, test.port, "port");
if ("pathname" in test) is(url.pathname, test.pathname, "pathname");
if ("search" in test) is(url.search, test.search, "search");
if ("hash" in test) is(url.hash, test.hash, "hash");
if ('href' in test) is(url.href, test.href, "href");
if ('origin' in test) is(url.origin, test.origin, "origin");
if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
if ('username' in test) is(url.username, test.username, "username");
if ('password' in test) is(url.password, test.password, "password");
if ('host' in test) is(url.host, test.host, "host");
if ('hostname' in test) is(url.hostname, test.hostname, "hostname");
if ('port' in test) is(url.port, test.port, "port");
if ('pathname' in test) is(url.pathname, test.pathname, "pathname");
if ('search' in test) is(url.search, test.search, "search");
if ('hash' in test) is(url.hash, test.hash, "hash");
if ("skip_setters" in test && test.skip_setters == false) {
info("Skip setter methods for URL: " + test);
continue;
}
if ('skip_setters' in test && test.skip_setters == false) {
info("Skip setter methods for URL: " + test);
continue;
}
url = new URL("https://www.example.net/what#foo?bar");
ok(url, "Url exists!");
url = new URL('https://www.example.net/what#foo?bar');
ok(url, "Url exists!");
if ("href" in test) url.href = test.href;
if ("protocol" in test) url.protocol = test.protocol;
if ("username" in test && test.username) url.username = test.username;
if ("password" in test && test.password) url.password = test.password;
if ("host" in test) url.host = test.host;
if ("hostname" in test) url.hostname = test.hostname;
if ("port" in test) url.port = test.port;
if ("pathname" in test) url.pathname = test.pathname;
if ("search" in test) url.search = test.search;
if ("hash" in test) url.hash = test.hash;
if ('href' in test) url.href = test.href;
if ('protocol' in test) url.protocol = test.protocol;
if ('username' in test && test.username) url.username = test.username;
if ('password' in test && test.password) url.password = test.password;
if ('host' in test) url.host = test.host;
if ('hostname' in test) url.hostname = test.hostname;
if ('port' in test) url.port = test.port;
if ('pathname' in test) url.pathname = test.pathname;
if ('search' in test) url.search = test.search;
if ('hash' in test) url.hash = test.hash;
if ("href" in test) is(url.href, test.href, "href");
if ("origin" in test) is(url.origin, test.origin, "origin");
if ("protocol" in test) is(url.protocol, test.protocol, "protocol");
if ("username" in test) is(url.username, test.username, "username");
if ("password" in test) is(url.password, test.password, "password");
if ("host" in test) is(url.host, test.host, "host");
if ("hostname" in test) is(test.hostname, url.hostname, "hostname");
if ("port" in test) is(test.port, url.port, "port");
if ("pathname" in test) is(test.pathname, url.pathname, "pathname");
if ("search" in test) is(test.search, url.search, "search");
if ("hash" in test) is(test.hash, url.hash, "hash");
if ('href' in test) is(url.href, test.href, "href");
if ('origin' in test) is(url.origin, test.origin, "origin");
if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
if ('username' in test) is(url.username, test.username, "username");
if ('password' in test) is(url.password, test.password, "password");
if ('host' in test) is(url.host, test.host, "host");
if ('hostname' in test) is(test.hostname, url.hostname, "hostname");
if ('port' in test) is(test.port, url.port, "port");
if ('pathname' in test) is(test.pathname, url.pathname, "pathname");
if ('search' in test) is(test.search, url.search, "search");
if ('hash' in test) is(test.hash, url.hash, "hash");
if ("href" in test) is(test.href, url + "", "stringify works");
}
</script>
if ('href' in test) is (test.href, url + '', 'stringify works');
}
<script>
/** Test for Bug 991471 **/
var url = new URL("http://localhost/");
url.hostname = "";
url.username = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt";
url.hostname = "www.mozilla.org";
url.username = "";
url.hostname = "www.mozilla.org";
is(url.href, "http://www.mozilla.org/", "No parsing error with empty host");
</script>
</script>
<script>
/** Test for Bug 996055 **/
var url = new URL("http://localhost/");
url.hostname = "";
is(url.href, "http://localhost/", "Empty hostname is ignored");
</script>
<script>
/** Test for Bug 991471 **/
var url = new URL("http://localhost/");
url.hostname = "";
url.username = "tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt";
url.hostname = "www.mozilla.org";
url.username = "";
url.hostname = "www.mozilla.org";
is(url.href, "http://www.mozilla.org/", "No parsing error with empty host");
</script>
<script>
/** Test for Bug 960014 **/
var url = new URL("http://localhost/");
url.hostname = "[2001::1]";
is(url.hostname, "[2001::1]", "IPv6 hostname");
is(url.href, "http://[2001::1]/");
<script>
/** Test for Bug 996055 **/
var url = new URL("http://localhost/");
url.hostname = "";
is(url.href, "http://localhost/", "Empty hostname is ignored");
</script>
url.hostname = "[::192.9.5.5]";
is(url.hostname, "[::192.9.5.5]", "IPv6 hostname");
is(url.href, "http://[::192.9.5.5]/");
<script>
/** Test for Bug 960014 **/
var url = new URL("http://localhost/");
url.hostname = "[2001::1]";
is(url.hostname, "[2001::1]", "IPv6 hostname");
is(url.href, "http://[2001::1]/");
url = new URL("http://localhost/");
url.hostname = "[::]";
is(url.hostname, "[::]", "IPv6 hostname");
url.hostname = "[::192.9.5.5]";
is(url.hostname, "[::192.9.5.5]", "IPv6 hostname");
is(url.href, "http://[::192.9.5.5]/");
url = new URL("http://localhost/");
url.host = "[2001::1]:30";
is(url.hostname, "[2001::1]", "IPv6 hostname");
is(url.port, "30", "Port");
is(url.host, "[2001::1]:30", "IPv6 host");
url = new URL("http://localhost/");
url.hostname = "[::]";
is(url.hostname, "[::]", "IPv6 hostname");
url = new URL("http://localhost/");
// This should silently fail since it's missing the brackets
url.hostname = "2001::1";
is(url.hostname, "localhost", "Setting bad hostname fails");
</script>
url = new URL("http://localhost/");
url.host = "[2001::1]:30";
is(url.hostname, "[2001::1]", "IPv6 hostname");
is(url.port, "30", "Port");
is(url.host, "[2001::1]:30", "IPv6 host");
<script>
var blob = new Blob(["a"]);
var url = URL.createObjectURL(blob);
url = new URL("http://localhost/");
// This should silently fail since it's missing the brackets
url.hostname = "2001::1";
is(url.hostname, "localhost", "Setting bad hostname fails");
</script>
var u = new URL(url);
ok(u.origin, "http://mochi.test:8888", "The URL generated from a blob URI has an origin");
</script>
<script>
var blob = new Blob(['a']);
var url = URL.createObjectURL(blob);
<script>
var blob = new Blob(["a"]);
var url = URL.createObjectURL(blob);
var u = new URL(url);
ok(u.origin, 'http://mochi.test:8888', "The URL generated from a blob URI has an origin");
</script>
var a = document.createElement("A");
a.href = url;
ok(a.origin, "http://mochi.test:8888", "The 'a' element has the correct origin");
</script>
<script>
var blob = new Blob(['a']);
var url = URL.createObjectURL(blob);
<script>
var blob = new Blob(["a"]);
var url = URL.createObjectURL(blob);
URL.revokeObjectURL(url);
URL.revokeObjectURL(url);
ok(true, "Calling revokeObjectURL twice should be ok");
</script>
var a = document.createElement('A');
a.href = url;
ok(a.origin, 'http://mochi.test:8888', "The 'a' element has the correct origin");
</script>
<script>
URL.revokeObjectURL("blob:something");
ok(true, "This should not throw.");
</script>
<script>
var blob = new Blob(['a']);
var url = URL.createObjectURL(blob);
URL.revokeObjectURL(url);
URL.revokeObjectURL(url);
ok(true, "Calling revokeObjectURL twice should be ok");
</script>
<script>
var base = new URL("http:\\\\test.com\\path/to\\file?query\\backslash#hash\\");
is(base.href, "http://test.com/path/to/file?query\\backslash#hash\\");
<script>
URL.revokeObjectURL('blob:something');
ok(true, "This should not throw.");
</script>
var url = new URL("..\\", base);
is(url.href, "http://test.com/path/");
<script>
var base = new URL("http:\\\\test.com\\path/to\\file?query\\backslash#hash\\");
is(base.href, "http://test.com/path/to/file?query\\backslash#hash\\");
url = new URL("\\test", base);
is(url.href, "http://test.com/test");
var url = new URL("..\\", base);
is(url.href, "http://test.com/path/");
url = new URL("\\test\\", base);
is(url.href, "http://test.com/test/");
url = new URL("\\test", base);
is(url.href, "http://test.com/test");
url = new URL("http://example.org/test", base);
is(url.href, "http://example.org/test");
url = new URL("\\test\\", base);
is(url.href, "http://test.com/test/");
url = new URL("ftp://tmp/test", base);
is(url.href, "ftp://tmp/test");
url = new URL("http://example.org/test", base);
is(url.href, "http://example.org/test");
url = new URL("ftp:\\\\tmp\\test", base);
is(url.href, "ftp://tmp/test");
url = new URL("ftp://tmp/test", base);
is(url.href, "ftp://tmp/test");
url = new URL("scheme://tmp\\test", base);
is(url.href, "scheme://tmp\\test");
</script>
url = new URL("ftp:\\\\tmp\\test", base);
is(url.href, "ftp://tmp/test");
<script>
/** Test for Bug 1275746 **/
SimpleTest.doesThrow(() => {
var url = new URL("http:");
}, "http: is not a valid URL");
SimpleTest.doesThrow(() => {
var url = new URL("http:///");
}, "http: is not a valid URL");
url = new URL("scheme://tmp\\test", base);
is(url.href, "scheme://tmp\\test");
</script>
var url = new URL("file:");
is(url.href, "file:///", "Parsing file: should work.");
<script>
/** Test for Bug 1275746 **/
SimpleTest.doesThrow(() => { var url = new URL("http:"); }, "http: is not a valid URL");
SimpleTest.doesThrow(() => { var url = new URL("http:///"); }, "http: is not a valid URL");
url = new URL("file:///");
is(url.href, "file:///", "Parsing file:/// should work.");
</script>
var url = new URL("file:");
is(url.href, "file:///", "Parsing file: should work.");
<script>
var url = new URL("scheme:path/to/file?query#hash");
is(url.href, "scheme:path/to/file?query#hash");
is(url.pathname, "path/to/file");
is(url.search, "?query");
is(url.hash, "#hash");
url = new URL("file:///");
is(url.href, "file:///", "Parsing file:/// should work.");
</script>
// pathname cannot be overwritten.
url.pathname = "new/path?newquery#newhash";
is(url.href, "scheme:path/to/file?query#hash");
<script>
var url = new URL("scheme:path/to/file?query#hash");
is(url.href, "scheme:path/to/file?query#hash");
is(url.pathname, "path/to/file");
is(url.search, "?query");
is(url.hash, "#hash");
// don't escape '#' until we implement a spec-compliant parser.
url.search = "?newquery#newhash";
is(url.href, "scheme:path/to/file?newquery#newhash#hash");
// pathname cannot be overwritten.
url.pathname = "new/path?newquery#newhash";
is(url.href, "scheme:path/to/file?query#hash");
// nulls get encoded, whitespace gets stripped
url = new URL("scheme:pa\0\nth/to/fi\0\nle?qu\0\nery#ha\0\nsh");
is(url.href, "scheme:pa%00th/to/fi%00le?qu%00ery#ha%00sh");
// don't escape '#' until we implement a spec-compliant parser.
url.search = "?newquery#newhash";
is(url.href, "scheme:path/to/file?newquery#newhash#hash");
url.search = "new\0\nquery";
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#ha%00sh");
url.hash = "new\0\nhash";
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#new%00%0Ahash");
// nulls get encoded, whitespace gets stripped
url = new URL("scheme:pa\0\nth/to/fi\0\nle?qu\0\nery#ha\0\nsh");
is(url.href, "scheme:pa%00th/to/fi%00le?qu%00ery#ha%00sh");
url = new URL("scheme:path#hash");
is(url.href, "scheme:path#hash");
url.search = "query";
is(url.href, "scheme:path?query#hash");
url.hash = "";
is(url.href, "scheme:path?query");
url.hash = "newhash";
is(url.href, "scheme:path?query#newhash");
url.search = "";
is(url.href, "scheme:path#newhash");
url.search = "new\0\nquery";
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#ha%00sh");
url.hash = "new\0\nhash";
is(url.href, "scheme:pa%00th/to/fi%00le?new%00%0Aquery#new%00%0Ahash");
// we don't implement a spec-compliant parser yet.
// make sure we are bug compatible with existing implementations.
url = new URL('data:text/html,<a href="http://example.org/?q">Link</a>');
is(url.href, 'data:text/html,<a%20href="http://example.org/?q">Link</a>');
</script>
url = new URL("scheme:path#hash");
is(url.href, "scheme:path#hash");
url.search = "query";
is(url.href, "scheme:path?query#hash");
url.hash = "";
is(url.href, "scheme:path?query");
url.hash = "newhash";
is(url.href, "scheme:path?query#newhash");
url.search = "";
is(url.href, "scheme:path#newhash");
<script>
is(
new URL("/static/client/runtime.js", "x:/").href,
"x:/static/client/runtime.js",
"URL constructor accepts root-relative input with x:/ base",
);
ok("canParse" in URL, "URL.canParse exists");
ok(
URL.canParse("/static/client/runtime.js", "x:/"),
"URL.canParse accepts root-relative input with x:/ base",
);
ok(
URL.canParse("/static/client/runtime.js", document.baseURI),
"URL.canParse accepts root-relative input with document base",
);
ok(!URL.canParse("/static/client/runtime.js"), "URL.canParse rejects root-relative input without base");
ok(
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
SimpleTest.doesThrow(() => {
new URL("/static/client/runtime.js", "mailto:test@example.com");
}, "constructor rejects root-relative input against opaque mailto: base");
</script>
// we don't implement a spec-compliant parser yet.
// make sure we are bug compatible with existing implementations.
url = new URL("data:text/html,<a href=\"http://example.org/?q\">Link</a>");
is(url.href, "data:text/html,<a%20href=\"http://example.org/?q\">Link</a>");
</script>
<script>
var u = new URL('http://www.example.org');
ok(u.toJSON(), 'http://www.example.org', "URL.toJSON()");
is(JSON.stringify(u), "\"http://www.example.org/\"", "JSON.stringify(u) works");
</script>
</body>
<script>
var u = new URL("http://www.example.org");
ok(u.toJSON(), "http://www.example.org", "URL.toJSON()");
is(JSON.stringify(u), '"http://www.example.org/"', "JSON.stringify(u) works");
</script>
</body>
</html>
+220 -176
View File
@@ -1,212 +1,224 @@
function ok(a, msg) {
dump("OK: " + !!a + " => " + a + " " + msg + "\n");
postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
postMessage({ type: "status", status: !!a, msg: a + ": " + msg });
}
function is(a, b, msg) {
dump("IS: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n");
postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
dump("IS: " + (a === b) + " => " + a + " | " + b + " " + msg + "\n");
postMessage({
type: "status",
status: a === b,
msg: a + " === " + b + ": " + msg,
});
}
onmessage = function() {
onmessage = function () {
status = false;
try {
if ((URL instanceof Object)) {
if (URL instanceof Object) {
status = true;
}
} catch(e) {
}
} catch (e) {}
var tests = [
{ url: 'http://www.abc.com',
{
url: "http://www.abc.com",
base: undefined,
error: false,
href: 'http://www.abc.com/',
origin: 'http://www.abc.com',
protocol: 'http:',
username: '',
password: '',
host: 'www.abc.com',
hostname: 'www.abc.com',
port: '',
pathname: '/',
search: '',
hash: ''
href: "http://www.abc.com/",
origin: "http://www.abc.com",
protocol: "http:",
username: "",
password: "",
host: "www.abc.com",
hostname: "www.abc.com",
port: "",
pathname: "/",
search: "",
hash: "",
},
{ url: 'ftp://auser:apw@www.abc.com',
{
url: "ftp://auser:apw@www.abc.com",
base: undefined,
error: false,
href: 'ftp://auser:apw@www.abc.com/',
origin: 'ftp://www.abc.com',
protocol: 'ftp:',
username: 'auser',
password: 'apw',
host: 'www.abc.com',
hostname: 'www.abc.com',
port: '',
pathname: '/',
search: '',
hash: ''
href: "ftp://auser:apw@www.abc.com/",
origin: "ftp://www.abc.com",
protocol: "ftp:",
username: "auser",
password: "apw",
host: "www.abc.com",
hostname: "www.abc.com",
port: "",
pathname: "/",
search: "",
hash: "",
},
{ url: 'http://www.abc.com:90/apath/',
{
url: "http://www.abc.com:90/apath/",
base: undefined,
error: false,
href: 'http://www.abc.com:90/apath/',
origin: 'http://www.abc.com:90',
protocol: 'http:',
username: '',
password: '',
host: 'www.abc.com:90',
hostname: 'www.abc.com',
port: '90',
pathname: '/apath/',
search: '',
hash: ''
href: "http://www.abc.com:90/apath/",
origin: "http://www.abc.com:90",
protocol: "http:",
username: "",
password: "",
host: "www.abc.com:90",
hostname: "www.abc.com",
port: "90",
pathname: "/apath/",
search: "",
hash: "",
},
{ url: 'http://www.abc.com/apath/afile.txt#ahash',
{
url: "http://www.abc.com/apath/afile.txt#ahash",
base: undefined,
error: false,
href: 'http://www.abc.com/apath/afile.txt#ahash',
origin: 'http://www.abc.com',
protocol: 'http:',
username: '',
password: '',
host: 'www.abc.com',
hostname: 'www.abc.com',
port: '',
pathname: '/apath/afile.txt',
search: '',
hash: '#ahash'
href: "http://www.abc.com/apath/afile.txt#ahash",
origin: "http://www.abc.com",
protocol: "http:",
username: "",
password: "",
host: "www.abc.com",
hostname: "www.abc.com",
port: "",
pathname: "/apath/afile.txt",
search: "",
hash: "#ahash",
},
{ url: 'http://example.com/?test#hash',
{
url: "http://example.com/?test#hash",
base: undefined,
error: false,
href: 'http://example.com/?test#hash',
origin: 'http://example.com',
protocol: 'http:',
username: '',
password: '',
host: 'example.com',
hostname: 'example.com',
port: '',
pathname: '/',
search: '?test',
hash: '#hash'
href: "http://example.com/?test#hash",
origin: "http://example.com",
protocol: "http:",
username: "",
password: "",
host: "example.com",
hostname: "example.com",
port: "",
pathname: "/",
search: "?test",
hash: "#hash",
},
{ url: 'http://example.com/?test',
{
url: "http://example.com/?test",
base: undefined,
error: false,
href: 'http://example.com/?test',
origin: 'http://example.com',
protocol: 'http:',
username: '',
password: '',
host: 'example.com',
hostname: 'example.com',
port: '',
pathname: '/',
search: '?test',
hash: ''
href: "http://example.com/?test",
origin: "http://example.com",
protocol: "http:",
username: "",
password: "",
host: "example.com",
hostname: "example.com",
port: "",
pathname: "/",
search: "?test",
hash: "",
},
{ url: 'http://example.com/carrot#question%3f',
{
url: "http://example.com/carrot#question%3f",
base: undefined,
error: false,
hash: '#question%3f'
hash: "#question%3f",
},
{ url: 'https://example.com:4443?',
{
url: "https://example.com:4443?",
base: undefined,
error: false,
protocol: 'https:',
port: '4443',
pathname: '/',
hash: '',
search: ''
protocol: "https:",
port: "4443",
pathname: "/",
hash: "",
search: "",
},
{ url: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
{
url: "http://www.abc.com/apath/afile.txt#ahash?asearch",
base: undefined,
error: false,
href: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
protocol: 'http:',
pathname: '/apath/afile.txt',
hash: '#ahash?asearch',
search: ''
href: "http://www.abc.com/apath/afile.txt#ahash?asearch",
protocol: "http:",
pathname: "/apath/afile.txt",
hash: "#ahash?asearch",
search: "",
},
{ url: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
{
url: "http://www.abc.com/apath/afile.txt?asearch#ahash",
base: undefined,
error: false,
href: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
protocol: 'http:',
pathname: '/apath/afile.txt',
hash: '#ahash',
search: '?asearch'
href: "http://www.abc.com/apath/afile.txt?asearch#ahash",
protocol: "http:",
pathname: "/apath/afile.txt",
hash: "#ahash",
search: "?asearch",
},
{ url: 'http://abc.com/apath/afile.txt?#ahash',
{
url: "http://abc.com/apath/afile.txt?#ahash",
base: undefined,
error: false,
pathname: '/apath/afile.txt',
hash: '#ahash',
search: ''
pathname: "/apath/afile.txt",
hash: "#ahash",
search: "",
},
{ url: 'http://auser:apassword@www.abc.com:90/apath/afile.txt?asearch#ahash',
{
url: "http://auser:apassword@www.abc.com:90/apath/afile.txt?asearch#ahash",
base: undefined,
error: false,
protocol: 'http:',
username: 'auser',
password: 'apassword',
host: 'www.abc.com:90',
hostname: 'www.abc.com',
port: '90',
pathname: '/apath/afile.txt',
hash: '#ahash',
search: '?asearch',
origin: 'http://www.abc.com:90'
protocol: "http:",
username: "auser",
password: "apassword",
host: "www.abc.com:90",
hostname: "www.abc.com",
port: "90",
pathname: "/apath/afile.txt",
hash: "#ahash",
search: "?asearch",
origin: "http://www.abc.com:90",
},
{ url: '/foo#bar',
base: 'www.test.org',
error: true,
},
{ url: '/foo#bar',
base: null,
error: true,
},
{ url: '/foo#bar',
base: 42,
error: true,
},
{ url: 'ftp://ftp.something.net',
{ url: "/foo#bar", base: "www.test.org", error: true },
{ url: "/foo#bar", base: null, error: true },
{ url: "/foo#bar", base: 42, error: true },
{
url: "ftp://ftp.something.net",
base: undefined,
error: false,
protocol: 'ftp:',
protocol: "ftp:",
},
{ url: 'file:///tmp/file',
{
url: "file:///tmp/file",
base: undefined,
error: false,
protocol: 'file:',
protocol: "file:",
},
{ url: 'gopher://gopher.something.net',
{
url: "gopher://gopher.something.net",
base: undefined,
error: false,
protocol: 'gopher:',
protocol: "gopher:",
},
{ url: 'ws://ws.something.net',
{
url: "ws://ws.something.net",
base: undefined,
error: false,
protocol: 'ws:',
protocol: "ws:",
},
{ url: 'wss://ws.something.net',
{
url: "wss://ws.something.net",
base: undefined,
error: false,
protocol: 'wss:',
protocol: "wss:",
},
{ url: 'foo://foo.something.net',
{
url: "foo://foo.something.net",
base: undefined,
error: false,
protocol: 'foo:',
protocol: "foo:",
},
];
while(tests.length) {
while (tests.length) {
var test = tests.shift();
var error = false;
@@ -217,7 +229,7 @@ onmessage = function() {
} else {
url = new URL(test.url);
}
} catch(e) {
} catch (e) {
error = true;
}
@@ -226,47 +238,79 @@ onmessage = function() {
continue;
}
if ('href' in test) is(url.href, test.href, "href");
if ('origin' in test) is(url.origin, test.origin, "origin");
if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
if ('username' in test) is(url.username, test.username, "username");
if ('password' in test) is(url.password, test.password, "password");
if ('host' in test) is(url.host, test.host, "host");
if ('hostname' in test) is(url.hostname, test.hostname, "hostname");
if ('port' in test) is(url.port, test.port, "port");
if ('pathname' in test) is(url.pathname, test.pathname, "pathname");
if ('search' in test) is(url.search, test.search, "search");
if ('hash' in test) is(url.hash, test.hash, "hash");
if ("href" in test) is(url.href, test.href, "href");
if ("origin" in test) is(url.origin, test.origin, "origin");
if ("protocol" in test) is(url.protocol, test.protocol, "protocol");
if ("username" in test) is(url.username, test.username, "username");
if ("password" in test) is(url.password, test.password, "password");
if ("host" in test) is(url.host, test.host, "host");
if ("hostname" in test) is(url.hostname, test.hostname, "hostname");
if ("port" in test) is(url.port, test.port, "port");
if ("pathname" in test) is(url.pathname, test.pathname, "pathname");
if ("search" in test) is(url.search, test.search, "search");
if ("hash" in test) is(url.hash, test.hash, "hash");
url = new URL('https://www.example.net/what#foo?bar');
url = new URL("https://www.example.net/what#foo?bar");
ok(url, "Url exists!");
if ('href' in test) url.href = test.href;
if ('protocol' in test) url.protocol = test.protocol;
if ('username' in test && test.username) url.username = test.username;
if ('password' in test && test.password) url.password = test.password;
if ('host' in test) url.host = test.host;
if ('hostname' in test) url.hostname = test.hostname;
if ('port' in test) url.port = test.port;
if ('pathname' in test) url.pathname = test.pathname;
if ('search' in test) url.search = test.search;
if ('hash' in test) url.hash = test.hash;
if ("href" in test) url.href = test.href;
if ("protocol" in test) url.protocol = test.protocol;
if ("username" in test && test.username) url.username = test.username;
if ("password" in test && test.password) url.password = test.password;
if ("host" in test) url.host = test.host;
if ("hostname" in test) url.hostname = test.hostname;
if ("port" in test) url.port = test.port;
if ("pathname" in test) url.pathname = test.pathname;
if ("search" in test) url.search = test.search;
if ("hash" in test) url.hash = test.hash;
if ('href' in test) is(url.href, test.href, "href");
if ('origin' in test) is(url.origin, test.origin, "origin");
if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
if ('username' in test) is(url.username, test.username, "username");
if ('password' in test) is(url.password, test.password, "password");
if ('host' in test) is(url.host, test.host, "host");
if ('hostname' in test) is(test.hostname, url.hostname, "hostname");
if ('port' in test) is(test.port, url.port, "port");
if ('pathname' in test) is(test.pathname, url.pathname, "pathname");
if ('search' in test) is(test.search, url.search, "search");
if ('hash' in test) is(test.hash, url.hash, "hash");
if ("href" in test) is(url.href, test.href, "href");
if ("origin" in test) is(url.origin, test.origin, "origin");
if ("protocol" in test) is(url.protocol, test.protocol, "protocol");
if ("username" in test) is(url.username, test.username, "username");
if ("password" in test) is(url.password, test.password, "password");
if ("host" in test) is(url.host, test.host, "host");
if ("hostname" in test) is(test.hostname, url.hostname, "hostname");
if ("port" in test) is(test.port, url.port, "port");
if ("pathname" in test) is(test.pathname, url.pathname, "pathname");
if ("search" in test) is(test.search, url.search, "search");
if ("hash" in test) is(test.hash, url.hash, "hash");
if ('href' in test) is (test.href, url + '', 'stringify works');
if ("href" in test) is(test.href, url + "", "stringify works");
}
postMessage({type: 'finish' });
}
is(
new URL("/static/client/runtime.js", "x:/").href,
"x:/static/client/runtime.js",
"URL constructor accepts root-relative input with x:/ base",
);
ok("canParse" in URL, "URL.canParse exists");
ok(
URL.canParse("/static/client/runtime.js", "x:/"),
"URL.canParse accepts root-relative input with x:/ base",
);
ok(
URL.canParse("/static/client/runtime.js", self.location.href),
"URL.canParse accepts root-relative input with worker location base",
);
ok(
!URL.canParse("/static/client/runtime.js"),
"URL.canParse rejects root-relative input without base",
);
ok(
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
let mailtoRelativeFailed = false;
try {
new URL("/static/client/runtime.js", "mailto:test@example.com");
} catch (e) {
mailtoRelativeFailed = true;
}
ok(
mailtoRelativeFailed,
"constructor rejects root-relative input against opaque mailto: base",
);
postMessage({ type: "finish" });
};
+1
View File
@@ -142,6 +142,7 @@ EditorBase::EditorBase()
, mDispatchInputEvent(true)
, mIsInEditAction(false)
, mHidingCaret(false)
, mIsHTMLEditorClass(false)
{
}
+20
View File
@@ -114,6 +114,7 @@ class DeleteNodeTransaction;
class DeleteTextTransaction;
class EditAggregateTransaction;
class ErrorResult;
class HTMLEditor;
class InsertNodeTransaction;
class InsertTextTransaction;
class JoinNodeTransaction;
@@ -121,6 +122,7 @@ class PlaceholderTransaction;
class RemoveStyleSheetTransaction;
class SplitNodeTransaction;
class TextComposition;
class TextEditor;
struct EditorDOMPoint;
namespace dom {
@@ -1113,14 +1115,32 @@ protected:
bool mIsInEditAction;
// Whether caret is hidden forcibly.
bool mHidingCaret;
// Whether we are an HTML editor class.
bool mIsHTMLEditorClass;
friend bool NSCanUnload(nsISupports* serviceMgr);
friend class AutoRules;
friend class AutoSelectionRestorer;
friend class AutoTransactionsConserveSelection;
friend class RangeUpdater;
friend class nsIEditor;
};
} // namespace mozilla
// nsIEditor helper functions.
// Here because of code context.
mozilla::EditorBase*
nsIEditor::AsEditorBase()
{
return static_cast<mozilla::EditorBase*>(this);
}
const mozilla::EditorBase*
nsIEditor::AsEditorBase() const
{
return static_cast<const mozilla::EditorBase*>(this);
}
#endif // #ifndef mozilla_EditorBase_h
+8 -1
View File
@@ -233,9 +233,16 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLEditRules, TextEditRules,
NS_IMETHODIMP
HTMLEditRules::Init(TextEditor* aTextEditor)
{
if (NS_WARN_IF(!aTextEditor)) {
return NS_ERROR_INVALID_ARG;
}
InitFields();
mHTMLEditor = static_cast<HTMLEditor*>(aTextEditor);
mHTMLEditor = aTextEditor->AsHTMLEditor();
if (NS_WARN_IF(!mHTMLEditor)) {
return NS_ERROR_INVALID_ARG;
}
// call through to base class Init
nsresult rv = TextEditRules::Init(aTextEditor);
+2 -1
View File
@@ -132,6 +132,7 @@ HTMLEditor::HTMLEditor()
, mPositionedObjectBorderTop(0)
, mGridSize(0)
{
mIsHTMLEditorClass = true;
}
HTMLEditor::~HTMLEditor()
@@ -501,7 +502,7 @@ HTMLEditor::InitRules()
// instantiate the rules for the html editor
mRules = new HTMLEditRules();
}
return mRules->Init(static_cast<TextEditor*>(this));
return mRules->Init(this);
}
NS_IMETHODIMP
+16
View File
@@ -1108,4 +1108,20 @@ private:
} // namespace mozilla
// nsIEditor helper functions.
// Here because of code context.
mozilla::HTMLEditor*
nsIEditor::AsHTMLEditor()
{
return static_cast<mozilla::EditorBase*>(this)->mIsHTMLEditorClass ?
static_cast<mozilla::HTMLEditor*>(this) : nullptr;
}
const mozilla::HTMLEditor*
nsIEditor::AsHTMLEditor() const
{
return static_cast<const mozilla::EditorBase*>(this)->mIsHTMLEditorClass ?
static_cast<const mozilla::HTMLEditor*>(this) : nullptr;
}
#endif // #ifndef mozilla_HTMLEditor_h
+21 -18
View File
@@ -30,24 +30,18 @@ namespace mozilla {
using namespace dom;
#ifdef DEBUG
nsresult
HTMLEditorEventListener::Connect(EditorBase* aEditorBase)
{
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryObject(aEditorBase);
nsCOMPtr<nsIHTMLInlineTableEditor> htmlInlineTableEditor =
do_QueryObject(aEditorBase);
NS_PRECONDITION(htmlEditor && htmlInlineTableEditor,
"Set HTMLEditor or its sub class");
return EditorEventListener::Connect(aEditorBase);
}
#endif
HTMLEditor*
HTMLEditorEventListener::GetHTMLEditor()
{
// mEditor must be HTMLEditor or its subclass.
return static_cast<HTMLEditor*>(mEditorBase);
if (NS_WARN_IF(!aEditorBase)) {
return NS_ERROR_INVALID_ARG;
}
// Guarantee that mEditorBase is always HTMLEditor.
HTMLEditor* htmlEditor = aEditorBase->AsHTMLEditor();
if (NS_WARN_IF(!htmlEditor)) {
return NS_ERROR_INVALID_ARG;
}
return EditorEventListener::Connect(htmlEditor);
}
nsresult
@@ -59,7 +53,8 @@ HTMLEditorEventListener::MouseUp(nsIDOMMouseEvent* aMouseEvent)
// FYI: We need to notify HTML editor of mouseup even if it's consumed
// because HTML editor always needs to release grabbing resizer.
HTMLEditor* htmlEditor = GetHTMLEditor();
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
MOZ_ASSERT(htmlEditor);
nsCOMPtr<nsIDOMEventTarget> target;
nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
@@ -85,7 +80,9 @@ HTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
WidgetMouseEvent* mousedownEvent =
aMouseEvent->AsEvent()->WidgetEventPtr()->AsMouseEvent();
HTMLEditor* htmlEditor = GetHTMLEditor();
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
MOZ_ASSERT(htmlEditor);
// Contenteditable should disregard mousedowns outside it.
// IsAcceptableInputEvent() checks it for a mouse event.
if (!htmlEditor->IsAcceptableInputEvent(mousedownEvent)) {
@@ -221,13 +218,19 @@ HTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
nsresult
HTMLEditorEventListener::MouseClick(nsIDOMMouseEvent* aMouseEvent)
{
if (NS_WARN_IF(DetachedFromEditor())) {
return NS_OK;
}
nsCOMPtr<nsIDOMEventTarget> target;
nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
GetHTMLEditor()->DoInlineTableEditingAction(element);
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
MOZ_ASSERT(htmlEditor);
htmlEditor->DoInlineTableEditingAction(element);
return EditorEventListener::MouseClick(aMouseEvent);
}
+1 -5
View File
@@ -25,17 +25,13 @@ public:
{
}
#ifdef DEBUG
// WARNING: You must be use HTMLEditor or its sub class for this class.
// Connect() fails if aEditorBase isn't an HTMLEditor instance.
virtual nsresult Connect(EditorBase* aEditorBase) override;
#endif
protected:
virtual nsresult MouseDown(nsIDOMMouseEvent* aMouseEvent) override;
virtual nsresult MouseUp(nsIDOMMouseEvent* aMouseEvent) override;
virtual nsresult MouseClick(nsIDOMMouseEvent* aMouseEvent) override;
inline HTMLEditor* GetHTMLEditor();
};
} // namespace mozilla
+1
View File
@@ -10,6 +10,7 @@
#include "gfxFontUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/EditorUtils.h" // AutoEditBatch, AutoRules
#include "mozilla/HTMLEditor.h"
#include "mozilla/mozalloc.h"
#include "mozilla/Preferences.h"
#include "mozilla/TextEditRules.h"
+14
View File
@@ -247,4 +247,18 @@ protected:
} // namespace mozilla
// nsIEditor helper functions.
// Here because of code context.
mozilla::TextEditor*
nsIEditor::AsTextEditor()
{
return static_cast<mozilla::TextEditor*>(this);
}
const mozilla::TextEditor*
nsIEditor::AsTextEditor() const
{
return static_cast<const mozilla::TextEditor*>(this);
}
#endif // #ifndef mozilla_TextEditor_h
+38
View File
@@ -21,6 +21,14 @@ interface nsIEditActionListener;
interface nsIInlineSpellChecker;
interface nsITransferable;
%{C++
namespace mozilla {
class EditorBase;
class HTMLEditor;
class TextEditor;
} // namespace mozilla
%}
[scriptable, uuid(094be624-f0bf-400f-89e2-6a84baab9474)]
interface nsIEditor : nsISupports
{
@@ -564,4 +572,34 @@ interface nsIEditor : nsISupports
* or nsIEditorObserver::CancelEditAction(). Otherwise, false.
*/
[noscript] readonly attribute boolean isInEditAction;
%{C++
/**
* AsEditorBase() returns a pointer to EditorBase class.
*
* In order to avoid circular dependency issues, this method is defined
* in mozilla/EditorBase.h. Consumers need to #include that header.
*/
inline mozilla::EditorBase* AsEditorBase();
inline const mozilla::EditorBase* AsEditorBase() const;
/**
* AsTextEditor() returns a pointer to TextEditor class.
*
* In order to avoid circular dependency issues, this method is defined
* in mozilla/TextEditor.h. Consumers need to #include that header.
*/
inline mozilla::TextEditor* AsTextEditor();
inline const mozilla::TextEditor* AsTextEditor() const;
/**
* AsHTMLEditor() returns a pointer to HTMLEditor class.
*
* In order to avoid circular dependency issues, this method is defined
* in mozilla/HTMLEditor.h. Consumers need to #include that header.
*/
inline mozilla::HTMLEditor* AsHTMLEditor();
inline const mozilla::HTMLEditor* AsHTMLEditor() const;
%}
};
@@ -97,9 +97,6 @@ using namespace mozilla::dom;
#define INLINESPELL_STARTED_TOPIC "inlineSpellChecker-spellCheck-started"
#define INLINESPELL_ENDED_TOPIC "inlineSpellChecker-spellCheck-ended"
static bool ContentIsDescendantOf(nsINode* aPossibleDescendant,
nsINode* aPossibleAncestor);
static const char kMaxSpellCheckSelectionSize[] = "extensions.spellcheck.inline.max-misspellings";
mozInlineSpellStatus::mozInlineSpellStatus(mozInlineSpellChecker* aSpellChecker)
@@ -238,7 +235,7 @@ mozInlineSpellStatus::InitForNavigation(
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> currentAnchor = do_QueryInterface(aOldAnchorNode, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (root && currentAnchor && ! ContentIsDescendantOf(currentAnchor, root)) {
if (root && currentAnchor && !nsContentUtils::ContentIsShadowIncludingDescendantOf(currentAnchor, root)) {
*aContinue = false;
return NS_OK;
}
@@ -1490,8 +1487,11 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil,
return NS_OK;
}
aWordUtil.SetEnd(endNode, endOffset);
aWordUtil.SetPosition(beginNode, beginOffset);
nsresult rv = aWordUtil.SetPositionAndEnd(beginNode, beginOffset, endNode, endOffset);
if (NS_FAILED(rv)) {
// Just bail out and don't try to spell-check this
return NS_OK;
}
}
// aWordUtil.SetPosition flushes pending notifications, check editor again.
@@ -1840,24 +1840,6 @@ nsresult mozInlineSpellChecker::SaveCurrentSelectionPosition()
return NS_OK;
}
// This is a copy of nsContentUtils::ContentIsDescendantOf. Another crime
// for XPCOM's rap sheet
bool // static
ContentIsDescendantOf(nsINode* aPossibleDescendant,
nsINode* aPossibleAncestor)
{
NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
do {
if (aPossibleDescendant == aPossibleAncestor)
return true;
aPossibleDescendant = aPossibleDescendant->GetParentNode();
} while (aPossibleDescendant);
return false;
}
// mozInlineSpellChecker::HandleNavigationEvent
//
// Acts upon mouse clicks and keyboard navigation changes, spell checking
@@ -23,6 +23,8 @@
#include "nsIFrame.h"
#include <algorithm>
#include "mozilla/BinarySearch.h"
#include "mozilla/HTMLEditor.h"
#include "mozilla/dom/ShadowRoot.h"
using namespace mozilla;
@@ -69,8 +71,10 @@ mozInlineSpellWordUtil::Init(nsWeakPtr aWeakEditor)
mDOMDocument = domDoc;
mDocument = do_QueryInterface(domDoc);
// Find the root node for the editor. For contenteditable we'll need something
// cleverer here.
mIsContentEditableOrDesignMode = !!editor->AsHTMLEditor();
// Find the root node for the editor. For contenteditable the mRootNode could
// change to shadow root if the begin and end are inside the shadowDOM.
nsCOMPtr<nsIDOMElement> rootElt;
rv = editor->GetRootElement(getter_AddRefs(rootElt));
NS_ENSURE_SUCCESS(rv, rv);
@@ -154,7 +158,7 @@ FindNextTextNode(nsINode* aNode, int32_t aOffset, nsINode* aRoot)
return checkNode;
}
// mozInlineSpellWordUtil::SetEnd
// mozInlineSpellWordUtil::SetPositionAndEnd
//
// We have two ranges "hard" and "soft". The hard boundary is simply
// the scope of the root node. The soft boundary is that which is set
@@ -172,34 +176,44 @@ FindNextTextNode(nsINode* aNode, int32_t aOffset, nsINode* aRoot)
// position.
nsresult
mozInlineSpellWordUtil::SetEnd(nsINode* aEndNode, int32_t aEndOffset)
mozInlineSpellWordUtil::SetPositionAndEnd(nsINode* aPositionNode,
int32_t aPositionOffset,
nsINode* aEndNode,
int32_t aEndOffset)
{
MOZ_ASSERT(aPositionNode, "Null begin node?");
NS_PRECONDITION(aEndNode, "Null end node?");
NS_ASSERTION(mRootNode, "Not initialized");
// Find a appropriate root if we are dealing with contenteditable nodes which
// are in the shadow DOM. See UXP Issue #3011
if (mIsContentEditableOrDesignMode) {
nsINode* rootNode = aPositionNode->SubtreeRoot();
if (rootNode != aEndNode->SubtreeRoot()) {
return NS_ERROR_FAILURE;
}
if (mozilla::dom::ShadowRoot::FromNode(rootNode)) {
mRootNode = rootNode;
}
}
InvalidateWords();
if (!IsTextNode(aPositionNode)) {
// Start at the start of the first text node after aNode/aOffset.
aPositionNode = FindNextTextNode(aPositionNode, aPositionOffset, mRootNode);
aPositionOffset = 0;
}
mSoftBegin = NodeOffset(aPositionNode, aPositionOffset);
if (!IsTextNode(aEndNode)) {
// End at the start of the first text node after aEndNode/aEndOffset.
aEndNode = FindNextTextNode(aEndNode, aEndOffset, mRootNode);
aEndOffset = 0;
}
mSoftEnd = NodeOffset(aEndNode, aEndOffset);
return NS_OK;
}
nsresult
mozInlineSpellWordUtil::SetPosition(nsINode* aNode, int32_t aOffset)
{
InvalidateWords();
if (!IsTextNode(aNode)) {
// Start at the start of the first text node after aNode/aOffset.
aNode = FindNextTextNode(aNode, aOffset, mRootNode);
aOffset = 0;
}
mSoftBegin = NodeOffset(aNode, aOffset);
nsresult rv = EnsureWords();
if (NS_FAILED(rv)) {
@@ -207,8 +221,10 @@ mozInlineSpellWordUtil::SetPosition(nsINode* aNode, int32_t aOffset)
}
int32_t textOffset = MapDOMPositionToSoftTextOffset(mSoftBegin);
if (textOffset < 0)
if (textOffset < 0) {
return NS_OK;
}
mNextWordIndex = FindRealWordContaining(textOffset, HINT_END, true);
return NS_OK;
}
@@ -29,12 +29,11 @@ class nsINode;
* The basic operation is:
*
* 1. Call Init with the weak pointer to the editor that you're using.
* 2. Call SetEnd to set where you want to stop spellchecking. We'll stop
* at the word boundary after that. If SetEnd is not called, we'll stop
* at the end of the document's root element.
* 3. Call SetPosition to initialize the current position inside the
* previously given range.
* 4. Call GetNextWord over and over until it returns false.
* 2. Call SetPositionAndEnd to to initialize the current position inside the
* previously given range and set where you want to stop spellchecking.
* We'll stop at the word boundary after that. If SetEnd is not called,
* we'll stop at the end of the root element.
* 3. Call GetNextWord over and over until it returns false.
*/
class mozInlineSpellWordUtil
@@ -57,17 +56,22 @@ public:
};
mozInlineSpellWordUtil()
: mRootNode(nullptr),
mSoftBegin(nullptr, 0), mSoftEnd(nullptr, 0),
mNextWordIndex(-1), mSoftTextValid(false) {}
: mIsContentEditableOrDesignMode(false)
, mRootNode(nullptr)
, mSoftBegin(nullptr, 0)
, mSoftEnd(nullptr, 0)
, mNextWordIndex(-1)
, mSoftTextValid(false)
{}
nsresult Init(nsWeakPtr aWeakEditor);
nsresult SetEnd(nsINode* aEndNode, int32_t aEndOffset);
// sets the current position, this should be inside the range. If we are in
// the middle of a word, we'll move to its start.
nsresult SetPosition(nsINode* aNode, int32_t aOffset);
// Sets the current position and end. This should be inside the range.
// If we are in the middle of a word, we'll move to its start.
nsresult SetPositionAndEnd(nsINode* aPositionNode,
int32_t aPositionOffset,
nsINode* aEndNode,
int32_t aEndOffset);
// Given a point inside or immediately following a word, this returns the
// DOM range that exactly encloses that word's characters. The current
@@ -100,7 +104,8 @@ private:
// cached stuff for the editor, set by Init
nsCOMPtr<nsIDOMDocument> mDOMDocument;
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsIDocument> mDocument;
bool mIsContentEditableOrDesignMode;
// range to check, see SetPosition and SetEnd
nsINode* mRootNode;
@@ -220,7 +220,8 @@ bool MacroExpander::expandMacro(const Macro &macro,
assert(macro.type == Macro::kTypeFunc);
std::vector<MacroArg> args;
args.reserve(macro.parameters.size());
if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
if (replacements->size() == 0 ||
!collectMacroArgs(macro, identifier, &args, &replacementLocation))
return false;
replaceMacroParams(macro, args, replacements);
+1132 -1048
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -1247,6 +1247,7 @@ static const JSFunctionSpec object_static_methods[] = {
JS_FN("seal", obj_seal, 1, 0),
JS_FN("isSealed", obj_isSealed, 1, 0),
JS_SELF_HOSTED_FN("fromEntries", "ObjectFromEntries", 1, 0),
JS_SELF_HOSTED_FN("groupBy", "ObjectGroupBy", 2, 0),
JS_SELF_HOSTED_FN("hasOwn", "ObjectHasOwn", 2, 0),
JS_FS_END
};
+178 -138
View File
@@ -4,228 +4,268 @@
// ES6 draft rev36 2015-03-17 19.1.2.1
function ObjectStaticAssign(target, firstSource) {
// Steps 1-2.
var to = ToObject(target);
// Steps 1-2.
var to = ToObject(target);
// Step 3.
if (arguments.length < 2)
return to;
// Step 3.
if (arguments.length < 2) return to;
// Steps 4-5.
for (var i = 1; i < arguments.length; i++) {
// Step 5.a.
var nextSource = arguments[i];
if (nextSource === null || nextSource === undefined)
continue;
// Steps 4-5.
for (var i = 1; i < arguments.length; i++) {
// Step 5.a.
var nextSource = arguments[i];
if (nextSource === null || nextSource === undefined) continue;
// Steps 5.b.i-ii.
var from = ToObject(nextSource);
// Steps 5.b.i-ii.
var from = ToObject(nextSource);
// Steps 5.b.iii-iv.
var keys = OwnPropertyKeys(from, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS);
// Steps 5.b.iii-iv.
var keys = OwnPropertyKeys(
from,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS,
);
// Step 5.c.
for (var nextIndex = 0, len = keys.length; nextIndex < len; nextIndex++) {
var nextKey = keys[nextIndex];
// Step 5.c.
for (var nextIndex = 0, len = keys.length; nextIndex < len; nextIndex++) {
var nextKey = keys[nextIndex];
// Steps 5.c.i-iii. We abbreviate this by calling propertyIsEnumerable
// which is faster and returns false for not defined properties.
if (callFunction(std_Object_propertyIsEnumerable, from, nextKey)) {
// Steps 5.c.iii.1-4.
to[nextKey] = from[nextKey];
}
}
// Steps 5.c.i-iii. We abbreviate this by calling propertyIsEnumerable
// which is faster and returns false for not defined properties.
if (callFunction(std_Object_propertyIsEnumerable, from, nextKey)) {
// Steps 5.c.iii.1-4.
to[nextKey] = from[nextKey];
}
}
}
// Step 6.
return to;
// Step 6.
return to;
}
// ES stage 4 proposal
function ObjectGetOwnPropertyDescriptors(O) {
// Step 1.
var obj = ToObject(O);
// Step 1.
var obj = ToObject(O);
// Step 2.
var keys = OwnPropertyKeys(obj, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS);
// Step 2.
var keys = OwnPropertyKeys(
obj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS,
);
// Step 3.
var descriptors = {};
// Step 3.
var descriptors = {};
// Step 4.
for (var index = 0, len = keys.length; index < len; index++) {
var key = keys[index];
// Step 4.
for (var index = 0, len = keys.length; index < len; index++) {
var key = keys[index];
// Steps 4.a-b.
var desc = std_Object_getOwnPropertyDescriptor(obj, key);
// Steps 4.a-b.
var desc = std_Object_getOwnPropertyDescriptor(obj, key);
// Step 4.c.
if (typeof desc !== "undefined")
_DefineDataProperty(descriptors, key, desc);
}
// Step 4.c.
if (typeof desc !== "undefined")
_DefineDataProperty(descriptors, key, desc);
}
// Step 5.
return descriptors;
// Step 5.
return descriptors;
}
/* ES6 draft rev 32 (2015 Feb 2) 19.1.2.9. */
function ObjectGetPrototypeOf(obj) {
return std_Reflect_getPrototypeOf(ToObject(obj));
return std_Reflect_getPrototypeOf(ToObject(obj));
}
/* ES6 draft rev 32 (2015 Feb 2) 19.1.2.11. */
function ObjectIsExtensible(obj) {
return IsObject(obj) && std_Reflect_isExtensible(obj);
return IsObject(obj) && std_Reflect_isExtensible(obj);
}
/* ES2015 19.1.3.5 Object.prototype.toLocaleString */
function Object_toLocaleString() {
// Step 1.
var O = this;
// Step 1.
var O = this;
// Step 2.
return callContentFunction(O.toString, O);
// Step 2.
return callContentFunction(O.toString, O);
}
// ES 2017 draft bb96899bb0d9ef9be08164a26efae2ee5f25e875 19.1.3.7
function Object_valueOf() {
// Step 1.
return ToObject(this);
// Step 1.
return ToObject(this);
}
// ES7 draft (2016 March 8) B.2.2.3
function ObjectDefineSetter(name, setter) {
// Step 1.
var object = ToObject(this);
// Step 1.
var object = ToObject(this);
// Step 2.
if (!IsCallable(setter))
ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "setter");
// Step 2.
if (!IsCallable(setter)) ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "setter");
// Step 3.
var desc = {
__proto__: null,
enumerable: true,
configurable: true,
set: setter
};
// Step 3.
var desc = {
__proto__: null,
enumerable: true,
configurable: true,
set: setter,
};
// Step 4.
var key = ToPropertyKey(name);
// Step 4.
var key = ToPropertyKey(name);
// Step 5.
std_Object_defineProperty(object, key, desc);
// Step 5.
std_Object_defineProperty(object, key, desc);
// Step 6. (implicit)
// Step 6. (implicit)
}
// ES7 draft (2016 March 8) B.2.2.2
function ObjectDefineGetter(name, getter) {
// Step 1.
var object = ToObject(this);
// Step 1.
var object = ToObject(this);
// Step 2.
if (!IsCallable(getter))
ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "getter");
// Step 2.
if (!IsCallable(getter)) ThrowTypeError(JSMSG_BAD_GETTER_OR_SETTER, "getter");
// Step 3.
var desc = {
__proto__: null,
enumerable: true,
configurable: true,
get: getter
};
// Step 3.
var desc = {
__proto__: null,
enumerable: true,
configurable: true,
get: getter,
};
// Step 4.
var key = ToPropertyKey(name);
// Step 4.
var key = ToPropertyKey(name);
// Step 5.
std_Object_defineProperty(object, key, desc);
// Step 5.
std_Object_defineProperty(object, key, desc);
// Step 6. (implicit)
// Step 6. (implicit)
}
// ES7 draft (2016 March 8) B.2.2.5
function ObjectLookupSetter(name) {
// Step 1.
var object = ToObject(this);
// Step 1.
var object = ToObject(this);
// Step 2.
var key = ToPropertyKey(name)
// Step 2.
var key = ToPropertyKey(name);
do {
// Step 3.a.
var desc = std_Object_getOwnPropertyDescriptor(object, key);
do {
// Step 3.a.
var desc = std_Object_getOwnPropertyDescriptor(object, key);
// Step 3.b.
if (desc) {
// Step.b.i.
if (callFunction(std_Object_hasOwnProperty, desc, "set"))
return desc.set;
// Step 3.b.
if (desc) {
// Step.b.i.
if (callFunction(std_Object_hasOwnProperty, desc, "set")) return desc.set;
// Step.b.ii.
return undefined;
}
// Step.b.ii.
return undefined;
}
// Step 3.c.
object = std_Reflect_getPrototypeOf(object);
} while (object !== null);
// Step 3.c.
object = std_Reflect_getPrototypeOf(object);
} while (object !== null);
// Step 3.d. (implicit)
// Step 3.d. (implicit)
}
// ES7 draft (2016 March 8) B.2.2.4
function ObjectLookupGetter(name) {
// Step 1.
var object = ToObject(this);
// Step 1.
var object = ToObject(this);
// Step 2.
var key = ToPropertyKey(name)
// Step 2.
var key = ToPropertyKey(name);
do {
// Step 3.a.
var desc = std_Object_getOwnPropertyDescriptor(object, key);
do {
// Step 3.a.
var desc = std_Object_getOwnPropertyDescriptor(object, key);
// Step 3.b.
if (desc) {
// Step.b.i.
if (callFunction(std_Object_hasOwnProperty, desc, "get"))
return desc.get;
// Step 3.b.
if (desc) {
// Step.b.i.
if (callFunction(std_Object_hasOwnProperty, desc, "get")) return desc.get;
// Step.b.ii.
return undefined;
}
// Step.b.ii.
return undefined;
}
// Step 3.c.
object = std_Reflect_getPrototypeOf(object);
} while (object !== null);
// Step 3.c.
object = std_Reflect_getPrototypeOf(object);
} while (object !== null);
// Step 3.d. (implicit)
// Step 3.d. (implicit)
}
// Stage 4 draft 2020-09-06 https://tc39.github.io/proposal-object-from-entries/
// Object.fromEntries (iterable)
function ObjectFromEntries(iter) {
// We omit the usual step number comments here because they don't help.
// This implementation inlines AddEntriesFromIterator and
// CreateDataPropertyOnObject, so it looks more like the polyfill
// than the step-by-step spec algorithm.
const obj = {};
// We omit the usual step number comments here because they don't help.
// This implementation inlines AddEntriesFromIterator and
// CreateDataPropertyOnObject, so it looks more like the polyfill
// than the step-by-step spec algorithm.
const obj = {};
for (const pair of allowContentIter(iter)) {
if (!IsObject(pair))
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Object.fromEntries");
_DefineDataProperty(obj, pair[0], pair[1]);
for (const pair of allowContentIter(iter)) {
if (!IsObject(pair))
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Object.fromEntries");
_DefineDataProperty(obj, pair[0], pair[1]);
}
return obj;
}
// ES2024
// Object.groupBy ( items, callbackfn )
function ObjectGroupBy(items, callbackfn) {
// Step 1.
RequireObjectCoercible(items);
// Step 2.
if (!IsCallable(callbackfn))
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn));
// Step 3.
var groups = std_Object_create(null);
// Step 4.
var k = 0;
// Steps 5-8.
for (var value of allowContentIter(items)) {
// Step 6.a.
var key = callContentFunction(callbackfn, undefined, value, k);
// Step 6.b.
key = ToPropertyKey(key);
// Steps 6.c-d.
var elements = groups[key];
if (elements === undefined) {
_DefineDataProperty(groups, key, [value]);
} else {
callFunction(std_Array_push, elements, value);
}
return obj;
// Step 6.e.
k++;
}
// Step 9.
return groups;
}
// Proposal https://github.com/tc39/proposal-accessible-object-hasownproperty
// Object.hasOwn (Object, Property)
function ObjectHasOwn(O, P) {
// Step 1.
var obj = ToObject(O);
// Step 2-3.
return callFunction(std_Object_hasOwnProperty, obj, P);
// Step 1.
var obj = ToObject(O);
// Step 2-3.
return callFunction(std_Object_hasOwnProperty, obj, P);
}
+106
View File
@@ -37,6 +37,10 @@ function TypedArrayLengthMethod() {
return TypedArrayLength(this);
}
function TypedArrayContentTypeIsBigIntMethod() {
return IsBigInt64TypedArray(this) || IsBigUint64TypedArray(this);
}
function GetAttachedArrayBuffer(tarray) {
var buffer = ViewedArrayBufferIfReified(tarray);
if (IsDetachedBuffer(buffer))
@@ -60,6 +64,12 @@ function IsTypedArrayEnsuringArrayBuffer(arg) {
return true;
}
if (IsObject(arg) && IsPossiblyWrappedTypedArray(arg)) {
if (PossiblyWrappedTypedArrayHasDetachedBuffer(arg))
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
return false;
}
callFunction(CallTypedArrayMethodIfWrapped, arg, "GetAttachedArrayBufferMethod");
return false;
}
@@ -157,6 +167,15 @@ function TypedArraySpeciesCreateWithBuffer(exemplar, buffer, byteOffset, length)
return TypedArrayCreateWithBuffer(C, buffer, byteOffset, length);
}
// ES2024 23.2.4.5 TypedArrayCreateSameType ( exemplar, argumentList )
function TypedArrayCreateSameType(exemplar, length) {
// Step 1.
var defaultConstructor = _ConstructorForTypedArray(exemplar);
// Step 2.
return TypedArrayCreateWithLength(defaultConstructor, length);
}
// ES6 draft 20150304 %TypedArray%.prototype.copyWithin
function TypedArrayCopyWithin(target, start, end = undefined) {
// This function is not generic.
@@ -848,6 +867,93 @@ function TypedArrayReverse() {
return O;
}
// ES2023 23.2.3.32 %TypedArray%.prototype.toReversed ( )
function TypedArrayToReversed() {
// Step 1.
var O = this;
// Step 2.
// This function is not generic.
// We want to make sure that we have an attached buffer, per spec prose.
var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
// If we got here, `this` is either a typed array or a wrapper for one.
// Step 3.
var len;
if (isTypedArray)
len = TypedArrayLength(O);
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayLengthMethod");
// Step 4.
var A = TypedArrayCreateSameType(O, len);
// Steps 5-6.
for (var k = 0; k < len; k++) {
var from = len - k - 1;
A[k] = O[from];
}
// Step 7.
return A;
}
// ES2023 23.2.3.36 %TypedArray%.prototype.with ( index, value )
function TypedArrayWith(index, value) {
// Step 1.
var O = this;
// Step 2.
// This function is not generic.
// We want to make sure that we have an attached buffer, per spec prose.
var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
// If we got here, `this` is either a typed array or a wrapper for one.
// Step 3.
var len;
if (isTypedArray)
len = TypedArrayLength(O);
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayLengthMethod");
// Steps 4-6.
var relativeIndex = ToInteger(index);
var actualIndex = relativeIndex >= 0 ? relativeIndex : len + relativeIndex;
// Steps 7-8.
var isBigIntContentType;
if (isTypedArray) {
isBigIntContentType = callFunction(TypedArrayContentTypeIsBigIntMethod, O);
} else {
isBigIntContentType = callFunction(CallTypedArrayMethodIfWrapped, O,
"TypedArrayContentTypeIsBigIntMethod");
}
var numericValue = isBigIntContentType ? ToBigInt(value) : ToNumber(value);
// Step 9.
if (actualIndex < 0 || actualIndex >= len)
ThrowRangeError(JSMSG_BAD_INDEX);
// Step 10.
var A = TypedArrayCreateSameType(O, len);
// Steps 11-12.
for (var k = 0; k < len; k++) {
var fromValue;
if (k === actualIndex) {
fromValue = numericValue;
} else {
fromValue = O[k];
}
A[k] = fromValue;
}
// Step 13.
return A;
}
// ES6 draft 20150220 22.2.3.22.1 %TypedArray%.prototype.set(array [, offset])
function SetFromNonTypedArray(target, array, targetOffset, targetLength, targetBuffer) {
assert(!IsPossiblyWrappedTypedArray(array),
+5 -1
View File
@@ -3209,7 +3209,9 @@ static const JSFunctionSpec array_methods[] = {
JS_SELF_HOSTED_FN("findLast", "ArrayFindLast", 1,0),
JS_SELF_HOSTED_FN("findLastIndex", "ArrayFindLastIndex", 1,0),
JS_SELF_HOSTED_FN("toReversed", "ArrayToReversed", 0,0),
JS_SELF_HOSTED_FN("toSpliced", "ArrayToSpliced", 2,0),
JS_SELF_HOSTED_FN("toSorted", "ArrayToSorted", 1,0),
JS_SELF_HOSTED_FN("with", "ArrayWith", 2,0),
JS_FS_END
};
@@ -3382,8 +3384,10 @@ array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto)
!DefineProperty(cx, unscopables, cx->names().includes, value) ||
!DefineProperty(cx, unscopables, cx->names().keys, value) ||
!DefineProperty(cx, unscopables, cx->names().toReversed, value) ||
!DefineProperty(cx, unscopables, cx->names().toSpliced, value) ||
!DefineProperty(cx, unscopables, cx->names().values, value) ||
!DefineProperty(cx, unscopables, cx->names().toSorted, value))
!DefineProperty(cx, unscopables, cx->names().toSorted, value) ||
!DefineProperty(cx, unscopables, cx->names().with, value))
{
return false;
}
+59
View File
@@ -0,0 +1,59 @@
<!doctype html>
<meta charset="utf-8">
<title>Array.prototype.toSpliced test</title>
<style>
body { font: 14px/1.4 sans-serif; padding: 16px; }
.pass { color: #0a0; }
.fail { color: #c00; }
pre { white-space: pre-wrap; }
</style>
<pre id="log"></pre>
<script>
(function() {
const log = document.getElementById("log");
function write(msg, cls) {
const line = document.createElement("div");
if (cls) line.className = cls;
line.textContent = msg;
log.appendChild(line);
}
window.assertEq = function(actual, expected, msg) {
if (actual !== expected) {
throw new Error((msg ? msg + ": " : "") +
"expected " + expected + ", got " + actual);
}
};
window.assertThrowsInstanceOf = function(fn, ctor, msg) {
let threw = false;
try {
fn();
} catch (e) {
if (e instanceof ctor) {
threw = true;
} else {
throw new Error((msg ? msg + ": " : "") +
"threw " + e + ", expected " + ctor.name);
}
}
if (!threw) {
throw new Error((msg ? msg + ": " : "") + "did not throw");
}
};
window.reportCompare = function() {};
let hadError = false;
window.addEventListener("error", function(e) {
hadError = true;
write("FAIL: " + e.message, "fail");
});
window.addEventListener("load", function() {
write("PASS: toSpliced.js loaded", "pass");
if (!hadError)
write("PASS: all toSpliced tests passed", "pass");
});
})();
</script>
<script src="toSpliced.js"></script>
+113
View File
@@ -0,0 +1,113 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/ */
assertEq(typeof Array.prototype.toSpliced, "function");
assertEq(Array.prototype.toSpliced.length, 2);
let desc = Object.getOwnPropertyDescriptor(Array.prototype, "toSpliced");
assertEq(desc.writable, true);
assertEq(desc.enumerable, false);
assertEq(desc.configurable, true);
assertThrowsInstanceOf(function () {
Array.prototype.toSpliced.call(null, 0, 0);
}, TypeError);
assertThrowsInstanceOf(function () {
Array.prototype.toSpliced.call(undefined, 0, 0);
}, TypeError);
// Non-mutating behavior.
let original = [1, 2, 3, 4];
let spliced = original.toSpliced(1, 2, "a", "b");
assertEq(original !== spliced, true);
assertEq(original.join(","), "1,2,3,4");
assertEq(spliced.join(","), "1,a,b,4");
assertEq(original.toSpliced().join(","), "1,2,3,4");
// Start index clamping and negatives.
assertEq([1, 2, 3].toSpliced(-1, 1, 9).join(","), "1,2,9");
assertEq([1, 2, 3].toSpliced(-99, 1, 9).join(","), "9,2,3");
assertEq([1, 2, 3].toSpliced(99, 1, 9).join(","), "1,2,3,9");
// deleteCount handling.
assertEq([1, 2, 3].toSpliced(1).join(","), "1");
assertEq([1, 2, 3].toSpliced(1, -3, 9).join(","), "1,9,2,3");
// Holes are materialized as undefined in copied segments.
let sparse = [1, , 3, 4];
let sparseResult = sparse.toSpliced(2, 1, "x");
assertEq(sparseResult.length, 4);
assertEq(sparseResult[0], 1);
assertEq(sparseResult[1], undefined);
assertEq(1 in sparseResult, true);
assertEq(sparseResult[2], "x");
assertEq(sparseResult[3], 4);
// Generic behavior on array-like values.
let arrayLike = { 0: "a", 1: "b", 3: "d", length: 4 };
let arrayLikeResult = Array.prototype.toSpliced.call(arrayLike, 1, 2, "X", "Y");
assertEq(Array.isArray(arrayLikeResult), true);
assertEq(arrayLikeResult.join(","), "a,X,Y,d");
// Element reads are ascending and skipped region is not read.
let accessLog = [];
let getterArr = {
length: 5,
get 0() {
accessLog.push(0);
return "z0";
},
get 1() {
accessLog.push(1);
throw new Error("must not be read");
},
get 2() {
accessLog.push(2);
throw new Error("must not be read");
},
get 3() {
accessLog.push(3);
return "z3";
},
get 4() {
accessLog.push(4);
return "z4";
},
};
let getterResult = Array.prototype.toSpliced.call(getterArr, 1, 2, "X");
assertEq(accessLog.join(","), "0,3,4");
assertEq(getterResult.join(","), "z0,X,z3,z4");
// constructor / Symbol.species is ignored and constructor is not read.
let constructorAccessed = false;
let speciesIgnored = [1, 2, 3];
Object.defineProperty(speciesIgnored, "constructor", {
get: function () {
constructorAccessed = true;
throw new Error("constructor should not be read");
},
configurable: true,
});
let speciesIgnoredResult = speciesIgnored.toSpliced(1, 1, 9);
assertEq(constructorAccessed, false);
assertEq(Array.isArray(speciesIgnoredResult), true);
assertEq(speciesIgnoredResult.join(","), "1,9,3");
// Length limit check happens before indexed reads.
let indexedRead = false;
let tooLong = {
length: 4294967296,
get 0() {
indexedRead = true;
throw new Error("index getter should not run");
},
};
assertThrowsInstanceOf(function () {
Array.prototype.toSpliced.call(tooLong, 0, 0);
}, RangeError);
assertEq(indexedRead, false);
// @@unscopables must include toSpliced.
assertEq(Array.prototype[Symbol.unscopables].toSpliced, true);
if (typeof reportCompare === "function") reportCompare(0, 0);
+59
View File
@@ -0,0 +1,59 @@
<!doctype html>
<meta charset="utf-8">
<title>Array.prototype.with test</title>
<style>
body { font: 14px/1.4 sans-serif; padding: 16px; }
.pass { color: #0a0; }
.fail { color: #c00; }
pre { white-space: pre-wrap; }
</style>
<pre id="log"></pre>
<script>
(function() {
const log = document.getElementById("log");
function write(msg, cls) {
const line = document.createElement("div");
if (cls) line.className = cls;
line.textContent = msg;
log.appendChild(line);
}
window.assertEq = function(actual, expected, msg) {
if (actual !== expected) {
throw new Error((msg ? msg + ": " : "") +
"expected " + expected + ", got " + actual);
}
};
window.assertThrowsInstanceOf = function(fn, ctor, msg) {
let threw = false;
try {
fn();
} catch (e) {
if (e instanceof ctor) {
threw = true;
} else {
throw new Error((msg ? msg + ": " : "") +
"threw " + e + ", expected " + ctor.name);
}
}
if (!threw) {
throw new Error((msg ? msg + ": " : "") + "did not throw");
}
};
window.reportCompare = function() {};
let hadError = false;
window.addEventListener("error", function(e) {
hadError = true;
write("FAIL: " + e.message, "fail");
});
window.addEventListener("load", function() {
write("PASS: with.js loaded", "pass");
if (!hadError)
write("PASS: all with tests passed", "pass");
});
})();
</script>
<script src="with.js"></script>
+107
View File
@@ -0,0 +1,107 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/ */
assertEq(typeof Array.prototype.with, "function");
assertEq(Array.prototype.with.length, 2);
let desc = Object.getOwnPropertyDescriptor(Array.prototype, "with");
assertEq(desc.writable, true);
assertEq(desc.enumerable, false);
assertEq(desc.configurable, true);
assertThrowsInstanceOf(function () {
Array.prototype.with.call(null, 0, 1);
}, TypeError);
assertThrowsInstanceOf(function () {
Array.prototype.with.call(undefined, 0, 1);
}, TypeError);
// Non-mutating behavior.
let original = [1, 2, 3];
let updated = original.with(1, 9);
assertEq(original !== updated, true);
assertEq(original.join(","), "1,2,3");
assertEq(updated.join(","), "1,9,3");
// Negative and -0 indices.
assertEq([1, 2, 3].with(-1, 7).join(","), "1,2,7");
assertEq([1, 2, 3].with(-0, 7).join(","), "7,2,3");
// Out-of-range index throws.
assertThrowsInstanceOf(function () {
[1, 2, 3].with(3, 9);
}, RangeError);
assertThrowsInstanceOf(function () {
[1, 2, 3].with(-4, 9);
}, RangeError);
// Holes are materialized as undefined in the result.
let sparse = [1, , 3];
let sparseResult = sparse.with(0, 9);
assertEq(sparseResult.length, 3);
assertEq(sparseResult[0], 9);
assertEq(sparseResult[1], undefined);
assertEq(sparseResult[2], 3);
assertEq(1 in sparseResult, true);
// Generic behavior on array-like values.
let arrayLike = { 0: "a", 2: "c", length: 3 };
let arrayLikeResult = Array.prototype.with.call(arrayLike, 1, "b");
assertEq(Array.isArray(arrayLikeResult), true);
assertEq(arrayLikeResult.length, 3);
assertEq(arrayLikeResult.join(","), "a,b,c");
// Reads occur in ascending index order, except replaced index isn't read.
let accessLog = [];
let getterArr = {
length: 3,
get 0() {
accessLog.push(0);
return "zero";
},
get 1() {
accessLog.push(1);
return "one";
},
get 2() {
accessLog.push(2);
return "two";
},
};
let getterResult = Array.prototype.with.call(getterArr, 1, "X");
assertEq(accessLog.join(","), "0,2");
assertEq(getterResult.join(","), "zero,X,two");
// constructor / Symbol.species is ignored and constructor is not read.
let constructorAccessed = false;
let speciesIgnored = [1, 2];
Object.defineProperty(speciesIgnored, "constructor", {
get: function () {
constructorAccessed = true;
throw new Error("constructor should not be read");
},
configurable: true,
});
let speciesIgnoredResult = speciesIgnored.with(0, 7);
assertEq(constructorAccessed, false);
assertEq(Array.isArray(speciesIgnoredResult), true);
assertEq(speciesIgnoredResult.join(","), "7,2");
// Length limit check happens before indexed reads.
let indexedRead = false;
let tooLong = {
length: 4294967296,
get 0() {
indexedRead = true;
throw new Error("index getter should not run");
},
};
assertThrowsInstanceOf(function () {
Array.prototype.with.call(tooLong, 0, 1);
}, RangeError);
assertEq(indexedRead, false);
// @@unscopables must include with.
assertEq(Array.prototype[Symbol.unscopables].with, true);
if (typeof reportCompare === "function") reportCompare(0, 0);
+89
View File
@@ -0,0 +1,89 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
assertEq(typeof Object.groupBy, "function");
assertEq(Object.groupBy.length, 2);
let desc = Object.getOwnPropertyDescriptor(Object, "groupBy");
assertEq(desc.enumerable, false);
assertEq(desc.writable, true);
assertEq(desc.configurable, true);
{
let values = [1, 2, 3, 4, 5];
let calls = [];
let grouped = Object.groupBy(values, function (value, index) {
"use strict";
assertEq(this, undefined);
calls.push([value, index]);
return value % 2 ? "odd" : "even";
});
assertEq(Object.getPrototypeOf(grouped), null);
assertDeepEq(Object.keys(grouped), ["odd", "even"]);
assertDeepEq(grouped.odd, [1, 3, 5]);
assertDeepEq(grouped.even, [2, 4]);
assertDeepEq(calls, [[1, 0], [2, 1], [3, 2], [4, 3], [5, 4]]);
}
{
let sym = Symbol("key");
let grouped = Object.groupBy([10, 11], value => value === 10 ? sym : 0);
assertDeepEq(Object.keys(grouped), ["0"]);
assertDeepEq(grouped[0], [11]);
let symbols = Object.getOwnPropertySymbols(grouped);
assertEq(symbols.length, 1);
assertEq(symbols[0], sym);
assertDeepEq(grouped[sym], [10]);
}
{
let grouped = Object.groupBy([1, 2], () => "__proto__");
assertEq(Object.getPrototypeOf(grouped), null);
assertDeepEq(grouped["__proto__"], [1, 2]);
let protoKeyDesc = Object.getOwnPropertyDescriptor(grouped, "__proto__");
assertEq(protoKeyDesc.enumerable, true);
assertEq(protoKeyDesc.writable, true);
assertEq(protoKeyDesc.configurable, true);
}
{
let closed = false;
let iterable = {
[Symbol.iterator]() {
let i = 0;
return {
next() {
i++;
if (i <= 3)
return { value: i, done: false };
return { done: true };
},
return() {
closed = true;
return { done: true };
}
};
}
};
assertThrowsValue(() => Object.groupBy(iterable, value => {
if (value === 2)
throw 42;
return "x";
}), 42);
assertEq(closed, true);
}
assertThrowsInstanceOf(() => Object.groupBy([], null), TypeError);
assertThrowsInstanceOf(() => Object.groupBy(null, null), TypeError);
assertThrowsInstanceOf(() => Object.groupBy({}, x => x), TypeError);
if (typeof reportCompare === "function")
reportCompare(true, true);
@@ -97,6 +97,10 @@ assertThrowsInstanceOf(() => {
array.values();
}, TypeError);
assertThrowsInstanceOf(() => {
array.with(POISON, POISON);
}, TypeError);
assertThrowsInstanceOf(() => {
array.every(POISON);
}, TypeError);
@@ -0,0 +1,53 @@
for (var constructor of anyTypedArrayConstructors) {
assertEq(constructor.prototype.toReversed.length, 0);
var original = new constructor([1, 2, 3, 4]);
var reversed = original.toReversed();
assertDeepEq(reversed, new constructor([4, 3, 2, 1]));
assertDeepEq(original, new constructor([1, 2, 3, 4]));
assertEq(reversed === original, false);
assertEq(reversed.constructor, constructor);
assertDeepEq(new constructor().toReversed(), new constructor());
assertDeepEq(new constructor([1]).toReversed(), new constructor([1]));
assertDeepEq(new constructor([1, 2, 3]).toReversed(), new constructor([3, 2, 1]));
var other = new constructor([7, 8, 9]);
Object.defineProperty(other, "length", {
get() {
throw new Error("length accessor called");
}
});
assertDeepEq(other.toReversed(), new constructor([9, 8, 7]));
var ctorIgnored = new constructor([5, 6, 7]);
Object.defineProperty(ctorIgnored, "constructor", {
get() {
throw new Error("constructor accessor called");
}
});
assertDeepEq(ctorIgnored.toReversed(), new constructor([7, 6, 5]));
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
new Proxy(new constructor(), {})];
invalidReceivers.forEach(invalidReceiver => {
assertThrowsInstanceOf(() => {
constructor.prototype.toReversed.call(invalidReceiver);
}, TypeError,
"Assert that toReversed fails if this value is not a TypedArray");
});
}
for (var constructor of typedArrayConstructors) {
if (typeof newGlobal === "function") {
var toReversed = newGlobal()[constructor.name].prototype.toReversed;
var original = new constructor([3, 2, 1]);
var reversed = toReversed.call(original);
assertDeepEq(reversed, new constructor([1, 2, 3]));
assertDeepEq(original, new constructor([3, 2, 1]));
}
}
if (typeof reportCompare === "function")
reportCompare(true, true);
+84
View File
@@ -0,0 +1,84 @@
for (var constructor of anyTypedArrayConstructors) {
assertEq(constructor.prototype.with.length, 2);
var original = new constructor([1, 2, 3, 4]);
var updated = original.with(1, 9);
assertDeepEq(updated, new constructor([1, 9, 3, 4]));
assertDeepEq(original, new constructor([1, 2, 3, 4]));
assertEq(updated === original, false);
assertEq(updated.constructor, constructor);
assertDeepEq(new constructor([1, 2, 3]).with(-1, 7),
new constructor([1, 2, 7]));
assertDeepEq(new constructor([1, 2, 3]).with(-0, 7),
new constructor([7, 2, 3]));
assertThrowsInstanceOf(() => {
new constructor([1, 2, 3]).with(3, 9);
}, RangeError);
assertThrowsInstanceOf(() => {
new constructor([1, 2, 3]).with(-4, 9);
}, RangeError);
var valueOrder = [];
var value = {
valueOf() {
valueOrder.push("valueOf");
return 9;
}
};
assertThrowsInstanceOf(() => {
new constructor([1, 2, 3]).with(9, value);
}, RangeError);
assertEq(valueOrder.join(","), "valueOf");
var ctorIgnored = new constructor([5, 6, 7]);
Object.defineProperty(ctorIgnored, "constructor", {
get() {
throw new Error("constructor accessor called");
}
});
assertDeepEq(ctorIgnored.with(0, 4), new constructor([4, 6, 7]));
if (constructor === Uint8ClampedArray ||
(typeof isSharedConstructor === "function" && isSharedConstructor(constructor) &&
constructor.name === Uint8ClampedArray.name))
{
assertDeepEq(new constructor([0, 1, 2]).with(1, 2.6),
new constructor([0, 3, 2]));
}
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
new Proxy(new constructor(), {})];
invalidReceivers.forEach(invalidReceiver => {
assertThrowsInstanceOf(() => {
constructor.prototype.with.call(invalidReceiver, 0, 1);
}, TypeError,
"Assert that with fails if this value is not a TypedArray");
});
}
for (var constructor of typedArrayConstructors) {
if (typeof newGlobal === "function") {
var withFn = newGlobal()[constructor.name].prototype.with;
var original = new constructor([3, 2, 1]);
var updated = withFn.call(original, 1, 8);
assertDeepEq(updated, new constructor([3, 8, 1]));
assertDeepEq(original, new constructor([3, 2, 1]));
}
}
if (typeof BigInt64Array === "function" && typeof BigUint64Array === "function") {
var bigIntArray = new BigInt64Array([1n, 2n, 3n]);
assertEq(BigInt64Array.prototype.with.length, 2);
assertDeepEq(bigIntArray.with(1, 9n), new BigInt64Array([1n, 9n, 3n]));
assertThrowsInstanceOf(() => bigIntArray.with(1, 9), TypeError);
var bigUintArray = new BigUint64Array([1n, 2n, 3n]);
assertDeepEq(bigUintArray.with(2, 4n), new BigUint64Array([1n, 2n, 4n]));
assertThrowsInstanceOf(() => bigUintArray.with(9, 1), TypeError);
}
if (typeof reportCompare === "function")
reportCompare(true, true);
+1
View File
@@ -430,6 +430,7 @@
macro(toLocaleString, toLocaleString, "toLocaleString") \
macro(toReversed, toReversed, "toReversed") \
macro(toSource, toSource, "toSource") \
macro(toSpliced, toSpliced, "toSpliced") \
macro(toSorted, toSorted, "toSorted") \
macro(toString, toString, "toString") \
macro(toUTCString, toUTCString, "toUTCString") \
+2 -2
View File
@@ -1938,8 +1938,8 @@ END_CASE(JSOP_LABEL)
CASE(JSOP_LOOPENTRY)
COUNT_COVERAGE();
// Attempt on-stack replacement with Baseline code.
if (jit::IsBaselineEnabled(cx)) {
// If not TLA module, attempt on-stack replacement with Baseline code.
if (jit::IsBaselineEnabled(cx) && !state.script()->hasTopLevelAwait()) {
jit::MethodStatus status = jit::CanEnterBaselineAtBranch(cx, REGS.fp(), false);
if (status == jit::Method_Error)
goto error;
+2
View File
@@ -1628,6 +1628,8 @@ TypedArrayObject::protoFunctions[] = {
JS_SELF_HOSTED_FN("reduce", "TypedArrayReduce", 1, 0),
JS_SELF_HOSTED_FN("reduceRight", "TypedArrayReduceRight", 1, 0),
JS_SELF_HOSTED_FN("reverse", "TypedArrayReverse", 0, 0),
JS_SELF_HOSTED_FN("toReversed", "TypedArrayToReversed", 0, 0),
JS_SELF_HOSTED_FN("with", "TypedArrayWith", 2, 0),
JS_SELF_HOSTED_FN("slice", "TypedArraySlice", 2, 0),
JS_SELF_HOSTED_FN("some", "TypedArraySome", 1, 0),
JS_SELF_HOSTED_FN("sort", "TypedArraySort", 1, 0),
+960
View File
@@ -0,0 +1,960 @@
/* -*- 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 "CSSNestingFlattener.h"
#include "mozilla/Assertions.h"
#include "nsString.h"
#include "nsTArray.h"
namespace mozilla {
namespace css {
namespace {
class CSSNestingFlattener final
{
using SelectorList = nsTArray<nsString>;
public:
explicit CSSNestingFlattener(const nsAString& aInput)
: mInput(aInput)
, mPos(0)
, mSawNesting(false)
{
}
bool Flatten(nsAString& aOutput)
{
nsAutoString flattened;
if (!ProcessStylesheet(flattened, false)) {
return false;
}
SkipWhitespaceAndComments();
if (mPos != mInput.Length() || !mSawNesting) {
return false;
}
aOutput.Assign(flattened);
return true;
}
private:
static bool
IsCSSWhitespace(char16_t aChar)
{
return aChar == ' ' || aChar == '\t' || aChar == '\r' ||
aChar == '\n' || aChar == '\f';
}
bool
AtEnd() const
{
return mPos >= mInput.Length();
}
char16_t
Peek() const
{
MOZ_ASSERT(!AtEnd(), "cannot peek past end");
return mInput.CharAt(mPos);
}
bool
StartsWithComment() const
{
return mPos + 1 < mInput.Length() &&
mInput.CharAt(mPos) == '/' &&
mInput.CharAt(mPos + 1) == '*';
}
bool
SkipComment()
{
MOZ_ASSERT(StartsWithComment(), "expected comment");
mPos += 2;
while (mPos + 1 < mInput.Length()) {
if (mInput.CharAt(mPos) == '*' && mInput.CharAt(mPos + 1) == '/') {
mPos += 2;
return true;
}
++mPos;
}
return false;
}
void
SkipWhitespaceAndComments()
{
while (!AtEnd()) {
if (IsCSSWhitespace(Peek())) {
++mPos;
continue;
}
if (StartsWithComment()) {
if (!SkipComment()) {
mPos = mInput.Length();
return;
}
continue;
}
break;
}
}
bool
SkipString(char16_t aQuote)
{
MOZ_ASSERT(!AtEnd() && Peek() == aQuote, "expected string start");
++mPos;
while (!AtEnd()) {
char16_t c = Peek();
++mPos;
if (c == aQuote) {
return true;
}
if (c == '\\' && !AtEnd()) {
++mPos;
continue;
}
if (c == '\n' || c == '\r' || c == '\f') {
return false;
}
}
return false;
}
static void
TrimWhitespace(nsAString& aText)
{
uint32_t start = 0;
uint32_t end = aText.Length();
while (start < end && IsCSSWhitespace(aText.CharAt(start))) {
++start;
}
while (end > start && IsCSSWhitespace(aText.CharAt(end - 1))) {
--end;
}
if (start == 0 && end == aText.Length()) {
return;
}
aText.Assign(Substring(aText, start, end - start));
}
bool
SplitSelectorList(const nsAString& aSelectorText, SelectorList& aSelectors)
{
uint32_t itemStart = 0;
int32_t parenDepth = 0;
int32_t bracketDepth = 0;
bool inComment = false;
char16_t stringQuote = 0;
for (uint32_t i = 0; i < aSelectorText.Length(); ++i) {
char16_t c = aSelectorText.CharAt(i);
if (inComment) {
if (c == '*' && i + 1 < aSelectorText.Length() &&
aSelectorText.CharAt(i + 1) == '/') {
inComment = false;
++i;
}
continue;
}
if (stringQuote) {
if (c == '\\') {
++i;
continue;
}
if (c == stringQuote) {
stringQuote = 0;
}
continue;
}
if (c == '/' && i + 1 < aSelectorText.Length() &&
aSelectorText.CharAt(i + 1) == '*') {
inComment = true;
++i;
continue;
}
if (c == '"' || c == '\'') {
stringQuote = c;
continue;
}
if (c == '(') {
++parenDepth;
continue;
}
if (c == ')' && parenDepth > 0) {
--parenDepth;
continue;
}
if (c == '[') {
++bracketDepth;
continue;
}
if (c == ']' && bracketDepth > 0) {
--bracketDepth;
continue;
}
if (c == ',' && parenDepth == 0 && bracketDepth == 0) {
nsAutoString selector;
selector.Assign(Substring(aSelectorText, itemStart, i - itemStart));
TrimWhitespace(selector);
if (!selector.IsEmpty()) {
aSelectors.AppendElement(selector);
}
itemStart = i + 1;
}
}
nsAutoString selector;
selector.Assign(Substring(aSelectorText, itemStart));
TrimWhitespace(selector);
if (!selector.IsEmpty()) {
aSelectors.AppendElement(selector);
}
return !aSelectors.IsEmpty();
}
bool
SelectorHasAmpersand(const nsAString& aSelector) const
{
bool inComment = false;
char16_t stringQuote = 0;
for (uint32_t i = 0; i < aSelector.Length(); ++i) {
char16_t c = aSelector.CharAt(i);
if (inComment) {
if (c == '*' && i + 1 < aSelector.Length() &&
aSelector.CharAt(i + 1) == '/') {
inComment = false;
++i;
}
continue;
}
if (stringQuote) {
if (c == '\\') {
++i;
continue;
}
if (c == stringQuote) {
stringQuote = 0;
}
continue;
}
if (c == '/' && i + 1 < aSelector.Length() &&
aSelector.CharAt(i + 1) == '*') {
inComment = true;
++i;
continue;
}
if (c == '"' || c == '\'') {
stringQuote = c;
continue;
}
if (c == '&') {
return true;
}
}
return false;
}
void
ReplaceAmpersands(const nsAString& aSelector,
const nsAString& aParent,
nsAString& aOutput) const
{
bool inComment = false;
char16_t stringQuote = 0;
for (uint32_t i = 0; i < aSelector.Length(); ++i) {
char16_t c = aSelector.CharAt(i);
if (inComment) {
aOutput.Append(c);
if (c == '*' && i + 1 < aSelector.Length() &&
aSelector.CharAt(i + 1) == '/') {
aOutput.Append('/');
inComment = false;
++i;
}
continue;
}
if (stringQuote) {
aOutput.Append(c);
if (c == '\\' && i + 1 < aSelector.Length()) {
aOutput.Append(aSelector.CharAt(i + 1));
++i;
continue;
}
if (c == stringQuote) {
stringQuote = 0;
}
continue;
}
if (c == '/' && i + 1 < aSelector.Length() &&
aSelector.CharAt(i + 1) == '*') {
aOutput.AppendLiteral("/*");
inComment = true;
++i;
continue;
}
if (c == '"' || c == '\'') {
aOutput.Append(c);
stringQuote = c;
continue;
}
if (c == '&') {
aOutput.Append(aParent);
continue;
}
aOutput.Append(c);
}
}
bool
ExpandNestedSelectors(const SelectorList& aParents,
const nsAString& aNestedSelectorText,
SelectorList& aSelectors)
{
SelectorList nestedSelectors;
if (!SplitSelectorList(aNestedSelectorText, nestedSelectors)) {
return false;
}
for (const nsString& nestedSelector : nestedSelectors) {
bool hasAmpersand = SelectorHasAmpersand(nestedSelector);
for (const nsString& parentSelector : aParents) {
nsAutoString combined;
if (hasAmpersand) {
ReplaceAmpersands(nestedSelector, parentSelector, combined);
} else {
combined.Assign(parentSelector);
if (!combined.IsEmpty()) {
combined.Append(' ');
}
combined.Append(nestedSelector);
}
TrimWhitespace(combined);
if (!combined.IsEmpty()) {
aSelectors.AppendElement(combined);
}
}
}
return !aSelectors.IsEmpty();
}
static void
AppendSelectors(const SelectorList& aSelectors, nsAString& aOutput)
{
for (uint32_t i = 0; i < aSelectors.Length(); ++i) {
if (i) {
aOutput.AppendLiteral(", ");
}
aOutput.Append(aSelectors[i]);
}
}
static bool
StartsNestedSelector(char16_t aChar)
{
switch (aChar) {
case '.':
case '#':
case '[':
case ':':
case '&':
case '|':
case '>':
case '+':
case '~':
case '*':
return true;
default:
return false;
}
}
static bool
StartsPotentialTypeSelector(char16_t aChar)
{
return (aChar >= 'a' && aChar <= 'z') ||
(aChar >= 'A' && aChar <= 'Z') ||
aChar == '_' ||
aChar == '\\' ||
aChar >= 0x80;
}
bool
LooksLikeTypeSelectorRule() const
{
if (AtEnd() || !StartsPotentialTypeSelector(Peek())) {
return false;
}
uint32_t pos = mPos;
int32_t parenDepth = 0;
int32_t bracketDepth = 0;
bool inComment = false;
char16_t stringQuote = 0;
while (pos < mInput.Length()) {
char16_t c = mInput.CharAt(pos);
if (inComment) {
if (c == '*' && pos + 1 < mInput.Length() &&
mInput.CharAt(pos + 1) == '/') {
inComment = false;
++pos;
}
++pos;
continue;
}
if (stringQuote) {
if (c == '\\' && pos + 1 < mInput.Length()) {
pos += 2;
continue;
}
if (c == stringQuote) {
stringQuote = 0;
}
++pos;
continue;
}
if (c == '/' && pos + 1 < mInput.Length() &&
mInput.CharAt(pos + 1) == '*') {
inComment = true;
pos += 2;
continue;
}
if (c == '"' || c == '\'') {
stringQuote = c;
++pos;
continue;
}
if (c == '(') {
++parenDepth;
++pos;
continue;
}
if (c == ')' && parenDepth > 0) {
--parenDepth;
++pos;
continue;
}
if (c == '[') {
++bracketDepth;
++pos;
continue;
}
if (c == ']' && bracketDepth > 0) {
--bracketDepth;
++pos;
continue;
}
if (parenDepth == 0 && bracketDepth == 0) {
if (c == '{') {
return true;
}
if (c == ';' || c == '}') {
return false;
}
}
++pos;
}
return false;
}
static bool
IsAtRuleNameChar(char16_t aChar)
{
return (aChar >= 'a' && aChar <= 'z') ||
(aChar >= 'A' && aChar <= 'Z') ||
(aChar >= '0' && aChar <= '9') ||
aChar == '-';
}
static void
LowercaseASCII(nsACString& aText)
{
for (uint32_t i = 0; i < aText.Length(); ++i) {
char c = aText.CharAt(i);
if (c >= 'A' && c <= 'Z') {
aText.BeginWriting()[i] = c - 'A' + 'a';
}
}
}
static bool
ShouldProcessGroupRule(const nsACString& aName)
{
return aName.EqualsLiteral("media") ||
aName.EqualsLiteral("supports") ||
aName.EqualsLiteral("document") ||
aName.EqualsLiteral("layer");
}
void
FlushDeclarations(const SelectorList& aSelectors,
nsAString& aDeclarations,
nsAString& aOutput)
{
nsAutoString declarations;
declarations.Assign(aDeclarations);
TrimWhitespace(declarations);
aDeclarations.Truncate();
if (declarations.IsEmpty()) {
return;
}
AppendSelectors(aSelectors, aOutput);
aOutput.AppendLiteral(" { ");
aOutput.Append(declarations);
aOutput.AppendLiteral(" }\n");
}
bool
ReadRawBlockBody(nsAString& aBody)
{
uint32_t start = mPos;
int32_t depth = 0;
while (!AtEnd()) {
char16_t c = Peek();
if (c == '"' || c == '\'') {
if (!SkipString(c)) {
return false;
}
continue;
}
if (StartsWithComment()) {
if (!SkipComment()) {
return false;
}
continue;
}
if (c == '{') {
++depth;
++mPos;
continue;
}
if (c == '}') {
if (depth == 0) {
aBody.Assign(Substring(mInput, start, mPos - start));
++mPos;
return true;
}
--depth;
++mPos;
continue;
}
++mPos;
}
return false;
}
bool
ReadQualifiedRulePrelude(nsAString& aPrelude)
{
uint32_t start = mPos;
int32_t parenDepth = 0;
int32_t bracketDepth = 0;
while (!AtEnd()) {
char16_t c = Peek();
if (c == '"' || c == '\'') {
if (!SkipString(c)) {
return false;
}
continue;
}
if (StartsWithComment()) {
if (!SkipComment()) {
return false;
}
continue;
}
if (c == '(') {
++parenDepth;
++mPos;
continue;
}
if (c == ')' && parenDepth > 0) {
--parenDepth;
++mPos;
continue;
}
if (c == '[') {
++bracketDepth;
++mPos;
continue;
}
if (c == ']' && bracketDepth > 0) {
--bracketDepth;
++mPos;
continue;
}
if (c == '{' && parenDepth == 0 && bracketDepth == 0) {
aPrelude.Assign(Substring(mInput, start, mPos - start));
TrimWhitespace(aPrelude);
++mPos;
return !aPrelude.IsEmpty();
}
if ((c == ';' || c == '}') && parenDepth == 0 && bracketDepth == 0) {
return false;
}
++mPos;
}
return false;
}
bool
ReadAtRulePrelude(nsAString& aPrelude, nsACString& aName, bool& aHasBlock)
{
MOZ_ASSERT(!AtEnd() && Peek() == '@', "expected at-rule");
uint32_t start = mPos;
++mPos;
aName.Truncate();
while (!AtEnd() && IsAtRuleNameChar(Peek())) {
char16_t c = Peek();
aName.Append(char(c <= 0x7f ? c : '?'));
++mPos;
}
LowercaseASCII(aName);
int32_t parenDepth = 0;
int32_t bracketDepth = 0;
while (!AtEnd()) {
char16_t c = Peek();
if (c == '"' || c == '\'') {
if (!SkipString(c)) {
return false;
}
continue;
}
if (StartsWithComment()) {
if (!SkipComment()) {
return false;
}
continue;
}
if (c == '(') {
++parenDepth;
++mPos;
continue;
}
if (c == ')' && parenDepth > 0) {
--parenDepth;
++mPos;
continue;
}
if (c == '[') {
++bracketDepth;
++mPos;
continue;
}
if (c == ']' && bracketDepth > 0) {
--bracketDepth;
++mPos;
continue;
}
if (parenDepth == 0 && bracketDepth == 0) {
if (c == ';') {
aPrelude.Assign(Substring(mInput, start, mPos - start));
TrimWhitespace(aPrelude);
++mPos;
aHasBlock = false;
return true;
}
if (c == '{') {
aPrelude.Assign(Substring(mInput, start, mPos - start));
TrimWhitespace(aPrelude);
++mPos;
aHasBlock = true;
return true;
}
}
++mPos;
}
return false;
}
bool
ConsumeDeclaration(nsAString& aDeclaration)
{
uint32_t start = mPos;
int32_t parenDepth = 0;
int32_t bracketDepth = 0;
int32_t braceDepth = 0;
while (!AtEnd()) {
char16_t c = Peek();
if (c == '"' || c == '\'') {
if (!SkipString(c)) {
return false;
}
continue;
}
if (StartsWithComment()) {
if (!SkipComment()) {
return false;
}
continue;
}
if (c == '(') {
++parenDepth;
++mPos;
continue;
}
if (c == ')' && parenDepth > 0) {
--parenDepth;
++mPos;
continue;
}
if (c == '[') {
++bracketDepth;
++mPos;
continue;
}
if (c == ']' && bracketDepth > 0) {
--bracketDepth;
++mPos;
continue;
}
if (c == '{') {
++braceDepth;
++mPos;
continue;
}
if (c == '}') {
if (braceDepth == 0 && parenDepth == 0 && bracketDepth == 0) {
break;
}
if (braceDepth > 0) {
--braceDepth;
}
++mPos;
continue;
}
if (c == ';' && parenDepth == 0 && bracketDepth == 0 &&
braceDepth == 0) {
++mPos;
break;
}
++mPos;
}
aDeclaration.Assign(Substring(mInput, start, mPos - start));
TrimWhitespace(aDeclaration);
if (aDeclaration.IsEmpty()) {
return false;
}
if (aDeclaration.Last() != ';') {
aDeclaration.Append(';');
}
return true;
}
bool
ParseAtRule(nsAString& aOutput, const SelectorList* aParents)
{
nsAutoString prelude;
nsAutoCString name;
bool hasBlock = false;
if (!ReadAtRulePrelude(prelude, name, hasBlock)) {
return false;
}
if (!hasBlock) {
aOutput.Append(prelude);
aOutput.AppendLiteral(";\n");
return true;
}
if (!ShouldProcessGroupRule(name)) {
nsAutoString body;
if (!ReadRawBlockBody(body)) {
return false;
}
aOutput.Append(prelude);
aOutput.AppendLiteral(" {");
aOutput.Append(body);
aOutput.AppendLiteral("}\n");
return true;
}
nsAutoString inner;
if (aParents) {
mSawNesting = true;
if (!ProcessStyleContext(*aParents, inner)) {
return false;
}
} else {
if (!ProcessStylesheet(inner, true)) {
return false;
}
}
aOutput.Append(prelude);
aOutput.AppendLiteral(" {\n");
aOutput.Append(inner);
aOutput.AppendLiteral("}\n");
return true;
}
bool
ParseQualifiedRule(nsAString& aOutput, const SelectorList* aParents)
{
nsAutoString prelude;
if (!ReadQualifiedRulePrelude(prelude)) {
return false;
}
SelectorList selectors;
if (aParents) {
mSawNesting = true;
if (!ExpandNestedSelectors(*aParents, prelude, selectors)) {
return false;
}
} else if (!SplitSelectorList(prelude, selectors)) {
return false;
}
return ProcessStyleContext(selectors, aOutput);
}
bool
ProcessStyleContext(const SelectorList& aSelectors, nsAString& aOutput)
{
nsAutoString declarations;
while (!AtEnd()) {
SkipWhitespaceAndComments();
if (AtEnd()) {
return false;
}
char16_t c = Peek();
if (c == '}') {
++mPos;
FlushDeclarations(aSelectors, declarations, aOutput);
return true;
}
if (c == '@') {
FlushDeclarations(aSelectors, declarations, aOutput);
if (!ParseAtRule(aOutput, &aSelectors)) {
return false;
}
continue;
}
if (StartsNestedSelector(c) || LooksLikeTypeSelectorRule()) {
FlushDeclarations(aSelectors, declarations, aOutput);
if (!ParseQualifiedRule(aOutput, &aSelectors)) {
return false;
}
continue;
}
nsAutoString declaration;
if (!ConsumeDeclaration(declaration)) {
return false;
}
if (!declarations.IsEmpty()) {
declarations.Append(' ');
}
declarations.Append(declaration);
}
return false;
}
bool
ProcessStylesheet(nsAString& aOutput, bool aStopAtBlockEnd)
{
while (!AtEnd()) {
SkipWhitespaceAndComments();
if (AtEnd()) {
return !aStopAtBlockEnd;
}
if (Peek() == '}') {
if (!aStopAtBlockEnd) {
return false;
}
++mPos;
return true;
}
if (Peek() == '@') {
if (!ParseAtRule(aOutput, nullptr)) {
return false;
}
} else {
if (!ParseQualifiedRule(aOutput, nullptr)) {
return false;
}
}
}
return !aStopAtBlockEnd;
}
const nsAString& mInput;
uint32_t mPos;
bool mSawNesting;
};
} // namespace
bool
FlattenBasicCSSNesting(const nsAString& aInput, nsAString& aOutput)
{
CSSNestingFlattener flattener(aInput);
return flattener.Flatten(aOutput);
}
} // namespace css
} // namespace mozilla
+19
View File
@@ -0,0 +1,19 @@
/* -*- 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/. */
#ifndef CSSNestingFlattener_h
#define CSSNestingFlattener_h
class nsAString;
namespace mozilla {
namespace css {
bool FlattenBasicCSSNesting(const nsAString& aInput, nsAString& aOutput);
} // namespace css
} // namespace mozilla
#endif // CSSNestingFlattener_h
+1
View File
@@ -126,6 +126,7 @@ UNIFIED_SOURCES += [
'CounterStyleManager.cpp',
'CSS.cpp',
'CSSLexer.cpp',
'CSSNestingFlattener.cpp',
'CSSRuleList.cpp',
'CSSStyleSheet.cpp',
'CSSVariableDeclarations.cpp',
+13 -1
View File
@@ -7,6 +7,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Maybe.h"
#include "mozilla/Move.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/TypedEnumBits.h"
@@ -17,6 +18,7 @@
#include <regex> // for std::regex and std::regex_match
#include "nsCSSParser.h"
#include "CSSNestingFlattener.h"
#include "nsAlgorithm.h"
#include "nsCSSProps.h"
#include "nsCSSKeywords.h"
@@ -71,6 +73,7 @@ static bool sMozGradientsEnabled;
static bool sControlCharVisibility;
static bool sLegacyNegationPseudoClassEnabled;
static bool sCascadeLayersEnabled;
static bool sNestingEnabled;
const uint32_t
nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = {
@@ -1837,7 +1840,14 @@ CSSParserImpl::ParseSheet(const nsAString& aInput,
"Sheet principal does not match passed principal");
#endif
nsCSSScanner scanner(aInput, aLineNumber);
nsAutoString flattenedInput;
const nsAString* input = &aInput;
if (sNestingEnabled &&
mozilla::css::FlattenBasicCSSNesting(aInput, flattenedInput)) {
input = &flattenedInput;
}
nsCSSScanner scanner(*input, aLineNumber);
css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI);
InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal);
@@ -19032,6 +19042,8 @@ nsCSSParser::Startup()
"layout.css.legacy-negation-pseudo.enabled");
Preferences::AddBoolVarCache(&sCascadeLayersEnabled,
"layout.css.cascade-layers.enabled");
Preferences::AddBoolVarCache(&sNestingEnabled,
"layout.css.nesting.enabled");
}
nsCSSParser::nsCSSParser(mozilla::css::Loader* aLoader,
+3
View File
@@ -71,6 +71,9 @@ support-files = file_animations_with_disabled_properties.html
[test_at_rule_parse_serialize.html]
[test_attribute_selector_eof_behavior.html]
[test_background_blend_mode.html]
[test_basic_nesting_flattening.html]
[test_nesting_flattening_parser_edges.html]
[test_nesting_flattening_recovery.html]
[test_box_size_keywords.html]
[test_bug73586.html]
[test_bug74880.html]
@@ -0,0 +1,146 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test for Basic CSS Nesting Flattening</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="scope" class="scope order">
<span id="desc" class="desc"></span>
</div>
<div id="button" class="button active"></div>
<pre id="standalone-log"></pre>
<script>
"use strict";
function colorOf(win, element, property) {
return win.getComputedStyle(element).getPropertyValue(property);
}
function appendTestSheet() {
var style = document.createElement("style");
style.textContent =
".scope {\n" +
" color: rgb(1, 2, 3);\n" +
" .desc {\n" +
" color: rgb(4, 5, 6);\n" +
" }\n" +
" span {\n" +
" border-left-style: solid;\n" +
" border-left-color: rgb(19, 20, 21);\n" +
" }\n" +
" span:first-child, span:last-child {\n" +
" border-bottom-style: solid;\n" +
" border-bottom-color: rgb(22, 23, 24);\n" +
" }\n" +
" background-color: rgb(7, 8, 9);\n" +
"}\n" +
"\n" +
".button {\n" +
" &.active {\n" +
" color: rgb(10, 11, 12);\n" +
" }\n" +
"}\n" +
"\n" +
".order {\n" +
" border-top-style: solid;\n" +
" @media all {\n" +
" & {\n" +
" border-top-color: rgb(13, 14, 15);\n" +
" }\n" +
" }\n" +
" border-right-style: solid;\n" +
" border-right-color: rgb(16, 17, 18);\n" +
"}\n";
document.head.appendChild(style);
return style;
}
function runChecks(style, report) {
var scope = document.getElementById("scope");
var desc = document.getElementById("desc");
var button = document.getElementById("button");
report(colorOf(window, scope, "color") === "rgb(1, 2, 3)",
"outer rule declarations should apply",
colorOf(window, scope, "color"),
"rgb(1, 2, 3)");
report(colorOf(window, desc, "color") === "rgb(4, 5, 6)",
"nested descendant rule should be flattened",
colorOf(window, desc, "color"),
"rgb(4, 5, 6)");
report(colorOf(window, desc, "border-left-color") === "rgb(19, 20, 21)",
"nested type selector rule should be flattened",
colorOf(window, desc, "border-left-color"),
"rgb(19, 20, 21)");
report(colorOf(window, desc, "border-bottom-color") === "rgb(22, 23, 24)",
"nested type selector pseudos should be flattened",
colorOf(window, desc, "border-bottom-color"),
"rgb(22, 23, 24)");
report(colorOf(window, scope, "background-color") === "rgb(7, 8, 9)",
"declarations after a nested rule should preserve order",
colorOf(window, scope, "background-color"),
"rgb(7, 8, 9)");
report(colorOf(window, button, "color") === "rgb(10, 11, 12)",
"ampersand selectors should be expanded",
colorOf(window, button, "color"),
"rgb(10, 11, 12)");
report(colorOf(window, scope, "border-top-color") === "rgb(13, 14, 15)",
"nested group rules should target the parent selector",
colorOf(window, scope, "border-top-color"),
"rgb(13, 14, 15)");
report(colorOf(window, scope, "border-right-color") === "rgb(16, 17, 18)",
"declarations after nested group rules should still apply",
colorOf(window, scope, "border-right-color"),
"rgb(16, 17, 18)");
report(style.sheet.cssRules.length === 9,
"flattening should produce flat top-level rules",
String(style.sheet.cssRules.length),
"9");
}
function runStandalone() {
var log = document.getElementById("standalone-log");
var lines = [
"Standalone mode.",
"This page only demonstrates nesting if layout.css.nesting.enabled is already true in the browser.",
""
];
var style = appendTestSheet();
runChecks(style, function(pass, message, actual, expected) {
lines.push((pass ? "PASS" : "FAIL") + ": " + message);
if (!pass) {
lines.push(" expected: " + expected);
lines.push(" actual: " + actual);
}
});
log.textContent = lines.join("\n");
}
function runMochitest() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({
set: [["layout.css.nesting.enabled", true]]
}, function() {
var style = appendTestSheet();
runChecks(style, function(pass, message, actual, expected) {
is(actual, expected, message);
});
SimpleTest.finish();
});
}
if (typeof SimpleTest !== "undefined" && typeof SpecialPowers !== "undefined") {
runMochitest();
} else {
runStandalone();
}
</script>
</body>
</html>
@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test CSS Nesting Flattening Parser Edges</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="scope" class="scope">
<span id="firstSpan" class="desc"></span>
<span id="middleSpan" class="middle"></span>
<span id="escapedSpan" class="1foo"></span>
<svg id="svgRoot" xmlns="http://www.w3.org/2000/svg" width="10" height="10">
<rect id="nsRect" width="10" height="10"></rect>
</svg>
</div>
<div id="afterMalformed" class="after-malformed"></div>
<div id="afterTarget" class="after-target"></div>
<pre id="standalone-log"></pre>
<script>
"use strict";
function propOf(win, element, property) {
return win.getComputedStyle(element).getPropertyValue(property);
}
function appendTestSheet() {
var style = document.createElement("style");
style.textContent =
"@namespace svg url(http://www.w3.org/2000/svg);\n" +
".scope {\n" +
" --payload: { alpha: 1; beta: 2; };\n" +
" color: rgb(1, 2, 3);\n" +
" span:first-of-type, span:last-of-type {\n" +
" color: rgb(30, 31, 32);\n" +
" }\n" +
" .\\31 foo {\n" +
" border-left-style: solid;\n" +
" border-left-color: rgb(40, 41, 42);\n" +
" }\n" +
" svg|rect {\n" +
" stroke: rgb(50, 51, 52);\n" +
" stroke-width: 1px;\n" +
" }\n" +
"}\n" +
"\n" +
".after-malformed {\n" +
" color: rgb(60, 61, 62);\n" +
" : {\n" +
" color: rgb(70, 71, 72);\n" +
" }\n" +
" background-color: rgb(80, 81, 82);\n" +
"}\n" +
"\n" +
".after-target {\n" +
" color: rgb(90, 91, 92);\n" +
"}\n";
document.head.appendChild(style);
return style;
}
function runChecks(style, report) {
var scope = document.getElementById("scope");
var firstSpan = document.getElementById("firstSpan");
var middleSpan = document.getElementById("middleSpan");
var escapedSpan = document.getElementById("escapedSpan");
var rect = document.getElementById("nsRect");
var afterMalformed = document.getElementById("afterMalformed");
var afterTarget = document.getElementById("afterTarget");
var payload = propOf(window, scope, "--payload");
report(payload.indexOf("alpha") !== -1 && payload.indexOf("beta") !== -1,
"custom property payload should survive flattening",
payload,
"contains alpha and beta");
report(propOf(window, scope, "color") === "rgb(1, 2, 3)",
"base declaration should apply",
propOf(window, scope, "color"),
"rgb(1, 2, 3)");
report(propOf(window, firstSpan, "color") === "rgb(30, 31, 32)",
"nested pseudo selector should style first span",
propOf(window, firstSpan, "color"),
"rgb(30, 31, 32)");
report(propOf(window, escapedSpan, "color") === "rgb(30, 31, 32)",
"nested pseudo selector should style last span",
propOf(window, escapedSpan, "color"),
"rgb(30, 31, 32)");
report(propOf(window, middleSpan, "color") === "rgb(1, 2, 3)",
"middle span should keep inherited scope color",
propOf(window, middleSpan, "color"),
"rgb(1, 2, 3)");
report(propOf(window, escapedSpan, "border-left-color") === "rgb(40, 41, 42)",
"escaped class selector should match",
propOf(window, escapedSpan, "border-left-color"),
"rgb(40, 41, 42)");
report(propOf(window, rect, "stroke") === "rgb(50, 51, 52)",
"namespace selector should match nested SVG rect",
propOf(window, rect, "stroke"),
"rgb(50, 51, 52)");
report(propOf(window, afterMalformed, "color") === "rgb(60, 61, 62)",
"declaration before malformed nested selector should apply",
propOf(window, afterMalformed, "color"),
"rgb(60, 61, 62)");
report(propOf(window, afterMalformed, "background-color") === "rgb(80, 81, 82)",
"declaration after malformed nested selector should still apply",
propOf(window, afterMalformed, "background-color"),
"rgb(80, 81, 82)");
report(propOf(window, afterTarget, "color") === "rgb(90, 91, 92)",
"subsequent top-level rules should still parse",
propOf(window, afterTarget, "color"),
"rgb(90, 91, 92)");
}
function runStandalone() {
var log = document.getElementById("standalone-log");
var lines = [
"Standalone mode.",
"This page only demonstrates nesting if layout.css.nesting.enabled is already true in the browser.",
""
];
var style = appendTestSheet();
runChecks(style, function(pass, message, actual, expected) {
lines.push((pass ? "PASS" : "FAIL") + ": " + message);
if (!pass) {
lines.push(" expected: " + expected);
lines.push(" actual: " + actual);
}
});
log.textContent = lines.join("\n");
}
function runMochitest() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({
set: [["layout.css.nesting.enabled", true]]
}, function() {
var style = appendTestSheet();
runChecks(style, function(pass, message, actual, expected) {
ok(pass, message + " (expected: " + expected + ", actual: " + actual + ")");
});
SimpleTest.finish();
});
}
if (typeof SimpleTest !== "undefined" && typeof SpecialPowers !== "undefined") {
runMochitest();
} else {
runStandalone();
}
</script>
</body>
</html>
@@ -0,0 +1,149 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test CSS Nesting Flattening Recovery Paths</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="recBase" class="rec-base"><span id="recBaseChild"></span></div>
<div id="recMalformed" class="rec-malformed"></div>
<div id="recGroup" class="rec-group"></div>
<div id="recTail" class="rec-tail"></div>
<pre id="standalone-log"></pre>
<script>
"use strict";
function propOf(win, element, property) {
return win.getComputedStyle(element).getPropertyValue(property);
}
function appendTestSheet() {
var style = document.createElement("style");
style.textContent =
".rec-base {\n" +
" color: rgb(1, 2, 3);\n" +
" |* {\n" +
" color: rgb(4, 5, 6);\n" +
" }\n" +
" background-color: rgb(7, 8, 9);\n" +
"}\n" +
"\n" +
".rec-malformed {\n" +
" color: rgb(20, 21, 22);\n" +
" : {\n" +
" color: rgb(23, 24, 25);\n" +
" }\n" +
" border-top-style: solid;\n" +
" border-top-color: rgb(26, 27, 28);\n" +
"}\n" +
"\n" +
".rec-group {\n" +
" color: rgb(32, 33, 34);\n" +
" @counter-style rec-counter {\n" +
" system: fixed;\n" +
" symbols: a;\n" +
" }\n" +
" background-color: rgb(35, 36, 37);\n" +
"}\n" +
"\n" +
".rec-tail {\n" +
" color: rgb(50, 51, 52);\n" +
"}\n";
document.head.appendChild(style);
return style;
}
function runChecks(style, report) {
var recBase = document.getElementById("recBase");
var recBaseChild = document.getElementById("recBaseChild");
var recMalformed = document.getElementById("recMalformed");
var recGroup = document.getElementById("recGroup");
var recTail = document.getElementById("recTail");
report(propOf(window, recBase, "color") === "rgb(1, 2, 3)",
"unsupported nested selector should not wipe earlier declarations",
propOf(window, recBase, "color"),
"rgb(1, 2, 3)");
report(propOf(window, recBase, "background-color") === "rgb(7, 8, 9)",
"unsupported nested selector should not wipe later declarations",
propOf(window, recBase, "background-color"),
"rgb(7, 8, 9)");
report(propOf(window, recBaseChild, "color") === "rgb(1, 2, 3)",
"unsupported nested selector should not restyle descendants unexpectedly",
propOf(window, recBaseChild, "color"),
"rgb(1, 2, 3)");
report(propOf(window, recMalformed, "color") === "rgb(20, 21, 22)",
"malformed nested selector should keep declaration before it",
propOf(window, recMalformed, "color"),
"rgb(20, 21, 22)");
report(propOf(window, recMalformed, "border-top-color") === "rgb(26, 27, 28)",
"malformed nested selector should keep declaration after it",
propOf(window, recMalformed, "border-top-color"),
"rgb(26, 27, 28)");
report(propOf(window, recGroup, "color") === "rgb(32, 33, 34)",
"nested unsupported at-rule should keep declaration before it",
propOf(window, recGroup, "color"),
"rgb(32, 33, 34)");
report(propOf(window, recGroup, "background-color") === "rgb(35, 36, 37)",
"nested unsupported at-rule should keep declaration after it",
propOf(window, recGroup, "background-color"),
"rgb(35, 36, 37)");
report(propOf(window, recTail, "color") === "rgb(50, 51, 52)",
"rules after recovery scenarios should still parse",
propOf(window, recTail, "color"),
"rgb(50, 51, 52)");
report(style.sheet.cssRules.length >= 4,
"stylesheet should remain parseable after recovery scenarios",
String(style.sheet.cssRules.length),
">= 4");
}
function runStandalone() {
var log = document.getElementById("standalone-log");
var lines = [
"Standalone mode.",
"This page only demonstrates nesting if layout.css.nesting.enabled is already true in the browser.",
""
];
var style = appendTestSheet();
runChecks(style, function(pass, message, actual, expected) {
lines.push((pass ? "PASS" : "FAIL") + ": " + message);
if (!pass) {
lines.push(" expected: " + expected);
lines.push(" actual: " + actual);
}
});
log.textContent = lines.join("\n");
}
function runMochitest() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({
set: [["layout.css.nesting.enabled", true]]
}, function() {
var style = appendTestSheet();
runChecks(style, function(pass, message, actual, expected) {
ok(pass, message + " (expected: " + expected + ", actual: " + actual + ")");
});
SimpleTest.finish();
});
}
if (typeof SimpleTest !== "undefined" && typeof SpecialPowers !== "undefined") {
runMochitest();
} else {
runStandalone();
}
</script>
</body>
</html>
+1
View File
@@ -81,6 +81,7 @@ class nsDisplayTableBackgroundSet {
nsDisplayTableBackgroundSet(nsDisplayListBuilder* aBuilder, nsIFrame* aTable)
: mBuilder(aBuilder) {
mPrevTableBackgroundSet = mBuilder->SetTableBackgroundSet(this);
mBuilder->FindReferenceFrameFor(aTable, &mToReferenceFrame);
mDirtyRect = mBuilder->GetDirtyRect();
}
+4
View File
@@ -48,10 +48,12 @@ static AVMutex mutex = AV_MUTEX_INITIALIZER;
#define LINE_SZ 1024
#if HAVE_VALGRIND_VALGRIND_H
#ifdef MOZ_VALGRIND
#include <valgrind/valgrind.h>
/* this is the log level at which valgrind will output a full backtrace */
#define BACKTRACE_LOGLEVEL AV_LOG_ERROR
#endif
#endif
static int av_log_level = AV_LOG_INFO;
static int flags;
@@ -395,9 +397,11 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[3].str);
#if CONFIG_VALGRIND_BACKTRACE
#ifdef MOZ_VALGRIND
if (level <= BACKTRACE_LOGLEVEL)
VALGRIND_PRINTF_BACKTRACE("%s", "");
#endif
#endif
end:
av_bprint_finalize(part+3, NULL);
ff_mutex_unlock(&mutex);
@@ -48,12 +48,16 @@ extern "C" {
int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz);
int64_t vp9_block_error_neon(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz);
#if HAVE_SVE
int64_t vp9_block_error_sve(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz);
#endif
RTCD_EXTERN int64_t (*vp9_block_error)(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz);
int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size);
int64_t vp9_block_error_fp_neon(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size);
#if HAVE_SVE
int64_t vp9_block_error_fp_sve(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size);
#endif
RTCD_EXTERN int64_t (*vp9_block_error_fp)(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size);
int vp9_diamond_search_sad_c(const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, uint32_t start_mv_sad, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp9_sad_table *sad_fn_ptr, const struct mv *center_mv);
@@ -112,9 +116,13 @@ static void setup_rtcd_internal(void)
(void)flags;
vp9_block_error = vp9_block_error_neon;
#if HAVE_SVE
if (flags & HAS_SVE) vp9_block_error = vp9_block_error_sve;
#endif
vp9_block_error_fp = vp9_block_error_fp_neon;
#if HAVE_SVE
if (flags & HAS_SVE) vp9_block_error_fp = vp9_block_error_fp_sve;
#endif
}
#endif
@@ -12,8 +12,8 @@
.equ HAVE_NEON , 1
.equ HAVE_NEON_DOTPROD , 1
.equ HAVE_NEON_I8MM , 1
.equ HAVE_SVE , 1
.equ HAVE_SVE2 , 1
.equ HAVE_SVE , 0
.equ HAVE_SVE2 , 0
.equ HAVE_MIPS32 , 0
.equ HAVE_DSPR2 , 0
.equ HAVE_MSA , 0
+3 -3
View File
@@ -8,7 +8,7 @@
/* This file automatically generated by configure. Do not edit! */
#ifndef VPX_CONFIG_H
#define VPX_CONFIG_H
#define RESTRICT
#define RESTRICT
#define INLINE inline
#define VPX_ARCH_ARM 1
#define VPX_ARCH_AARCH64 1
@@ -21,8 +21,8 @@
#define HAVE_NEON 1
#define HAVE_NEON_DOTPROD 1
#define HAVE_NEON_I8MM 1
#define HAVE_SVE 1
#define HAVE_SVE2 1
#define HAVE_SVE 0
#define HAVE_SVE2 0
#define HAVE_MIPS32 0
#define HAVE_DSPR2 0
#define HAVE_MSA 0
@@ -926,7 +926,9 @@ void vpx_subtract_block_neon(int rows, int cols, int16_t *diff_ptr, ptrdiff_t di
uint64_t vpx_sum_squares_2d_i16_c(const int16_t *src, int stride, int size);
uint64_t vpx_sum_squares_2d_i16_neon(const int16_t *src, int stride, int size);
#if HAVE_SVE
uint64_t vpx_sum_squares_2d_i16_sve(const int16_t *src, int stride, int size);
#endif
RTCD_EXTERN uint64_t (*vpx_sum_squares_2d_i16)(const int16_t *src, int stride, int size);
void vpx_tm_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left);
@@ -1160,7 +1162,9 @@ static void setup_rtcd_internal(void)
vpx_sse = vpx_sse_neon;
if (flags & HAS_NEON_DOTPROD) vpx_sse = vpx_sse_neon_dotprod;
vpx_sum_squares_2d_i16 = vpx_sum_squares_2d_i16_neon;
#if HAVE_SVE
if (flags & HAS_SVE) vpx_sum_squares_2d_i16 = vpx_sum_squares_2d_i16_sve;
#endif
vpx_variance16x16 = vpx_variance16x16_neon;
if (flags & HAS_NEON_DOTPROD) vpx_variance16x16 = vpx_variance16x16_neon_dotprod;
vpx_variance16x32 = vpx_variance16x32_neon;
+35 -9
View File
@@ -27,6 +27,7 @@ if CONFIG['CPU_ARCH'] == 'x86_64':
else: # Linux, BSDs, etc.
ASFLAGS += [ '-I%s/media/libvpx/config/linux/x64/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/linux/x64/' % TOPSRCDIR ]
elif CONFIG['CPU_ARCH'] == 'x86':
EXPORTS.vpx += files['IA32_EXPORTS']
SOURCES += files['IA32_SOURCES']
@@ -36,9 +37,10 @@ elif CONFIG['CPU_ARCH'] == 'x86':
elif CONFIG['OS_TARGET'] == 'Darwin':
ASFLAGS += [ '-I%s/media/libvpx/config/mac/ia32/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/mac/ia32/' % TOPSRCDIR ]
else: # Linux, BSDs, etc.
else:
ASFLAGS += [ '-I%s/media/libvpx/config/linux/ia32/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/linux/ia32/' % TOPSRCDIR ]
elif CONFIG['CPU_ARCH'] == 'arm':
EXPORTS.vpx += files['ARM_EXPORTS']
ASFLAGS += [
@@ -64,35 +66,50 @@ elif CONFIG['CPU_ARCH'] == 'arm':
ASFLAGS += [
'-no-integrated-as',
]
elif CONFIG['CPU_ARCH'] == 'aarch64':
EXPORTS.vpx += files['AARCH64_EXPORTS']
SOURCES += files['AARCH64_SOURCES']
# Enable SVE only on macOS (Apple Clang toolchain)
if CONFIG['OS_TARGET'] == 'Darwin':
SOURCES += files['AARCH64_SOURCES']
else:
SOURCES += [
f for f in files['AARCH64_SOURCES']
if '_sve.c' not in f and '_sve2.c' not in f
]
if CONFIG['OS_TARGET'] == 'Darwin':
ASFLAGS += [ '-I%s/media/libvpx/config/mac/arm64/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/mac/arm64/' % TOPSRCDIR ]
else: # Linux, BSDs, etc.
else:
ASFLAGS += [ '-I%s/media/libvpx/config/linux/arm64/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/linux/arm64/' % TOPSRCDIR ]
elif CONFIG['CPU_ARCH'] == 'mips32':
EXPORTS.vpx += files['MIPS32_EXPORTS']
SOURCES += files['MIPS32_SOURCES']
ASFLAGS += [ '-I%s/media/libvpx/config/linux/mips32/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/linux/mips32/' % TOPSRCDIR ]
elif CONFIG['CPU_ARCH'] == 'mips64':
EXPORTS.vpx += files['MIPS64_EXPORTS']
SOURCES += files['MIPS64_SOURCES']
ASFLAGS += [ '-I%s/media/libvpx/config/linux/mips64/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/linux/mips64/' % TOPSRCDIR ]
elif CONFIG['CPU_ARCH'] == 'ppc64le':
EXPORTS.vpx += files['PPC64LE_EXPORTS']
SOURCES += files['PPC64LE_SOURCES']
ASFLAGS += [ '-I%s/media/libvpx/config/linux/ppc64le/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/linux/ppc64le/' % TOPSRCDIR ]
elif CONFIG['CPU_ARCH'].startswith('loongarch64'):
EXPORTS.vpx += files['LOONGARCH64_EXPORTS']
SOURCES += files['LOONGARCH64_SOURCES']
ASFLAGS += [ '-I%s/media/libvpx/config/linux/loongarch64/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/linux/loongarch64/' % TOPSRCDIR ]
else:
# Generic C-only configuration used by unsupported targets.
EXPORTS.vpx += files['GENERIC_EXPORTS']
@@ -100,6 +117,7 @@ else:
ASFLAGS += [ '-I%s/media/libvpx/config/generic/' % TOPSRCDIR ]
CFLAGS += [ '-I%s/media/libvpx/config/generic/' % TOPSRCDIR ]
if CONFIG['GKMEDIAS_SHARED_LIBRARY']:
NO_VISIBILITY_FLAGS = True
@@ -110,6 +128,7 @@ FINAL_LIBRARY = 'gkmedias'
DEFINES['HAVE_CONFIG_H'] = 'vpx_config.h'
if CONFIG['CLANG_CL'] or not CONFIG['_MSC_VER']:
for f in SOURCES:
if f.endswith('.c'):
@@ -135,10 +154,14 @@ if CONFIG['CLANG_CL'] or not CONFIG['_MSC_VER']:
SOURCES[f].flags += ['-march=armv8.2-a+dotprod']
if 'neon_i8mm.c' in f:
SOURCES[f].flags += ['-march=armv8.2-a+dotprod+i8mm']
if '_sve.c' in f:
SOURCES[f].flags += ['-march=armv8.2-a+dotprod+i8mm+sve']
if '_sve2.c' in f:
SOURCES[f].flags += ['-march=armv9-a+i8mm+sve2']
# Only apply SVE flags on macOS
if CONFIG['OS_TARGET'] == 'Darwin':
if '_sve.c' in f:
SOURCES[f].flags += ['-march=armv8.2-a+dotprod+i8mm+sve']
if '_sve2.c' in f:
SOURCES[f].flags += ['-march=armv9-a+i8mm+sve2']
if '_vsx.c' in f:
SOURCES[f].flags += ['-maltivec', '-mvsx']
if '_msa.c' in f:
@@ -148,18 +171,21 @@ if CONFIG['CLANG_CL'] or not CONFIG['_MSC_VER']:
if '_lasx.c' in f:
SOURCES[f].flags += ['-mlasx']
# Suppress warnings in third-party code.
if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
CFLAGS += [
'-Wno-sign-compare',
'-Wno-unused-function', # so many of these warnings; just ignore them
'-Wno-unused-function',
]
if CONFIG['CLANG_CXX'] or CONFIG['CLANG_CL']:
CFLAGS += [
'-Wno-unreachable-code',
'-Wno-unneeded-internal-declaration',
]
ASFLAGS += CONFIG['VPX_ASFLAGS']
ASFLAGS += [
'-I.',
@@ -168,5 +194,5 @@ ASFLAGS += [
CFLAGS += [
'-I%s/media/libvpx/libvpx' % TOPSRCDIR,
'-I%s/media/libvpx/config' % TOPSRCDIR, # vpx_version.h
'-I%s/media/libvpx/config' % TOPSRCDIR,
]
-3
View File
@@ -148,9 +148,6 @@
#elif defined(__hppa__)
#define ARCH_CPU_HPPA 1
#define ARCH_CPU_32_BITS 1
#elif defined(__ia64__)
#define ARCH_CPU_IA64 1
#define ARCH_CPU_64_BITS 1
#elif defined(__s390x__)
#define ARCH_CPU_S390X 1
#define ARCH_CPU_64_BITS 1
@@ -571,17 +571,16 @@ using ::std::tuple_size;
#endif // GTEST_HAS_TR1_TUPLE
// Determines whether clone(2) is supported.
// Usually it will only be available on Linux, excluding
// Linux on the Itanium architecture, and x86 Android.
// Usually it will only be available on Linux.
// Also see http://linux.die.net/man/2/clone.
#ifndef GTEST_HAS_CLONE
// The user didn't tell us, so we need to figure it out.
# if GTEST_OS_LINUX && !defined(__ia64__) && !(defined(ANDROID) && defined(__i386__))
# if GTEST_OS_LINUX && !(defined(ANDROID) && defined(__i386__))
# define GTEST_HAS_CLONE 1
# else
# define GTEST_HAS_CLONE 0
# endif // GTEST_OS_LINUX && !defined(__ia64__) && !(defined(ANDROID) && defined(__i386__))
# endif // GTEST_OS_LINUX && !(defined(ANDROID) && defined(__i386__))
#endif // GTEST_HAS_CLONE
@@ -804,7 +804,6 @@ _target_machine_enumeration = _Enumeration(
None,
'MachineARM', # /MACHINE:ARM
'MachineEBC', # /MACHINE:EBC
'MachineIA64', # /MACHINE:IA64
None,
'MachineMIPS', # /MACHINE:MIPS
'MachineMIPS16', # /MACHINE:MIPS16
@@ -904,8 +903,7 @@ _MSBuildOnly(_link, 'ForceFileOutput',
_MSBuildOnly(_link, 'CreateHotPatchableImage',
_Enumeration([], new=['Enabled', # /FUNCTIONPADMIN
'X86Image', # /FUNCTIONPADMIN:5
'X64Image', # /FUNCTIONPADMIN:6
'ItaniumImage'])) # /FUNCTIONPADMIN:16
'X64Image'])) # /FUNCTIONPADMIN:6
_MSBuildOnly(_link, 'CLRSupportLastError',
_Enumeration([], new=['Enabled', # /CLRSupportLastError
'Disabled', # /CLRSupportLastError:NO
@@ -969,7 +967,6 @@ _Same(_midl, 'DefaultCharType',
_Same(_midl, 'TargetEnvironment',
_Enumeration(['NotSet',
'Win32', # /env win32
'Itanium', # /env ia64
'X64'])) # /env x64
_Same(_midl, 'EnableErrorChecks',
_Enumeration(['EnableCustom',
@@ -484,7 +484,7 @@ class TestSequenceFunctions(unittest.TestCase):
'StructMemberAlignment': 'NotSet',
'SuppressCompilerWarnings': 'true',
'SuppressStartupBanner': 'true',
'TargetEnvironment': 'Itanium',
'TargetEnvironment': 'InvalidTarget',
'TrackerLogDirectory': 'a_folder',
'TypeLibFormat': 'NewFormat',
'TypeLibraryName': 'a_file_name',
@@ -152,8 +152,7 @@ BOOL AudioDeviceUtilityWindows::GetOSDisplayString(LPTSTR pszOS)
// Add 64-bit or 32-bit
//
if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||
(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64))
if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64))
StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( ", 64-bit" ));
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
StringCchCat(pszOS, STRING_MAX_SIZE, TEXT(", 32-bit"));
-5
View File
@@ -90,11 +90,6 @@
#define WEBRTC_ARCH_32_BITS 1
#define WEBRTC_ARCH_BIG_ENDIAN
#define WEBRTC_BIG_ENDIAN
#elif defined(__ia64__)
#define WEBRTC_ARCH_IA64 1
#define WEBRTC_ARCH_64_BITS 1
#define WEBRTC_ARCH_LITTLE_ENDIAN
#define WEBRTC_LITTLE_ENDIAN
#elif defined(__s390x__)
#define WEBRTC_ARCH_S390X 1
#define WEBRTC_ARCH_64_BITS 1
@@ -59,8 +59,6 @@
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
+15 -3
View File
@@ -107,6 +107,18 @@ typedef struct mi_option_desc_s {
#endif
#endif
#ifndef MI_DEFAULT_PURGE_DECOMMITS
#define MI_DEFAULT_PURGE_DECOMMITS 0
#endif
#ifndef MI_DEFAULT_PURGE_DELAY
#define MI_DEFAULT_PURGE_DELAY 500
#endif
#ifndef MI_DEFAULT_GENERIC_COLLECT
#define MI_DEFAULT_GENERIC_COLLECT 50000
#endif
// Static options
static mi_option_desc_t options[_mi_option_last] =
{
@@ -124,7 +136,7 @@ static mi_option_desc_t options[_mi_option_last] =
UNINIT, MI_OPTION(eager_commit) }, // commit per segment directly (4MiB) (but see also `eager_commit_delay`)
{ MI_DEFAULT_ARENA_EAGER_COMMIT,
UNINIT, MI_OPTION_LEGACY(arena_eager_commit,eager_region_commit) }, // eager commit arena's? 2 is used to enable this only on an OS that has overcommit (i.e. linux)
{ 1, UNINIT, MI_OPTION_LEGACY(purge_decommits,reset_decommits) }, // purge decommits memory (instead of reset) (note: on linux this uses MADV_DONTNEED for decommit)
{ MI_DEFAULT_PURGE_DECOMMITS, UNINIT, MI_OPTION_LEGACY(purge_decommits,reset_decommits) }, // 0 prefers reset/MADV_FREE for lower syscall overhead (1 decommits with MADV_DONTNEED)
{ MI_DEFAULT_ALLOW_LARGE_OS_PAGES,
UNINIT, MI_OPTION_LEGACY(allow_large_os_pages,large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's
{ MI_DEFAULT_RESERVE_HUGE_OS_PAGES,
@@ -141,7 +153,7 @@ static mi_option_desc_t options[_mi_option_last] =
#else
{ 1, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed (but per page in the segment on demand)
#endif
{ 10, UNINIT, MI_OPTION_LEGACY(purge_delay,reset_delay) }, // purge delay in milli-seconds
{ MI_DEFAULT_PURGE_DELAY, UNINIT, MI_OPTION_LEGACY(purge_delay,reset_delay) }, // purge delay in milli-seconds (higher favors throughput over faster rss drop)
{ 0, UNINIT, MI_OPTION(use_numa_nodes) }, // 0 = use available numa nodes, otherwise use at most N nodes.
{ 0, UNINIT, MI_OPTION_LEGACY(disallow_os_alloc,limit_os_alloc) }, // 1 = do not use OS memory for allocation (but only reserved arenas)
{ 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose
@@ -167,7 +179,7 @@ static mi_option_desc_t options[_mi_option_last] =
UNINIT, MI_OPTION(guarded_sample_rate)}, // 1 out of N allocations in the min/max range will be guarded (=4000)
{ 0, UNINIT, MI_OPTION(guarded_sample_seed)},
{ 0, UNINIT, MI_OPTION(target_segments_per_thread) }, // abandon segments beyond this point, or 0 to disable.
{ 10000, UNINIT, MI_OPTION(generic_collect) }, // collect heaps every N (=10000) generic allocation calls
{ MI_DEFAULT_GENERIC_COLLECT, UNINIT, MI_OPTION(generic_collect) }, // collect heaps every N generic allocation calls (higher reduces maintenance frequency)
{ MI_DEFAULT_ALLOW_THP,
UNINIT, MI_OPTION(allow_thp) } // allow transparent huge pages?
};
+2 -3
View File
@@ -896,7 +896,8 @@ static const bool config_recycle = false;
* controlling the malloc behavior are defined as compile-time constants
* for best performance and cannot be altered at runtime.
*/
#if !defined(__ia64__) && !defined(__sparc__) && !defined(__mips__) && !defined(__aarch64__)
#if !defined(__ia64__) && !defined(__sparc__) && !defined(__mips__) && \
!defined(__aarch64__) && !defined(__loongarch__) && !defined(__loongarch64)
#define MALLOC_STATIC_SIZES 1
#endif
@@ -912,8 +913,6 @@ static const bool config_recycle = false;
#define pagesize_2pow ((size_t) 13)
#elif defined(__powerpc64__)
#define pagesize_2pow ((size_t) 16)
#elif defined(__loongarch__) || defined(__loongarch64)
#define pagesize_2pow ((size_t) 14)
#else
#define pagesize_2pow ((size_t) 12)
#endif
+12 -12
View File
@@ -1931,6 +1931,12 @@ pref("network.predictor.max-resources-per-entry", 100);
pref("network.predictor.max-uri-length", 500);
pref("network.predictor.cleaned-up", false);
// Cloudflare Image Resizing compatibility.
// When enabled, URLs containing the "/cdn-cgi/image/" marker will have
// everything after that marker treated as opaque path data. This matches
// Cloudflare's expectations for Image Resizing URLs.
pref("network.url.cloudflare_image_resizing.enabled", true);
// The following prefs pertain to the negotiate-auth extension (see bug 17578),
// which provides transparent Kerberos or NTLM authentication using the SPNEGO
// protocol. Each pref is a comma-separated list of keys, where each key has
@@ -2668,6 +2674,9 @@ pref("layout.css.resizeobserver.enabled", true);
// Is support for cascade layers enabled?
pref("layout.css.cascade-layers.enabled", true);
// Is support for basic CSS nesting lowering enabled?
pref("layout.css.nesting.enabled", true);
// Should rules in imported style sheets be added based on the order
// of appearance of their respective @import rules in the parent
// style sheet? Otherwise, they are added before rules preceding
@@ -3182,7 +3191,7 @@ pref("ui.mouse.resize_grip", false);
#ifdef XP_WIN
// Be as uniform as possible, use Twemoji everywhere.
// Be as uniform as possible, use Twemoji everywhere.
// Optional: prefix with `Segoe UI Emoji` to use Win8+ Segoe UI font emoji where available.
pref("font.name-list.emoji", "Twemoji Mozilla");
@@ -4206,11 +4215,7 @@ pref("image.decode-immediately.enabled", false);
pref("image.downscale-during-decode.enabled", true);
// The default Accept header sent for images loaded over HTTP(S)
#ifdef MOZ_JXL
pref("image.http.accept", "image/webp,image/jxl,image/png,image/*;q=0.8,*/*;q=0.5");
#else
pref("image.http.accept", "image/webp,image/png,image/*;q=0.8,*/*;q=0.5");
#endif
// The threshold for inferring that changes to an <img> element's |src|
// attribute by JavaScript represent an animation, in milliseconds. If the |src|
@@ -4267,11 +4272,6 @@ pref("image.mem.surfacecache.discard_factor", 1);
// automatically determined based on the system's number of cores.
pref("image.multithreaded_decoding.limit", -1);
#ifdef MOZ_JXL
// Whether we attempt to decode JPEG-XL images or not.
pref("image.jxl.enabled", true);
#endif
// Limit for the canvas image cache. 0 means we don't limit the size of the
// cache.
pref("canvas.image.cache.limit", 0);
@@ -4661,7 +4661,7 @@ pref("media.ondevicechange.fakeDeviceChangeEvent.enabled", false);
// those platforms we don't handle touch events anyway so it's conceptually
// a no-op.
pref("layout.css.touch_action.enabled", true);
// WHATWG computed intrinsic aspect ratio for an img element
// https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images
// Are the width and height attributes on image-like elements mapped to the
@@ -5055,7 +5055,7 @@ pref("plugins.navigator_hide_disabled_flash", false);
pref("dom.mozBrowserFramesEnabled", false);
// Thick caret when behind CJK characters
pref("layout.cjkthickcaret", true);
pref("layout.cjkthickcaret", true);
// Is support for 'color-adjust' CSS property enabled?
pref("layout.css.color-adjust.enabled", true);
+53
View File
@@ -26,6 +26,7 @@
#include "prprf.h"
#include "nsReadableUtils.h"
#include "nsPrintfCString.h"
#include "mozilla/Preferences.h" //fixes up dependency issues in non-unified building
using mozilla::dom::EncodingUtils;
using namespace mozilla::ipc;
@@ -1105,6 +1106,58 @@ nsStandardURL::ParseURL(const char *spec, int32_t specLen)
nsresult
nsStandardURL::ParsePath(const char *spec, uint32_t pathPos, int32_t pathLen)
{
// Cloudflare Image Resizing compatibility (pref-controlled)
//
// This feature detects the "/cdn-cgi/image/" marker in the URL path and
// treats everything after it as opaque path data. Cloudflare's Image
// Resizing service expects clients to preserve the entire suffix exactly.
//
// Because this code runs in a hot path (URL parsing), we avoid calling
// Preferences::GetBool() repeatedly. Instead, we use AddBoolVarCache()
// to cache the pref value once and read it cheaply thereafter.
// Cached preference: true = enable Cloudflare Image Resizing fixup
static bool sCloudflareImageResizingEnabled = true;
static bool sCloudflareImageResizingPrefCached = false;
if (!sCloudflareImageResizingPrefCached) {
Preferences::AddBoolVarCache(
&sCloudflareImageResizingEnabled,
"network.url.cloudflare_image_resizing.enabled",
true // default if pref does not exist
);
sCloudflareImageResizingPrefCached = true;
}
if (sCloudflareImageResizingEnabled) {
// Extract the full path substring from the full URL spec.
nsDependentCSubstring fullPath(spec + pathPos, pathLen);
// Prepare iterators for scanning the path.
nsACString::const_iterator begin, end;
fullPath.BeginReading(begin);
fullPath.EndReading(end);
// Search for the Cloudflare Image Resizing marker.
nsACString::const_iterator cfPos = begin;
if (FindInReadable(NS_LITERAL_CSTRING("/cdn-cgi/image/"), cfPos, end)) {
// Compute how far into the path the marker was found.
uint32_t offset = cfPos.get() - begin.get();
// Rewrite the internal path representation so that the path
// begins at the Cloudflare marker. Everything before it is ignored.
mPath.mPos = pathPos + offset;
mPath.mLen = pathLen - offset;
// We handled the path; no further parsing needed.
return NS_OK;
}
}
LOG(("ParsePath: %s pathpos %d len %d\n",spec,pathPos,pathLen));
if (pathLen > net_GetURLMaxLength()) {
+1 -1
View File
@@ -9,4 +9,4 @@ The upstream expat git repository is:
https://github.com/libexpat/libexpat
The version used was tagged release version 2.7.3.
The version used was tagged release version 2.7.4.
+2 -2
View File
@@ -11,7 +11,7 @@
Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
@@ -1082,7 +1082,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
*/
# define XML_MAJOR_VERSION 2
# define XML_MINOR_VERSION 7
# define XML_MICRO_VERSION 3
# define XML_MICRO_VERSION 4
# ifdef __cplusplus
}
+2 -3
View File
@@ -12,7 +12,7 @@
Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
Licensed under the MIT license:
@@ -88,8 +88,7 @@
# ifndef XML_BUILDING_EXPAT
/* using Expat from an application */
# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) \
&& ! defined(__CYGWIN__)
# if defined(_MSC_VER) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
# define XMLIMPORT __declspec(dllimport)
# endif
+1 -1
View File
@@ -128,7 +128,7 @@
# elif ULONG_MAX == 18446744073709551615u // 2^64-1
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu"
# elif defined(EMSCRIPTEN) // 32bit mode Emscripten
# elif defined(__wasm32__) // 32bit mode Emscripten or WASI SDK
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "zu"
# else
+59 -51
View File
@@ -1,4 +1,4 @@
/* 28bcd8b1ba7eb595d82822908257fd9c3589b4243e3c922d0369f35bfcd7b506 (2.7.3+)
/* fab937ab8b186d7d296013669c332e6dfce2f99567882cff1f8eb24223c524a7 (2.7.4+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -13,7 +13,7 @@
Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2005-2009 Steven Solie <steven@solie.ca>
Copyright (c) 2016 Eric Rahm <erahm@mozilla.com>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016 Gaurav <g.gupta@samsung.com>
Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr>
@@ -42,6 +42,9 @@
Copyright (c) 2024-2025 Berkay Eren Ürün <berkay.ueruen@siemens.com>
Copyright (c) 2024 Hanno Böck <hanno@gentoo.org>
Copyright (c) 2025 Matthew Fernandez <matthew.fernandez@gmail.com>
Copyright (c) 2025 Atrem Borovik <polzovatellllk@gmail.com>
Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com>
Copyright (c) 2026 Rosen Penev <rosenp@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -101,7 +104,7 @@
#include <limits.h> /* INT_MAX, UINT_MAX */
#include <stdio.h> /* fprintf */
#include <stdlib.h> /* getenv, rand_s */
#include <stdint.h> /* uintptr_t */
#include <stdint.h> /* SIZE_MAX, uintptr_t */
#include <math.h> /* isnan */
#ifdef _WIN32
@@ -134,11 +137,6 @@
# endif /* defined(GRND_NONBLOCK) */
#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
#if defined(HAVE_LIBBSD) \
&& (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
# include <bsd/stdlib.h>
#endif
#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
@@ -155,8 +153,6 @@
* Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
* BSD / macOS >=10.7 / glibc >=2.36 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
* BSD / macOS (including <10.7) / glibc >=2.36 (arc4random): HAVE_ARC4RANDOM, \
* libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
* libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
* Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \
* Windows >=Vista (rand_s): _WIN32. \
\
@@ -316,8 +312,11 @@ typedef struct tag {
const char *rawName; /* tagName in the original encoding */
int rawNameLength;
TAG_NAME name; /* tagName in the API encoding */
char *buf; /* buffer for name components */
char *bufEnd; /* end of the buffer */
union {
char *raw; /* for byte-level access (rawName storage) */
XML_Char *str; /* for character-level access (converted name) */
} buf; /* buffer for name components */
char *bufEnd; /* end of the buffer */
BINDING *bindings;
} TAG;
@@ -354,7 +353,7 @@ typedef struct {
typedef struct block {
struct block *next;
int size;
XML_Char s[1];
XML_Char s[];
} BLOCK;
typedef struct {
@@ -1266,8 +1265,11 @@ generate_hash_secret_salt(XML_Parser parser) {
# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
/* .. and self-made low quality for backup: */
entropy = gather_time_entropy();
# if ! defined(__wasi__)
/* Process ID is 0 bits entropy if attacker has local access */
entropy = gather_time_entropy() ^ getpid();
entropy ^= getpid();
# endif
/* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
if (sizeof(unsigned long) == 4) {
@@ -1804,6 +1806,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
XML_SkippedEntityHandler oldSkippedEntityHandler;
XML_UnknownEncodingHandler oldUnknownEncodingHandler;
void *oldUnknownEncodingHandlerData;
XML_ElementDeclHandler oldElementDeclHandler;
XML_AttlistDeclHandler oldAttlistDeclHandler;
XML_EntityDeclHandler oldEntityDeclHandler;
@@ -1849,6 +1852,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
oldSkippedEntityHandler = parser->m_skippedEntityHandler;
oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
oldUnknownEncodingHandlerData = parser->m_unknownEncodingHandlerData;
oldElementDeclHandler = parser->m_elementDeclHandler;
oldAttlistDeclHandler = parser->m_attlistDeclHandler;
oldEntityDeclHandler = parser->m_entityDeclHandler;
@@ -1909,6 +1913,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
parser->m_skippedEntityHandler = oldSkippedEntityHandler;
parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
parser->m_unknownEncodingHandlerData = oldUnknownEncodingHandlerData;
parser->m_elementDeclHandler = oldElementDeclHandler;
parser->m_attlistDeclHandler = oldAttlistDeclHandler;
parser->m_entityDeclHandler = oldEntityDeclHandler;
@@ -1984,7 +1989,7 @@ XML_ParserFree(XML_Parser parser) {
}
p = tagList;
tagList = tagList->parent;
FREE(parser, p->buf);
FREE(parser, p->buf.raw);
destroyBindings(p->bindings, parser);
FREE(parser, p);
}
@@ -2665,7 +2670,7 @@ XML_GetBuffer(XML_Parser parser, int len) {
// NOTE: We are avoiding MALLOC(..) here to leave limiting
// the input size to the application using Expat.
newBuf = parser->m_mem.malloc_fcn(bufferSize);
if (newBuf == 0) {
if (newBuf == NULL) {
parser->m_errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
@@ -3220,7 +3225,7 @@ storeRawNames(XML_Parser parser) {
size_t bufSize;
size_t nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
size_t rawNameLen;
char *rawNameBuf = tag->buf + nameLen;
char *rawNameBuf = tag->buf.raw + nameLen;
/* Stop if already stored. Since m_tagStack is a stack, we can stop
at the first entry that has already been copied; everything
below it in the stack is already been accounted for in a
@@ -3236,22 +3241,22 @@ storeRawNames(XML_Parser parser) {
if (rawNameLen > (size_t)INT_MAX - nameLen)
return XML_FALSE;
bufSize = nameLen + rawNameLen;
if (bufSize > (size_t)(tag->bufEnd - tag->buf)) {
char *temp = REALLOC(parser, tag->buf, bufSize);
if (bufSize > (size_t)(tag->bufEnd - tag->buf.raw)) {
char *temp = REALLOC(parser, tag->buf.raw, bufSize);
if (temp == NULL)
return XML_FALSE;
/* if tag->name.str points to tag->buf (only when namespace
/* if tag->name.str points to tag->buf.str (only when namespace
processing is off) then we have to update it
*/
if (tag->name.str == (XML_Char *)tag->buf)
if (tag->name.str == tag->buf.str)
tag->name.str = (XML_Char *)temp;
/* if tag->name.localPart is set (when namespace processing is on)
then update it as well, since it will always point into tag->buf
*/
if (tag->name.localPart)
tag->name.localPart
= (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
tag->buf = temp;
= (XML_Char *)temp + (tag->name.localPart - tag->buf.str);
tag->buf.raw = temp;
tag->bufEnd = temp + bufSize;
rawNameBuf = temp + nameLen;
}
@@ -3597,12 +3602,12 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
tag = MALLOC(parser, sizeof(TAG));
if (! tag)
return XML_ERROR_NO_MEMORY;
tag->buf = MALLOC(parser, INIT_TAG_BUF_SIZE);
if (! tag->buf) {
tag->buf.raw = MALLOC(parser, INIT_TAG_BUF_SIZE);
if (! tag->buf.raw) {
FREE(parser, tag);
return XML_ERROR_NO_MEMORY;
}
tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
tag->bufEnd = tag->buf.raw + INIT_TAG_BUF_SIZE;
}
tag->bindings = NULL;
tag->parent = parser->m_tagStack;
@@ -3615,31 +3620,32 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
{
const char *rawNameEnd = tag->rawName + tag->rawNameLength;
const char *fromPtr = tag->rawName;
toPtr = (XML_Char *)tag->buf;
toPtr = tag->buf.str;
for (;;) {
int bufSize;
int convLen;
const enum XML_Convert_Result convert_res
= XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
(ICHAR *)tag->bufEnd - 1);
convLen = (int)(toPtr - (XML_Char *)tag->buf);
convLen = (int)(toPtr - tag->buf.str);
if ((fromPtr >= rawNameEnd)
|| (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
tag->name.strLen = convLen;
break;
}
bufSize = (int)(tag->bufEnd - tag->buf) << 1;
if (SIZE_MAX / 2 < (size_t)(tag->bufEnd - tag->buf.raw))
return XML_ERROR_NO_MEMORY;
const size_t bufSize = (size_t)(tag->bufEnd - tag->buf.raw) * 2;
{
char *temp = REALLOC(parser, tag->buf, bufSize);
char *temp = REALLOC(parser, tag->buf.raw, bufSize);
if (temp == NULL)
return XML_ERROR_NO_MEMORY;
tag->buf = temp;
tag->buf.raw = temp;
tag->bufEnd = temp + bufSize;
toPtr = (XML_Char *)temp + convLen;
}
}
}
tag->name.str = (XML_Char *)tag->buf;
tag->name.str = tag->buf.str;
*toPtr = XML_T('\0');
result
= storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account);
@@ -4033,7 +4039,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
if ((unsigned)parser->m_attsSize > SIZE_MAX / sizeof(ATTRIBUTE)) {
parser->m_attsSize = oldAttsSize;
return XML_ERROR_NO_MEMORY;
}
@@ -4052,7 +4058,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
# if UINT_MAX >= SIZE_MAX
if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
if ((unsigned)parser->m_attsSize > SIZE_MAX / sizeof(XML_AttrInfo)) {
parser->m_attsSize = oldAttsSize;
return XML_ERROR_NO_MEMORY;
}
@@ -4247,7 +4253,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) {
if (nsAttsSize > SIZE_MAX / sizeof(NS_ATT)) {
/* Restore actual size of memory in m_nsAtts */
parser->m_nsAttsPower = oldNsAttsPower;
return XML_ERROR_NO_MEMORY;
@@ -4484,7 +4490,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
if ((unsigned)(n + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) {
return XML_ERROR_NO_MEMORY;
}
#endif
@@ -4730,7 +4736,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
if ((unsigned)(len + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) {
return XML_ERROR_NO_MEMORY;
}
#endif
@@ -4757,7 +4763,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
if ((unsigned)(len + EXPAND_SPARE) > SIZE_MAX / sizeof(XML_Char)) {
return XML_ERROR_NO_MEMORY;
}
#endif
@@ -6148,15 +6154,18 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) {
if (parser->m_groupSize > SIZE_MAX / sizeof(int)) {
parser->m_groupSize /= 2;
return XML_ERROR_NO_MEMORY;
}
#endif
int *const new_scaff_index = REALLOC(
parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
if (new_scaff_index == NULL)
if (new_scaff_index == NULL) {
parser->m_groupSize /= 2;
return XML_ERROR_NO_MEMORY;
}
dtd->scaffIndex = new_scaff_index;
}
} else {
@@ -7427,7 +7436,7 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
if ((unsigned)count > SIZE_MAX / sizeof(DEFAULT_ATTRIBUTE)) {
return 0;
}
#endif
@@ -7905,8 +7914,7 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
* from -Wtype-limits on platforms where
* sizeof(int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if ((size_t)oldE->nDefaultAtts
> ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) {
if ((size_t)oldE->nDefaultAtts > SIZE_MAX / sizeof(DEFAULT_ATTRIBUTE)) {
return 0;
}
#endif
@@ -8108,7 +8116,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
unsigned long newMask = (unsigned long)newSize - 1;
/* Detect and prevent integer overflow */
if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
if (newSize > SIZE_MAX / sizeof(NAMED *)) {
return NULL;
}
@@ -8346,7 +8354,7 @@ poolBytesToAllocateFor(int blockSize) {
static XML_Bool FASTCALL
poolGrow(STRING_POOL *pool) {
if (pool->freeBlocks) {
if (pool->start == 0) {
if (pool->start == NULL) {
pool->blocks = pool->freeBlocks;
pool->freeBlocks = pool->freeBlocks->next;
pool->blocks->next = NULL;
@@ -8458,7 +8466,7 @@ nextScaffoldPart(XML_Parser parser) {
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if (parser->m_groupSize > ((size_t)(-1) / sizeof(int))) {
if (parser->m_groupSize > SIZE_MAX / sizeof(int)) {
return -1;
}
#endif
@@ -8485,7 +8493,7 @@ nextScaffoldPart(XML_Parser parser) {
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
if (dtd->scaffSize > SIZE_MAX / 2u / sizeof(CONTENT_SCAFFOLD)) {
return -1;
}
#endif
@@ -8535,15 +8543,15 @@ build_model(XML_Parser parser) {
* from -Wtype-limits on platforms where
* sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
#if UINT_MAX >= SIZE_MAX
if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
if (dtd->scaffCount > SIZE_MAX / sizeof(XML_Content)) {
return NULL;
}
if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
if (dtd->contentStringLen > SIZE_MAX / sizeof(XML_Char)) {
return NULL;
}
#endif
if (dtd->scaffCount * sizeof(XML_Content)
> (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
> SIZE_MAX - dtd->contentStringLen * sizeof(XML_Char)) {
return NULL;
}
+1 -1
View File
@@ -16,6 +16,7 @@
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -46,7 +47,6 @@
# include "winconfig.h"
#endif
#include "expat_external.h"
#include "internal.h"
#include "xmlrole.h"
#include "ascii.h"
+1 -1
View File
@@ -24,6 +24,7 @@
Copyright (c) 2022 Martin Ettl <ettl.martin78@googlemail.com>
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
Copyright (c) 2023 Hanno Böck <hanno@gentoo.org>
Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -56,7 +57,6 @@
# include "winconfig.h"
#endif
#include "expat_external.h"
#include "internal.h"
#include "xmltok.h"
#include "nametab.h"
+3 -2
View File
@@ -12,6 +12,7 @@
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -98,13 +99,13 @@ NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) {
int i;
XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
if (ptr != end)
return 0;
return NULL;
*p = 0;
if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
return enc;
i = getEncodingIndex(buf);
if (i == UNKNOWN_ENC)
return 0;
return NULL;
return NS(encodings)[i];
}
+1 -8
View File
@@ -44,17 +44,10 @@ print OUTFILE "* 0 is QueryInterface\n";
print OUTFILE "* 1 is AddRef\n";
print OUTFILE "* 2 is Release\n";
print OUTFILE "*/\n";
print OUTFILE "#if !defined(__ia64) || (!defined(__hpux) && !defined(__linux__) && !defined(__FreeBSD__))\n";
for($i = 0; $i < $entry_count; $i++) {
print OUTFILE "NS_IMETHOD Stub",$i+3,"();\n";
}
print OUTFILE "#else\n";
for($i = 0; $i < $entry_count; $i++) {
print OUTFILE "NS_IMETHOD Stub",$i+3,"(uint64_t,uint64_t,\n";
print OUTFILE " uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);\n";
}
print OUTFILE "#endif\n";
print OUTFILE "\n/* declarations of sentinel stubs */\n";
-9
View File
@@ -46,15 +46,6 @@ if CONFIG['OS_ARCH'] in ('Linux', 'Bitrig', 'DragonFly', 'FreeBSD', 'NetBSD', 'O
'xptcstubs_gcc_x86_unix.cpp'
]
if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD'):
if 'ia64' in CONFIG['OS_TEST']:
SOURCES += [
'xptcinvoke_asm_ipf64.s',
'xptcinvoke_ipf64.cpp',
'xptcstubs_asm_ipf64.s',
'xptcstubs_ipf64.cpp'
]
if CONFIG['OS_TEST'] == 'alpha':
if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD', 'NetBSD'):
SOURCES += [
@@ -1,145 +0,0 @@
// Select C numeric constant
.radix C
// for 64 bit mode, use .psr abi64
.psr abi32
// big endian
.psr msb
// Section has executable code
.section .text, "ax","progbits"
// procedure named 'NS_InvokeByIndex'
.proc NS_InvokeByIndex
// manual bundling
.explicit
// extern "C" uint32_t
// invoke_copy_to_stack(uint64_t* d,
// const uint32_t paramCount, nsXPTCVariant* s)
.global invoke_copy_to_stack
// .exclass invoke_copy_to_stack, @fullyvisible
.type invoke_copy_to_stack,@function
// .exclass NS_InvokeByIndex, @fullyvisible
.type NS_InvokeByIndex,@function
// NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
// uint32_t paramCount, nsXPTCVariant* params);
NS_InvokeByIndex::
.prologue
.save ar.pfs, r37
// allocate 4 input args, 6 local args, and 8 output args
alloc r37 = ar.pfs, 4, 6, 8, 0 // M
nop.i 0 ;; // I
// unwind table already knows gp, no need to specify anything
add r39 = 0, gp // A
.save rp, r36
mov r36 = rp // I
.vframe r38
add r38 = 0, sp ;; // A
// We first calculate the amount of extra memory stack space required
// for the arguments, and register storage.
// We then call invoke_copy_to_stack() to write the argument contents
// to the specified memory regions.
// We then copy the integer arguments to integer registers, and floating
// arguments to float registers.
// Lastly we load the virtual table jump pointer, and call the target
// subroutine.
// in0 : that
// in1 : methodIndex
// in2 : paramCount
// in3 : params
// stack frame size is 16 + (8 * even(paramCount)) + 64 + 64
// 16 byte frame header
// 8 * even(paramCount) memory argument area
// 64 bytes integer register area
// 64 bytes float register area
// This scheme makes sure stack fram size is a multiple of 16
.body
add r10 = 8, r0 // A
// r41 points to float register area
add r41 = -64, sp // A
// r40 points to int register area
add r40 = -128, sp ;; // A
add out1 = 0, r40 // A
add out2 = 0, r41 // A
tbit.z p14,p15 = in2,0 ;; // I
// compute 8 * even(paramCount)
(p14) shladd r11 = in2, 3, r0 ;; // A
(p15) shladd r11 = in2, 3, r10 ;; // A
sub out0 = r40, r11 ;; // A
// advance the stack frame
add sp = -16, out0 // A
add out3 = 0, in2 // A
add out4 = 0, in3 // A
// branch to invoke_copy_to_stack
br.call.sptk.few rp = invoke_copy_to_stack ;; // B
// restore gp
add gp = 0, r39 // A
add out0 = 0, in0 // A
// load the integer and float registers
ld8 out1 = [r40], 8 // M
ldfd f8 = [r41], 8 ;; // M
ld8 out2 = [r40], 8 // M
ldfd f9 = [r41], 8 ;; // M
ld8 out3 = [r40], 8 // M
ldfd f10 = [r41], 8 ;; // M
ld8 out4 = [r40], 8 // M
ldfd f11 = [r41], 8 ;; // M
ld8 out5 = [r40], 8 // M
ldfd f12 = [r41], 8 ;; // M
// 16 * methodIndex
shladd r11 = in1, 4, r0 // A
ld8 out6 = [r40], 8 // M
ldfd f13 = [r41], 8 ;; // M
ld8 out7 = [r40], 8 // M
ldfd f14 = [r41], 8 // M
addp4 r8 = 0, in0 ;; // A
// look up virtual base table and dispatch to target subroutine
// This section assumes 32 bit pointer mode, and virtual base table
// layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html
// load base table
ld4 r8 = [r8] ;; // M
addp4 r8 = r11, r8 ;; // A
// first entry is jump pointer, second entry is gp
addp4 r9 = 8, r8 ;; // A
// load jump pointer
ld8 r8 = [r8]
// load gp
ld8 gp = [r9] ;; // M
mov b6 = r8 ;; // I
// branch to target virtual function
br.call.sptk.few rp = b6 ;; // B
// epilog
mov ar.pfs = r37 // I
mov rp = r36 ;; // I
add sp = 0, r38 // A
add gp = 0, r39 // A
br.ret.sptk.few rp ;; // B
.endp
@@ -1,146 +0,0 @@
// Select C numeric constant
.radix C
// for 64 bit mode, use .psr abi64
.psr abi64
// little endian
.psr lsb
// Section has executable code
.section .text, "ax","progbits"
// procedure named 'NS_InvokeByIndex'
.proc NS_InvokeByIndex
// manual bundling
.explicit
// extern "C" uint32_t
// invoke_copy_to_stack(uint64_t* d,
// const uint32_t paramCount, nsXPTCVariant* s)
.global invoke_copy_to_stack
// .exclass invoke_copy_to_stack, @fullyvisible
.type invoke_copy_to_stack,@function
// .exclass NS_InvokeByIndex, @fullyvisible
.type NS_InvokeByIndex,@function
// XPTC_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
// uint32_t paramCount, nsXPTCVariant* params);
NS_InvokeByIndex::
.prologue
.save ar.pfs, r37
// allocate 4 input args, 6 local args, and 8 output args
alloc r37 = ar.pfs, 4, 6, 8, 0 // M
nop.i 0 ;; // I
// unwind table already knows gp, no need to specify anything
add r39 = 0, gp // A
.save rp, r36
mov r36 = rp // I
.vframe r38
add r38 = 0, sp ;; // A
// We first calculate the amount of extra memory stack space required
// for the arguments, and register storage.
// We then call invoke_copy_to_stack() to write the argument contents
// to the specified memory regions.
// We then copy the integer arguments to integer registers, and floating
// arguments to float registers.
// Lastly we load the virtual table jump pointer, and call the target
// subroutine.
// in0 : that
// in1 : methodIndex
// in2 : paramCount
// in3 : params
// stack frame size is 16 + (8 * even(paramCount)) + 64 + 64
// 16 byte frame header
// 8 * even(paramCount) memory argument area
// 64 bytes integer register area
// 64 bytes float register area
// This scheme makes sure stack fram size is a multiple of 16
.body
add r10 = 8, r0 // A
// r41 points to float register area
add r41 = -64, sp // A
// r40 points to int register area
add r40 = -128, sp ;; // A
add out1 = 0, r40 // A
add out2 = 0, r41 // A
tbit.z p14,p15 = in2,0 ;; // I
// compute 8 * even(paramCount)
(p14) shladd r11 = in2, 3, r0 ;; // A
(p15) shladd r11 = in2, 3, r10 ;; // A
sub out0 = r40, r11 ;; // A
// advance the stack frame
add sp = -16, out0 // A
add out3 = 0, in2 // A
add out4 = 0, in3 // A
// branch to invoke_copy_to_stack
br.call.sptk.few rp = invoke_copy_to_stack ;; // B
// restore gp
add gp = 0, r39 // A
add out0 = 0, in0 // A
// load the integer and float registers
ld8 out1 = [r40], 8 // M
ldfd f8 = [r41], 8 ;; // M
ld8 out2 = [r40], 8 // M
ldfd f9 = [r41], 8 ;; // M
ld8 out3 = [r40], 8 // M
ldfd f10 = [r41], 8 ;; // M
ld8 out4 = [r40], 8 // M
ldfd f11 = [r41], 8 ;; // M
ld8 out5 = [r40], 8 // M
ldfd f12 = [r41], 8 ;; // M
// 16 * methodIndex
shladd r11 = in1, 4, r0 // A
ld8 out6 = [r40], 8 // M
ldfd f13 = [r41], 8 ;; // M
ld8 out7 = [r40], 8 // M
ldfd f14 = [r41], 8 // M
add r8 = 0, in0 ;; // A
// look up virtual base table and dispatch to target subroutine
// This section assumes 64 bit pointer mode, and virtual base table
// layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html
// load base table
ld8 r8 = [r8] ;; // M
add r8 = r11, r8 ;; // A
// first entry is jump pointer, second entry is gp
add r9 = 8, r8 ;; // A
// load jump pointer
ld8 r8 = [r8]
// load gp
ld8 gp = [r9] ;; // M
mov b6 = r8 ;; // I
// branch to target virtual function
br.call.sptk.few rp = b6 ;; // B
// epilog
mov ar.pfs = r37 // I
mov rp = r36 ;; // I
add sp = 0, r38 // A
add gp = 0, r39 // A
br.ret.sptk.few rp ;; // B
.endp
/* Magic indicating no need for an executable stack */
.section .note.GNU-stack, "", @progbits ; .previous
@@ -1,132 +0,0 @@
/* -*- 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 "xptcprivate.h"
#include <iostream.h>
// "This code is for IA64 only"
/* invoke_copy_to_stack() will copy from variant array 's' to
* the stack argument area 'mloc', the integer register area 'iloc', and
* the float register area 'floc'.
*
*/
extern "C" void
invoke_copy_to_stack(uint64_t* mloc, uint64_t* iloc, uint64_t* floc,
const uint32_t paramCount, nsXPTCVariant* s)
{
uint64_t* dest = mloc;
uint32_t len = paramCount;
nsXPTCVariant* source = s;
uint32_t indx;
uint32_t endlen;
endlen = (len > 7) ? 7 : len;
/* handle the memory arguments */
for (indx = 7; indx < len; ++indx)
{
if (source[indx].IsPtrData())
{
#ifdef __LP64__
/* 64 bit pointer mode */
*((void**) dest) = source[indx].ptr;
#else
/* 32 bit pointer mode */
uint32_t* adr = (uint32_t*) dest;
*(adr) = 0;
*(adr+1) = (uint32_t) source[indx].ptr;
#endif
}
else
switch (source[indx].type)
{
case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break;
case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break;
case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break;
case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break;
case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break;
case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break;
case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break;
case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break;
case nsXPTType::T_FLOAT : *(dest) = source[indx].val.u32; break;
case nsXPTType::T_DOUBLE: *(dest) = source[indx].val.u64; break;
case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break;
case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break;
case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break;
default:
// all the others are plain pointer types
#ifdef __LP64__
/* 64 bit pointer mode */
*((void**) dest) = source[indx].val.p;
#else
{
/* 32 bit pointer mode */
uint32_t* adr = (uint32_t*) dest;
*(adr) = 0;
*(adr+1) = (uint32_t) source[indx].val.p;
}
#endif
}
++dest;
}
/* process register arguments */
dest = iloc;
for (indx = 0; indx < endlen; ++indx)
{
if (source[indx].IsPtrData())
{
#ifdef __LP64__
/* 64 bit pointer mode */
*((void**) dest) = source[indx].ptr;
#else
/* 32 bit pointer mode */
uint32_t* adr = (uint32_t*) dest;
*(adr) = 0;
*(adr+1) = (uint32_t) source[indx].ptr;
#endif
}
else
switch (source[indx].type)
{
case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break;
case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break;
case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break;
case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break;
case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break;
case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break;
case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break;
case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break;
case nsXPTType::T_FLOAT :
*((double*) (floc++)) = (double) source[indx].val.f;
break;
case nsXPTType::T_DOUBLE:
*((double*) (floc++)) = source[indx].val.d;
break;
case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break;
case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break;
case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break;
default:
// all the others are plain pointer types
#ifdef __LP64__
/* 64 bit pointer mode */
*((void**) dest) = source[indx].val.p;
#else
{
/* 32 bit pointer mode */
uint32_t* adr = (uint32_t*) dest;
*(adr) = 0;
*(adr+1) = (uint32_t) source[indx].val.p;
}
#endif
}
++dest;
}
}
@@ -1,100 +0,0 @@
/* -*- 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 "xptcprivate.h"
#include <stdint.h>
// "This code is for IA64 only"
/* invoke_copy_to_stack() will copy from variant array 's' to
* the stack argument area 'mloc', the integer register area 'iloc', and
* the float register area 'floc'.
*
*/
extern "C" void
invoke_copy_to_stack(uint64_t* mloc, uint64_t* iloc, uint64_t* floc,
const uint32_t paramCount, nsXPTCVariant* s)
{
uint64_t* dest = mloc;
uint32_t len = paramCount;
nsXPTCVariant* source = s;
uint32_t indx;
uint32_t endlen;
endlen = (len > 7) ? 7 : len;
/* handle the memory arguments */
for (indx = 7; indx < len; ++indx)
{
if (source[indx].IsPtrData())
{
/* 64 bit pointer mode */
*((void**) dest) = source[indx].ptr;
}
else
switch (source[indx].type)
{
case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break;
case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break;
case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break;
case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break;
case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break;
case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break;
case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break;
case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break;
case nsXPTType::T_FLOAT : *(dest) = source[indx].val.u32; break;
case nsXPTType::T_DOUBLE: *(dest) = source[indx].val.u64; break;
case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break;
case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break;
case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break;
default:
// all the others are plain pointer types
/* 64 bit pointer mode */
*((void**) dest) = source[indx].val.p;
}
++dest;
}
/* process register arguments */
dest = iloc;
for (indx = 0; indx < endlen; ++indx)
{
if (source[indx].IsPtrData())
{
/* 64 bit pointer mode */
*((void**) dest) = source[indx].ptr;
}
else
switch (source[indx].type)
{
case nsXPTType::T_I8 : *(dest) = source[indx].val.i8; break;
case nsXPTType::T_I16 : *(dest) = source[indx].val.i16; break;
case nsXPTType::T_I32 : *(dest) = source[indx].val.i32; break;
case nsXPTType::T_I64 : *(dest) = source[indx].val.i64; break;
case nsXPTType::T_U8 : *(dest) = source[indx].val.u8; break;
case nsXPTType::T_U16 : *(dest) = source[indx].val.u16; break;
case nsXPTType::T_U32 : *(dest) = source[indx].val.u32; break;
case nsXPTType::T_U64 : *(dest) = source[indx].val.u64; break;
case nsXPTType::T_FLOAT :
*((double*) (floc++)) = (double) source[indx].val.f;
break;
case nsXPTType::T_DOUBLE:
*((double*) (floc++)) = source[indx].val.d;
break;
case nsXPTType::T_BOOL : *(dest) = source[indx].val.b; break;
case nsXPTType::T_CHAR : *(dest) = source[indx].val.c; break;
case nsXPTType::T_WCHAR : *(dest) = source[indx].val.wc; break;
default:
// all the others are plain pointer types
/* 64 bit pointer mode */
*((void**) dest) = source[indx].val.p;
}
++dest;
}
}
@@ -1,123 +0,0 @@
// Select C numeric constant
.radix C
.psr abi32
.psr msb
// Section has executable code
.section .text, "ax","progbits"
// procedure named 'SharedStub'
.proc SharedStub
// manual bundling
.explicit
.global PrepareAndDispatch
// .exclass PrepareAndDispatch, @fullyvisible
.type PrepareAndDispatch,@function
SharedStub::
// 10 arguments, first 8 are the input arguments of previous
// function call. The 9th one is methodIndex and the 10th is the
// pointer to the remaining input arguments. The last two arguments
// are passed in memory.
.prologue
.save ar.pfs , r41
// allocate 8 input args, 4 local args, and 5 output args
alloc r41 = ar.pfs, 8, 4, 5, 0 // M
.save rp, r40
mov r40 = rp // I
addp4 out4 = 28, sp ;; // I
.save ar.unat, r42
mov r42 = ar.unat // M
.fframe 144
add sp = -144, sp // A
// unwind table already knows gp, don't need to specify anything
add r43 = 0, gp ;; // A
// We have possible 8 integer registers and 8 float registers that could
// be arguments. We also have a stack region from the previous
// stack frame that may hold some stack arguments.
// We need to write the integer registers to a memory region, write
// the float registers to a memory region (making sure we don't step
// on NAT while touching the registers). We also mark the memory
// address of the stack arguments.
// We then call PrepareAndDispatch() specifying the three memory
// region pointers.
.body
add out0 = 0, in0 // A move self ptr
// 144 bytes = 16 byte stack header + 64 byte int space + 64 byte float space
// methodIndex is at 144 + 16 bytes away from current sp
// (current frame + previous frame header)
ld4 out4 = [out4] // A restarg address
add r11 = 160, sp ;; // A address of methodIndex
ld8 out1 = [r11] // M load methodIndex
// sp + 16 is the start of intargs
add out2 = 16, sp // A address of intargs
// the intargs take up 64 bytes, so sp + 16 + 64 is the start of floatargs
add out3 = 80, sp ;; // A address of floatargs
add r11 = 0, out2 ;; // A
st8.spill [r11] = in1, 8 // M
add r10 = 0, out3 ;; // A
st8.spill [r11] = in2, 8 ;; // M
st8.spill [r11] = in3, 8 // M
nop.i 0 ;; // I
st8.spill [r11] = in4, 8 ;; // M
st8.spill [r11] = in5, 8 // M
nop.i 0 ;; // I
st8.spill [r11] = in6, 8 ;; // M
st8.spill [r11] = in7 // M
fclass.nm p14,p15 = f8,@nat ;; // F
(p14) stfd [r10] = f8, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 = f9,@nat ;; // F
(p12) stfd [r10] = f9, 8 // M
(p13) add r10 = 8, r10 // A
fclass.nm p14,p15 =f10,@nat ;; // F
(p14) stfd [r10] = f10, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 =f11,@nat ;; // F
(p12) stfd [r10] = f11, 8 // M
(p13) add r10 = 8, r10 // A
fclass.nm p14,p15 =f12,@nat ;; // F
(p14) stfd [r10] = f12, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 =f13,@nat ;; // F
(p12) stfd [r10] = f13, 8 // M
(p13) add r10 = 8, r10 // A
fclass.nm p14,p15 =f14,@nat ;; // F
(p14) stfd [r10] = f14, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 =f15,@nat ;; // F
(p12) stfd [r10] = f15, 8 // M
(p13) add r10 = 8, r10 // A
// branch to PrepareAndDispatch
br.call.dptk.few rp = PrepareAndDispatch ;; // B
// epilog
mov ar.unat = r42 // M
mov ar.pfs = r41 // I
mov rp = r40 ;; // I
add gp = 0, r43 // A
add sp = 144, sp // A
br.ret.dptk.few rp ;; // B
.endp
@@ -1,124 +0,0 @@
// Select C numeric constant
.radix C
.psr abi64
.psr lsb
// Section has executable code
.section .text, "ax","progbits"
// procedure named 'SharedStub'
.proc SharedStub
// manual bundling
.explicit
.global PrepareAndDispatch
// .exclass PrepareAndDispatch, @fullyvisible
.type PrepareAndDispatch,@function
SharedStub::
// 10 arguments, first 8 are the input arguments of previous
// function call. The 9th one is methodIndex and the 10th is the
// pointer to the remaining input arguments. The last two arguments
// are passed in memory.
.prologue
.save ar.pfs , r41
// allocate 8 input args, 4 local args, and 5 output args
alloc r41 = ar.pfs, 8, 4, 5, 0 // M
.save rp, r40
mov r40 = rp // I
add out4 = 24, sp ;; // I
.save ar.unat, r42
mov r42 = ar.unat // M
.fframe 144
add sp = -144, sp // A
// unwind table already knows gp, don't need to specify anything
add r43 = 0, gp ;; // A
// We have possible 8 integer registers and 8 float registers that could
// be arguments. We also have a stack region from the previous
// stack frame that may hold some stack arguments.
// We need to write the integer registers to a memory region, write
// the float registers to a memory region (making sure we don't step
// on NAT while touching the registers). We also mark the memory
// address of the stack arguments.
// We then call PrepareAndDispatch() specifying the three memory
// region pointers.
.body
add out0 = 0, in0 // A move self ptr
// 144 bytes = 16 byte stack header + 64 byte int space + 64 byte float space
// methodIndex is at 144 + 16 bytes away from current sp
// (current frame + previous frame header)
ld8 out4 = [out4] // M restarg address
add r11 = 160, sp ;; // A address of methodIndex
ld8 out1 = [r11] // M load methodIndex
// sp + 16 is the start of intargs
add out2 = 16, sp // A address of intargs
// the intargs take up 64 bytes, so sp + 16 + 64 is the start of floatargs
add out3 = 80, sp ;; // A address of floatargs
add r11 = 0, out2 ;; // A
st8.spill [r11] = in1, 8 // M
add r10 = 0, out3 ;; // A
st8.spill [r11] = in2, 8 ;; // M
st8.spill [r11] = in3, 8 // M
nop.i 0 ;; // I
st8.spill [r11] = in4, 8 ;; // M
st8.spill [r11] = in5, 8 // M
nop.i 0 ;; // I
st8.spill [r11] = in6, 8 ;; // M
st8.spill [r11] = in7 // M
fclass.nm p14,p15 = f8,@nat ;; // F
(p14) stfd [r10] = f8, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 = f9,@nat ;; // F
(p12) stfd [r10] = f9, 8 // M
(p13) add r10 = 8, r10 // A
fclass.nm p14,p15 =f10,@nat ;; // F
(p14) stfd [r10] = f10, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 =f11,@nat ;; // F
(p12) stfd [r10] = f11, 8 // M
(p13) add r10 = 8, r10 // A
fclass.nm p14,p15 =f12,@nat ;; // F
(p14) stfd [r10] = f12, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 =f13,@nat ;; // F
(p12) stfd [r10] = f13, 8 // M
(p13) add r10 = 8, r10 // A
fclass.nm p14,p15 =f14,@nat ;; // F
(p14) stfd [r10] = f14, 8 // M
(p15) add r10 = 8, r10 // A
fclass.nm p12,p13 =f15,@nat ;; // F
(p12) stfd [r10] = f15, 8 // M
(p13) add r10 = 8, r10 // A
// branch to PrepareAndDispatch
br.call.dptk.few rp = PrepareAndDispatch ;; // B
// epilog
mov ar.unat = r42 // M
mov ar.pfs = r41 // I
mov rp = r40 ;; // I
add gp = 0, r43 // A
add sp = 144, sp // A
br.ret.dptk.few rp ;; // B
.endp
/* Magic indicating no need for an executable stack */
.section .note.GNU-stack, "", @progbits ; .previous
@@ -1,151 +0,0 @@
/* -*- 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 "xptcprivate.h"
#include "xptiprivate.h"
#include <stddef.h>
#include <stdlib.h>
// "This code is for IA64 only"
/* Implement shared vtbl methods. */
extern "C" nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
uint64_t* intargs, uint64_t* floatargs, uint64_t* restargs)
{
#define PARAM_BUFFER_COUNT 16
nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
nsXPTCMiniVariant* dispatchParams = nullptr;
const nsXPTMethodInfo* info;
nsresult result = NS_ERROR_FAILURE;
uint64_t* iargs = intargs;
uint64_t* fargs = floatargs;
uint8_t paramCount;
uint8_t i;
NS_ASSERTION(self,"no self");
self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
NS_ASSERTION(info,"no interface info");
paramCount = info->GetParamCount();
// setup variant array pointer
if(paramCount > PARAM_BUFFER_COUNT)
dispatchParams = new nsXPTCMiniVariant[paramCount];
else
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
if (! dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
for(i = 0; i < paramCount; ++i)
{
int isfloat = 0;
const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if(param.IsOut() || !type.IsArithmetic())
{
#ifdef __LP64__
/* 64 bit pointer mode */
dp->val.p = (void*) *iargs;
#else
/* 32 bit pointer mode */
uint32_t* adr = (uint32_t*) iargs;
dp->val.p = (void*) (*(adr+1));
#endif
}
else
switch(type)
{
case nsXPTType::T_I8 : dp->val.i8 = *(iargs); break;
case nsXPTType::T_I16 : dp->val.i16 = *(iargs); break;
case nsXPTType::T_I32 : dp->val.i32 = *(iargs); break;
case nsXPTType::T_I64 : dp->val.i64 = *(iargs); break;
case nsXPTType::T_U8 : dp->val.u8 = *(iargs); break;
case nsXPTType::T_U16 : dp->val.u16 = *(iargs); break;
case nsXPTType::T_U32 : dp->val.u32 = *(iargs); break;
case nsXPTType::T_U64 : dp->val.u64 = *(iargs); break;
case nsXPTType::T_FLOAT :
isfloat = 1;
if (i < 7)
dp->val.f = (float) *((double*) fargs); /* register */
else
dp->val.u32 = *(fargs); /* memory */
break;
case nsXPTType::T_DOUBLE :
isfloat = 1;
dp->val.u64 = *(fargs);
break;
case nsXPTType::T_BOOL : dp->val.b = *(iargs); break;
case nsXPTType::T_CHAR : dp->val.c = *(iargs); break;
case nsXPTType::T_WCHAR : dp->val.wc = *(iargs); break;
default:
NS_ERROR("bad type");
break;
}
if (i < 7)
{
/* we are parsing register arguments */
if (i == 6)
{
// run out of register arguments, move on to memory arguments
iargs = restargs;
fargs = restargs;
}
else
{
++iargs; // advance one integer register slot
if (isfloat) ++fargs; // advance float register slot if isfloat
}
}
else
{
/* we are parsing memory arguments */
++iargs;
++fargs;
}
}
result = self->mOuter->CallMethod((uint16_t) methodIndex, info, dispatchParams);
if(dispatchParams != paramBuffer)
delete [] dispatchParams;
return result;
}
extern "C" nsresult SharedStub(uint64_t,uint64_t,uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t *);
/* Variable a0-a7 were put there so we can have access to the 8 input
registers on Stubxyz entry */
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n(uint64_t a1, \
uint64_t a2,uint64_t a3,uint64_t a4,uint64_t a5,uint64_t a6,uint64_t a7, \
uint64_t a8) \
{ uint64_t a0 = (uint64_t) this; \
return SharedStub(a0,a1,a2,a3,a4,a5,a6,a7,(uint64_t) n, &a8); \
}
#define SENTINEL_ENTRY(n) \
nsresult nsXPTCStubBase::Sentinel##n() \
{ \
NS_ERROR("nsXPTCStubBase::Sentinel called"); \
return NS_ERROR_NOT_IMPLEMENTED; \
}
#include "xptcstubsdef.inc"
@@ -1,154 +0,0 @@
/* -*- 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 "xptcprivate.h"
#include "xptiprivate.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
// "This code is for IA64 only"
/* Implement shared vtbl methods. */
extern "C" nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
uint64_t* intargs, uint64_t* floatargs, uint64_t* restargs)
{
#define PARAM_BUFFER_COUNT 16
nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
nsXPTCMiniVariant* dispatchParams = nullptr;
const nsXPTMethodInfo* info;
nsresult result = NS_ERROR_FAILURE;
uint64_t* iargs = intargs;
uint64_t* fargs = floatargs;
uint8_t paramCount;
uint8_t i;
NS_ASSERTION(self,"no self");
self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
NS_ASSERTION(info,"no method info");
if (! info)
return NS_ERROR_UNEXPECTED;
paramCount = info->GetParamCount();
// setup variant array pointer
if(paramCount > PARAM_BUFFER_COUNT)
dispatchParams = new nsXPTCMiniVariant[paramCount];
else
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
if (! dispatchParams)
return NS_ERROR_OUT_OF_MEMORY;
for(i = 0; i < paramCount; ++i)
{
int isfloat = 0;
const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if(param.IsOut() || !type.IsArithmetic())
{
#ifdef __LP64__
/* 64 bit pointer mode */
dp->val.p = (void*) *iargs;
#else
/* 32 bit pointer mode */
uint32_t* adr = (uint32_t*) iargs;
dp->val.p = (void*) (*(adr+1));
#endif
}
else
switch(type)
{
case nsXPTType::T_I8 : dp->val.i8 = *(iargs); break;
case nsXPTType::T_I16 : dp->val.i16 = *(iargs); break;
case nsXPTType::T_I32 : dp->val.i32 = *(iargs); break;
case nsXPTType::T_I64 : dp->val.i64 = *(iargs); break;
case nsXPTType::T_U8 : dp->val.u8 = *(iargs); break;
case nsXPTType::T_U16 : dp->val.u16 = *(iargs); break;
case nsXPTType::T_U32 : dp->val.u32 = *(iargs); break;
case nsXPTType::T_U64 : dp->val.u64 = *(iargs); break;
case nsXPTType::T_FLOAT :
isfloat = 1;
if (i < 7)
dp->val.f = (float) *((double*) fargs); /* register */
else
dp->val.u32 = *(fargs); /* memory */
break;
case nsXPTType::T_DOUBLE :
isfloat = 1;
dp->val.u64 = *(fargs);
break;
case nsXPTType::T_BOOL : dp->val.b = *(iargs); break;
case nsXPTType::T_CHAR : dp->val.c = *(iargs); break;
case nsXPTType::T_WCHAR : dp->val.wc = *(iargs); break;
default:
NS_ERROR("bad type");
break;
}
if (i < 7)
{
/* we are parsing register arguments */
if (i == 6)
{
// run out of register arguments, move on to memory arguments
iargs = restargs;
fargs = restargs;
}
else
{
++iargs; // advance one integer register slot
if (isfloat) ++fargs; // advance float register slot if isfloat
}
}
else
{
/* we are parsing memory arguments */
++iargs;
++fargs;
}
}
result = self->mOuter->CallMethod((uint16_t) methodIndex, info, dispatchParams);
if(dispatchParams != paramBuffer)
delete [] dispatchParams;
return result;
}
extern "C" nsresult SharedStub(uint64_t,uint64_t,uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t *);
/* Variable a0-a7 were put there so we can have access to the 8 input
registers on Stubxyz entry */
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n(uint64_t a1, \
uint64_t a2,uint64_t a3,uint64_t a4,uint64_t a5,uint64_t a6,uint64_t a7, \
uint64_t a8) \
{ uint64_t a0 = (uint64_t) this; \
return SharedStub(a0,a1,a2,a3,a4,a5,a6,a7,(uint64_t) n, &a8); \
}
#define SENTINEL_ENTRY(n) \
nsresult nsXPTCStubBase::Sentinel##n() \
{ \
NS_ERROR("nsXPTCStubBase::Sentinel called"); \
return NS_ERROR_NOT_IMPLEMENTED; \
}
#include "xptcstubsdef.inc"
-12
View File
@@ -345,18 +345,6 @@ snapshot from a couple of days ago).
</TD>
</TR>
<TR>
<TD bgcolor="green"><font color="white"><b>Done</b></font></TD>
<TD>Linux ia64</TD>
<TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
HP<br>
<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif">
<a href="mailto:drepper@redhat.com">Ulrich Drepper &lt;drepper@redhat.com&gt;</a>
</TD>
<TD><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=40950#c15">bug 40950 comment 15</a></TD>
</TR>
<TR>
<TD bgcolor="red"><font color="white"><b>HELP!</b></font></TD>
<TD>All others!</TD>
-8
View File
@@ -14,11 +14,7 @@
class xptiInterfaceEntry;
#if !defined(__ia64) || (!defined(__hpux) && !defined(__linux__) && !defined(__FreeBSD__))
#define STUB_ENTRY(n) NS_IMETHOD Stub##n() = 0;
#else
#define STUB_ENTRY(n) NS_IMETHOD Stub##n(uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t) = 0;
#endif
#define SENTINEL_ENTRY(n) NS_IMETHOD Sentinel##n() = 0;
@@ -31,11 +27,7 @@ public:
#undef STUB_ENTRY
#undef SENTINEL_ENTRY
#if !defined(__ia64) || (!defined(__hpux) && !defined(__linux__) && !defined(__FreeBSD__))
#define STUB_ENTRY(n) NS_IMETHOD Stub##n() override;
#else
#define STUB_ENTRY(n) NS_IMETHOD Stub##n(uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t) override;
#endif
#define SENTINEL_ENTRY(n) NS_IMETHOD Sentinel##n() override;
-497
View File
@@ -8,7 +8,6 @@
* 1 is AddRef
* 2 is Release
*/
#if !defined(__ia64) || (!defined(__hpux) && !defined(__linux__) && !defined(__FreeBSD__))
NS_IMETHOD Stub3();
NS_IMETHOD Stub4();
NS_IMETHOD Stub5();
@@ -256,502 +255,6 @@ NS_IMETHOD Stub246();
NS_IMETHOD Stub247();
NS_IMETHOD Stub248();
NS_IMETHOD Stub249();
#else
NS_IMETHOD Stub3(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub4(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub5(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub6(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub7(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub8(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub9(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub10(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub11(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub12(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub13(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub14(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub15(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub16(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub17(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub18(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub19(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub20(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub21(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub22(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub23(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub24(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub25(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub26(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub27(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub28(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub29(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub30(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub31(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub32(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub33(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub34(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub35(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub36(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub37(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub38(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub39(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub40(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub41(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub42(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub43(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub44(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub45(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub46(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub47(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub48(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub49(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub50(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub51(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub52(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub53(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub54(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub55(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub56(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub57(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub58(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub59(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub60(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub61(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub62(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub63(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub64(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub65(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub66(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub67(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub68(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub69(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub70(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub71(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub72(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub73(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub74(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub75(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub76(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub77(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub78(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub79(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub80(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub81(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub82(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub83(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub84(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub85(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub86(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub87(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub88(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub89(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub90(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub91(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub92(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub93(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub94(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub95(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub96(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub97(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub98(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub99(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub100(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub101(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub102(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub103(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub104(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub105(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub106(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub107(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub108(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub109(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub110(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub111(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub112(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub113(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub114(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub115(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub116(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub117(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub118(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub119(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub120(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub121(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub122(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub123(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub124(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub125(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub126(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub127(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub128(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub129(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub130(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub131(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub132(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub133(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub134(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub135(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub136(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub137(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub138(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub139(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub140(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub141(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub142(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub143(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub144(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub145(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub146(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub147(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub148(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub149(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub150(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub151(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub152(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub153(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub154(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub155(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub156(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub157(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub158(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub159(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub160(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub161(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub162(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub163(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub164(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub165(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub166(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub167(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub168(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub169(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub170(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub171(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub172(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub173(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub174(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub175(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub176(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub177(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub178(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub179(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub180(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub181(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub182(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub183(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub184(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub185(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub186(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub187(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub188(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub189(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub190(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub191(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub192(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub193(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub194(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub195(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub196(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub197(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub198(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub199(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub200(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub201(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub202(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub203(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub204(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub205(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub206(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub207(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub208(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub209(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub210(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub211(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub212(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub213(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub214(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub215(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub216(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub217(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub218(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub219(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub220(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub221(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub222(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub223(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub224(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub225(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub226(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub227(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub228(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub229(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub230(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub231(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub232(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub233(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub234(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub235(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub236(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub237(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub238(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub239(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub240(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub241(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub242(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub243(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub244(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub245(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub246(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub247(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub248(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
NS_IMETHOD Stub249(uint64_t,uint64_t,
uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
#endif
/* declarations of sentinel stubs */
NS_IMETHOD Sentinel0();