Merge mozilla-central to autoland. a=merge on a CLOSED TREE

This commit is contained in:
Razvan Maries 2019-01-11 17:33:16 +02:00
commit 642dd2cc11
132 changed files with 7656 additions and 725 deletions

View file

@ -1063,6 +1063,13 @@ function _loadURI(browser, uri, params = {}) {
if (!requiredRemoteType) {
browser.inLoadURI = true;
}
let loadURIOptions = {
triggeringPrincipal,
loadFlags: flags,
referrerURI,
referrerPolicy,
postData,
};
try {
if (!mustChangeProcess) {
if (userContextId) {
@ -1071,10 +1078,7 @@ function _loadURI(browser, uri, params = {}) {
privateBrowsingId: PrivateBrowsingUtils.isBrowserPrivate(browser) ? 1 : 0,
});
}
browser.webNavigation.loadURIWithOptions(uri, flags,
referrerURI, referrerPolicy,
postData, null, null, triggeringPrincipal);
browser.webNavigation.loadURI(uri, loadURIOptions);
} else {
// Check if the current browser is allowed to unload.
let {permitUnload, timedOut} = browser.permitUnload();
@ -1121,9 +1125,7 @@ function _loadURI(browser, uri, params = {}) {
privateBrowsingId: PrivateBrowsingUtils.isBrowserPrivate(browser) ? 1 : 0,
});
}
browser.webNavigation.loadURIWithOptions(uri, flags, referrerURI, referrerPolicy,
postData, null, null, triggeringPrincipal);
browser.webNavigation.loadURI(uri, loadURIOptions);
} else {
throw e;
}

View file

@ -63,9 +63,10 @@ function clear_history() {
var waitForLoad = async function(uri) {
info("Loading " + uri);
// Longwinded but this ensures we don't just shortcut to LoadInNewProcess
gBrowser.selectedBrowser.webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
null, null, null,
Services.scriptSecurityManager.getSystemPrincipal());
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
};
gBrowser.selectedBrowser.webNavigation.loadURI(uri, loadURIOptions);
await BrowserTestUtils.browserStopped(gBrowser);
gExpectedHistory.index++;

View file

@ -56,7 +56,7 @@ tags = blocklist
skip-if = toolkit == "gtk3" # fails intermittently on Linux (bug 909342)
tags = blocklist
[browser_CTP_crashreporting.js]
skip-if = !crashreporter || verify
skip-if = !crashreporter || verify || os == 'win' # bug 1442837
tags = blocklist
[browser_CTP_drag_drop.js]
tags = blocklist

View file

@ -54,6 +54,7 @@ skip-if = true || !healthreport # Bug 1185403 for the "true"
[browser_homepages_filter_aboutpreferences.js]
[browser_homepages_use_bookmark.js]
[browser_extension_controlled.js]
skipif = ccov && os == 'win' # bug 1437051
[browser_languages_subdialog.js]
[browser_browser_languages_subdialog.js]
[browser_layersacceleration.js]

View file

@ -204,19 +204,24 @@ ContentRestoreInternal.prototype = {
if (loadArguments.userContextId) {
webNavigation.setOriginAttributesBeforeLoading({ userContextId: loadArguments.userContextId });
}
webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
referrer, referrerPolicy, postData,
null, null, triggeringPrincipal);
let loadURIOptions = {
triggeringPrincipal,
loadFlags: loadArguments.flags,
referrerURI: referrer,
referrerPolicy,
postData,
};
webNavigation.loadURI(loadArguments.uri, loadURIOptions);
} else if (tabData.userTypedValue && tabData.userTypedClear) {
// If the user typed a URL into the URL bar and hit enter right before
// we crashed, we want to start loading that page again. A non-zero
// userTypedClear value means that the load had started.
// Load userTypedValue and fix up the URL if it's partial/broken.
webNavigation.loadURI(tabData.userTypedValue,
Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP,
null, null, null,
Services.scriptSecurityManager.getSystemPrincipal());
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP,
};
webNavigation.loadURI(tabData.userTypedValue, loadURIOptions);
} else if (tabData.entries.length) {
// Stash away the data we need for restoreDocument.
let activeIndex = tabData.index - 1;
@ -230,10 +235,11 @@ ContentRestoreInternal.prototype = {
history.reloadCurrentEntry();
} else {
// If there's nothing to restore, we should still blank the page.
webNavigation.loadURI("about:blank",
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
null, null, null,
Services.scriptSecurityManager.getSystemPrincipal());
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
};
webNavigation.loadURI("about:blank", loadURIOptions);
}
return true;
@ -377,9 +383,11 @@ HistoryListener.prototype = {
// STATE_START notification to be sent and the ProgressListener will then
// notify the parent and do the rest.
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
this.webNavigation.loadURI(newURI.spec, flags,
null, null, null,
Services.scriptSecurityManager.getSystemPrincipal());
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
loadFlags: flags,
};
this.webNavigation.loadURI(newURI.spec, loadURIOptions);
},
OnHistoryReload(reloadURI, reloadFlags) {

View file

@ -117,8 +117,7 @@ add_task(async function save_worthy_tabs_remote_final() {
// Replace about:blank with a new remote page.
let snippet = 'webNavigation.loadURI("https://example.com/",\
null, null, null, null,\
Services.scriptSecurityManager.getSystemPrincipal())';
{triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()})';
await promiseNewLocationAndHistoryEntryReplaced(browser, snippet);
// Remotness shouldn't have changed.

View file

@ -43,8 +43,10 @@ add_task(async function contentToChromeNavigate() {
await ContentTask.spawn(tab.linkedBrowser, null, function() {
const CHROME_URL = "about:config";
let webnav = content.window.getInterface(Ci.nsIWebNavigation);
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
webnav.loadURI(CHROME_URL, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null, systemPrincipal);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
};
webnav.loadURI(CHROME_URL, loadURIOptions);
});
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);

View file

@ -15,7 +15,10 @@ const progressListeners = new Map();
function loadContentWindow(webNavigation, uri, principal) {
return new Promise((resolve, reject) => {
webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null, principal);
let loadURIOptions = {
triggeringPrincipal: principal,
};
webNavigation.loadURI(uri, loadURIOptions);
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)

View file

@ -130,9 +130,12 @@ this.tabExtras = class extends ExtensionAPI {
},
};
windowTracker.addListener("progress", listener);
let triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal({});
tab.browser.webNavigation.loadURIWithOptions(url, null, null, null,
post, null, null, triggeringPrincipal);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
postData: post,
};
tab.browser.webNavigation.loadURI(url, loadURIOptions);
});
},
async getWebcompatInfo(tabId) {

View file

@ -302,13 +302,22 @@ endif # WINNT
ifdef _MSC_VER
ifeq ($(CPU_ARCH),x86_64)
ifdef MOZ_ASAN
# ASan could have 3x stack memory usage of normal builds.
WIN32_EXE_LDFLAGS += -STACK:6291456
# Normal operation on 64-bit Windows needs 2 MB of stack. (Bug 582910)
# ASAN requires 6 MB of stack.
# Setting the stack to 8 MB to match the capability of other systems
# to deal with frame construction for unreasonably deep DOM trees
# with worst-case styling. This uses address space unnecessarily for
# non-main threads, but that should be tolerable on 64-bit systems.
# (Bug 256180)
WIN32_EXE_LDFLAGS += -STACK:8388608
else
# set stack to 2MB on x64 build. See bug 582910
WIN32_EXE_LDFLAGS += -STACK:2097152
endif
# Since this setting affects the default stack size for non-main
# threads, too, to avoid burning the address space, increase only
# 512 KB over the default. Just enough to be able to deal with
# reasonable styling applied to DOM trees whose depth is near what
# Blink's HTML parser can output, esp.
# layout/base/crashtests/507119.html (Bug 256180)
WIN32_EXE_LDFLAGS += -STACK:1572864
endif
endif

View file

@ -58,6 +58,7 @@
#include "mozilla/dom/TabGroup.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/ChildSHistory.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/net/ReferrerPolicy.h"
@ -3803,37 +3804,22 @@ nsDocShell::GotoIndex(int32_t aIndex) {
return rootSH->LegacySHistory()->GotoIndex(aIndex);
}
NS_IMETHODIMP
nsDocShell::LoadURI(const nsAString& aURI, uint32_t aLoadFlags,
nsIURI* aReferringURI, nsIInputStream* aPostStream,
nsIInputStream* aHeaderStream,
nsIPrincipal* aTriggeringPrincipal) {
if (mUseStrictSecurityChecks && !aTriggeringPrincipal) {
return NS_ERROR_FAILURE;
}
return LoadURIWithOptions(aURI, aLoadFlags, aReferringURI, RP_Unset,
aPostStream, aHeaderStream, nullptr,
aTriggeringPrincipal);
}
nsresult nsDocShell::LoadURI(const nsAString& aURI,
const LoadURIOptions& aLoadURIOptions) {
uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
NS_IMETHODIMP
nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
nsIURI* aReferringURI, uint32_t aReferrerPolicy,
nsIInputStream* aPostStream,
nsIInputStream* aHeaderStream, nsIURI* aBaseURI,
nsIPrincipal* aTriggeringPrincipal) {
NS_ASSERTION((aLoadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
NS_ASSERTION((loadFlags & INTERNAL_LOAD_FLAGS_LOADURI_SETUP_FLAGS) == 0,
"Unexpected flags");
if (!IsNavigationAllowed()) {
return NS_OK; // JS may not handle returning of an error code
}
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIInputStream> postStream(aPostStream);
nsCOMPtr<nsIInputStream> postData(aLoadURIOptions.mPostData);
nsresult rv = NS_OK;
// Create a URI from our string; if that succeeds, we want to
// change aLoadFlags to not include the ALLOW_THIRD_PARTY_FIXUP
// change loadFlags to not include the ALLOW_THIRD_PARTY_FIXUP
// flag.
NS_ConvertUTF16toUTF8 uriString(aURI);
@ -3843,13 +3829,13 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
uriString.StripCRLF();
NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
if (mUseStrictSecurityChecks && !aTriggeringPrincipal) {
if (mUseStrictSecurityChecks && !aLoadURIOptions.mTriggeringPrincipal) {
return NS_ERROR_FAILURE;
}
rv = NS_NewURI(getter_AddRefs(uri), uriString);
if (uri) {
aLoadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
loadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
nsCOMPtr<nsIURIFixupInfo> fixupInfo;
@ -3859,10 +3845,10 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
// if NS_NewURI returned a URI, because fixup handles nested URIs, etc
// (things like view-source:mozilla.org for example).
uint32_t fixupFlags = 0;
if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
if (loadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
fixupFlags |= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
}
if (aLoadFlags & LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
if (loadFlags & LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
fixupFlags |= nsIURIFixup::FIXUP_FLAG_FIX_SCHEME_TYPOS;
}
nsCOMPtr<nsIInputStream> fixupStream;
@ -3879,10 +3865,10 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
// GetFixupURIInfo only returns a post data stream if it succeeded
// and changed the URI, in which case we should override the
// passed-in post data.
postStream = fixupStream;
postData = fixupStream;
}
if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
if (loadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
if (serv) {
serv->NotifyObservers(fixupInfo, "keyword-uri-fixup",
@ -3895,7 +3881,7 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
if (NS_ERROR_MALFORMED_URI == rv) {
if (DisplayLoadError(rv, uri, PromiseFlatString(aURI).get(), nullptr) &&
(aLoadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) {
(loadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) {
return NS_ERROR_LOAD_SHOWED_ERRORPAGE;
}
}
@ -3905,21 +3891,21 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
}
PopupBlocker::PopupControlState popupState;
if (aLoadFlags & LOAD_FLAGS_ALLOW_POPUPS) {
if (loadFlags & LOAD_FLAGS_ALLOW_POPUPS) {
popupState = PopupBlocker::openAllowed;
aLoadFlags &= ~LOAD_FLAGS_ALLOW_POPUPS;
loadFlags &= ~LOAD_FLAGS_ALLOW_POPUPS;
} else {
popupState = PopupBlocker::openOverridden;
}
nsAutoPopupStatePusher statePusher(popupState);
bool forceAllowDataURI = aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
bool forceAllowDataURI = loadFlags & LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
// Don't pass certain flags that aren't needed and end up confusing
// ConvertLoadTypeToDocShellInfoLoadType. We do need to ensure that they are
// passed to LoadURI though, since it uses them.
uint32_t extraFlags = (aLoadFlags & EXTRA_LOAD_FLAGS);
aLoadFlags &= ~EXTRA_LOAD_FLAGS;
uint32_t extraFlags = (loadFlags & EXTRA_LOAD_FLAGS);
loadFlags &= ~EXTRA_LOAD_FLAGS;
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(uri);
@ -3927,21 +3913,22 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
* If the user "Disables Protection on This Page", we have to make sure to
* remember the users decision when opening links in child tabs [Bug 906190]
*/
if (aLoadFlags & LOAD_FLAGS_ALLOW_MIXED_CONTENT) {
if (loadFlags & LOAD_FLAGS_ALLOW_MIXED_CONTENT) {
loadState->SetLoadType(
MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, aLoadFlags));
MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, loadFlags));
} else {
loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags));
loadState->SetLoadType(MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags));
}
loadState->SetLoadFlags(extraFlags);
loadState->SetFirstParty(true);
loadState->SetPostDataStream(postStream);
loadState->SetReferrer(aReferringURI);
loadState->SetReferrerPolicy((mozilla::net::ReferrerPolicy)aReferrerPolicy);
loadState->SetHeadersStream(aHeaderStream);
loadState->SetBaseURI(aBaseURI);
loadState->SetTriggeringPrincipal(aTriggeringPrincipal);
loadState->SetPostDataStream(postData);
loadState->SetReferrer(aLoadURIOptions.mReferrerURI);
loadState->SetReferrerPolicy(
(mozilla::net::ReferrerPolicy)aLoadURIOptions.mReferrerPolicy);
loadState->SetHeadersStream(aLoadURIOptions.mHeaders);
loadState->SetBaseURI(aLoadURIOptions.mBaseURI);
loadState->SetTriggeringPrincipal(aLoadURIOptions.mTriggeringPrincipal);
loadState->SetForceAllowDataURI(forceAllowDataURI);
if (fixupInfo) {
@ -3960,6 +3947,18 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
return rv;
}
NS_IMETHODIMP
nsDocShell::LoadURIFromScript(const nsAString& aURI,
JS::Handle<JS::Value> aLoadURIOptions,
JSContext* aCx) {
// generate dictionary for aLoadURIOptions and forward call
LoadURIOptions loadURIOptions;
if (!loadURIOptions.Init(aCx, aLoadURIOptions)) {
return NS_ERROR_INVALID_ARG;
}
return LoadURI(aURI, loadURIOptions);
}
NS_IMETHODIMP
nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
const char16_t* aURL, nsIChannel* aFailedChannel,
@ -6911,12 +6910,11 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
MOZ_ASSERT(loadInfo, "loadInfo is required on all channels");
nsCOMPtr<nsIPrincipal> triggeringPrincipal =
loadInfo->TriggeringPrincipal();
return LoadURI(newSpecW, // URI string
LOAD_FLAGS_NONE, // Load flags
nullptr, // Referring URI
newPostData, // Post data stream
nullptr, // Headers stream
triggeringPrincipal); // TriggeringPrincipal
LoadURIOptions loadURIOptions;
loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
loadURIOptions.mPostData = newPostData;
return LoadURI(newSpecW, loadURIOptions);
}
}
}

View file

@ -56,6 +56,7 @@
#include "mozilla/dom/Event.h" // for Event
#include "mozilla/dom/File.h" // for input type=file
#include "mozilla/dom/FileList.h" // for input type=file
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/TextEvents.h"
using namespace mozilla;
@ -896,8 +897,9 @@ nsDocShellTreeOwner::HandleEvent(Event* aEvent) {
"nsDocShellTreeOwner::HandleEvent: Need a valid "
"triggeringPrincipal");
#endif
webnav->LoadURI(url, 0, nullptr, nullptr, nullptr,
triggeringPrincipal);
LoadURIOptions loadURIOptions;
loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
webnav->LoadURI(url, loadURIOptions);
}
}

View file

@ -14,8 +14,15 @@ webidl Document;
%{ C++
#include "mozilla/dom/ChildSHistory.h"
namespace mozilla {
namespace dom {
struct LoadURIOptions;
} // namespace dom
} // namespace mozilla
%}
[ref] native LoadURIOptionsRef(const mozilla::dom::LoadURIOptions);
/**
* The nsIWebNavigation interface defines an interface for navigating the web.
* It provides methods and attributes to direct an object to navigate to a new
@ -219,103 +226,30 @@ interface nsIWebNavigation : nsISupports
*/
const unsigned long LOAD_FLAGS_IS_REDIRECT = 0x800000;
/**
* Loads a given URI. This will give priority to loading the requested URI
* in the object implementing this interface. If it can't be loaded here
* however, the URI dispatcher will go through its normal process of content
* loading.
*
* @param aURI
* The URI string to load. For HTTP and FTP URLs and possibly others,
* characters above U+007F will be converted to UTF-8 and then URL-
* escaped per the rules of RFC 2396.
* @param aLoadFlags
* Flags modifying load behaviour. This parameter is a bitwise
* combination of the load flags defined above. (Undefined bits are
* reserved for future use.) Generally you will pass LOAD_FLAGS_NONE
* for this parameter.
* @param aReferrer
* The referring URI. If this argument is null, then the referring
* URI will be inferred internally.
* @param aPostData
* If the URI corresponds to a HTTP request, then this stream is
* appended directly to the HTTP request headers. It may be prefixed
* with additional HTTP headers. This stream must contain a "\r\n"
* sequence separating any HTTP headers from the HTTP request body.
* This parameter is optional and may be null.
* @param aHeaders
* If the URI corresponds to a HTTP request, then any HTTP headers
* contained in this stream are set on the HTTP request. The HTTP
* header stream is formatted as:
* ( HEADER "\r\n" )*
* This parameter is optional and may be null.
* @param aTriggeringPrincipal
* The principal that initiated the load of aURI. If omitted docShell
* tries to create a codeBasePrincipal from aReferrer if not null. If
* aReferrer is also null docShell peforms a load using the
* SystemPrincipal as the triggeringPrincipal.
*/
void loadURI(in AString aURI,
in unsigned long aLoadFlags,
in nsIURI aReferrer,
in nsIInputStream aPostData,
in nsIInputStream aHeaders,
[optional] in nsIPrincipal aTriggeringPrincipal);
/**
* Loads a given URI. This will give priority to loading the requested URI
* in the object implementing this interface. If it can't be loaded here
* however, the URI dispatcher will go through its normal process of content
* loading.
*
* Behaves like loadURI, but allows passing of additional parameters.
*
* @param aURI
* The URI string to load. For HTTP and FTP URLs and possibly others,
* characters above U+007F will be converted to UTF-8 and then URL-
* escaped per the rules of RFC 2396.
* @param aLoadFlags
* Flags modifying load behaviour. This parameter is a bitwise
* combination of the load flags defined above. (Undefined bits are
* reserved for future use.) Generally you will pass LOAD_FLAGS_NONE
* for this parameter.
* @param aReferrer
* The referring URI. If this argument is null, then the referring
* URI will be inferred internally.
* @param aReferrerPolicy
* One of the REFERRER_POLICY_* constants from nsIHttpChannel.
* Normal case is REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE.
* @param aPostData
* If the URI corresponds to a HTTP request, then this stream is
* appended directly to the HTTP request headers. It may be prefixed
* with additional HTTP headers. This stream must contain a "\r\n"
* sequence separating any HTTP headers from the HTTP request body.
* This parameter is optional and may be null.
* @param aHeaders
* If the URI corresponds to a HTTP request, then any HTTP headers
* contained in this stream are set on the HTTP request. The HTTP
* header stream is formatted as:
* ( HEADER "\r\n" )*
* This parameter is optional and may be null.
* @param aBaseURI
* Set to indicate a base URI to be associated with the load. Note
* that at present this argument is only used with view-source aURIs
* and cannot be used to resolve aURI.
* This parameter is optional and may be null.
* @param aTriggeringPrincipal
* The principal that initiated the load of aURI. If omitted docShell
* tries to create a codeBasePrincipal from aReferrer if not null. If
* aReferrer is also null docShell peforms a load using the
* SystemPrincipal as the triggeringPrincipal.
* @param aLoadURIOptions
* A JSObject defined in LoadURIOptions.webidl holding info like e.g.
* the triggeringPrincipal, the referrer URI, the referrer policy.
*/
void loadURIWithOptions(in AString aURI,
in unsigned long aLoadFlags,
in nsIURI aReferrer,
in unsigned long aReferrerPolicy,
in nsIInputStream aPostData,
in nsIInputStream aHeaders,
in nsIURI aBaseURI,
[optional] in nsIPrincipal aTriggeringPrincipal);
[implicit_jscontext, binaryname(LoadURIFromScript)]
void loadURI(in AString aURI,
in jsval aLoadURIOptions);
/**
* A C++ friendly version of loadURI
*/
[nostdcall, binaryname(LoadURI)]
void binaryLoadURI(in AString aURI,
in LoadURIOptionsRef aLoadURIOptions);
/**
* Tells the Object to reload the current page. There may be cases where the

View file

@ -34,8 +34,10 @@ add_task(async function() {
equal(loadContext.usePrivateBrowsing, false,
"Should be able to change origin attributes prior to a document load");
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
webNav.loadURI("data:text/html,", webNav.LOAD_FLAGS_NONE, null, null, null, systemPrincipal);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
};
webNav.loadURI("data:text/html,", loadURIOptions);
// Return to the event loop so the load can begin.
await new Promise(executeSoon);

View file

@ -50,6 +50,17 @@ void TextEncoder::Encode(JSContext* aCx, JS::Handle<JSObject*> aObj,
aRetval.set(outView);
}
void TextEncoder::EncodeInto(const nsAString& aSrc, const Uint8Array& aDst,
TextEncoderEncodeIntoResult& aResult) {
aDst.ComputeLengthAndData();
size_t read;
size_t written;
Tie(read, written) = ConvertUTF16toUTF8Partial(
aSrc, MakeSpan(reinterpret_cast<char*>(aDst.Data()), aDst.Length()));
aResult.mRead.Construct() = read;
aResult.mWritten.Construct() = written;
}
void TextEncoder::GetEncoding(nsAString& aEncoding) {
aEncoding.AssignLiteral("utf-8");
}

View file

@ -60,6 +60,9 @@ class TextEncoder final : public NonRefcountedDOMObject {
void Encode(JSContext* aCx, JS::Handle<JSObject*> aObj,
const nsAString& aString, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
void EncodeInto(const nsAString& aSrc, const Uint8Array& aDst,
TextEncoderEncodeIntoResult& aResult);
};
} // namespace dom

View file

@ -23,6 +23,7 @@
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/dom/MessageManagerBinding.h"
#include "mozilla/dom/MouseEventBinding.h"
#include "mozilla/dom/Nullable.h"
@ -1007,11 +1008,14 @@ mozilla::ipc::IPCResult TabChild::RecvLoadURL(const nsCString& aURI,
ApplyShowInfo(aInfo);
}
nsresult rv = WebNavigation()->LoadURI(
NS_ConvertUTF8toUTF16(aURI),
LoadURIOptions loadURIOptions;
loadURIOptions.mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
loadURIOptions.mLoadFlags =
nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL,
nullptr, nullptr, nullptr, nsContentUtils::GetSystemPrincipal());
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
nsresult rv =
WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI), loadURIOptions);
if (NS_FAILED(rv)) {
NS_WARNING(
"WebNavigation()->LoadURI failed. Eating exception, what else can I "

View file

@ -83,6 +83,7 @@ errNoSpaceBetweenPublicAndSystemIds=No space between the doctype public and syst
errNoSpaceBetweenDoctypePublicKeywordAndQuote=No space between the doctype “PUBLIC” keyword and the quote.
# Tree builder errors
errDeepTree=The document tree is too deep. The tree will be flattened to be 513 elements deep.
errStrayStartTag2=Stray start tag “%1$S”.
errStrayEndTag=Stray end tag “%1$S”.
errUnclosedElements=End tag “%1$S” seen, but there were open elements.

View file

@ -25,6 +25,9 @@
#include "nsNetUtil.h"
#include "nsXULAppAPI.h"
#define REPORTING_PURGE_ALL "reporting:purge-all"
#define REPORTING_PURGE_HOST "reporting:purge-host"
namespace mozilla {
namespace dom {
@ -51,9 +54,9 @@ StaticRefPtr<ReportingHeader> gReporting;
obs->AddObserver(service, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC, false);
obs->AddObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
obs->AddObserver(service, "browser:purge-domain-data", false);
obs->AddObserver(service, "clear-origin-attributes-data", false);
obs->AddObserver(service, "extension:purge-localStorage", false);
obs->AddObserver(service, REPORTING_PURGE_HOST, false);
obs->AddObserver(service, REPORTING_PURGE_ALL, false);
gReporting = service;
}
@ -80,9 +83,9 @@ StaticRefPtr<ReportingHeader> gReporting;
obs->RemoveObserver(service, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC);
obs->RemoveObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
obs->RemoveObserver(service, "browser:purge-domain-data");
obs->RemoveObserver(service, "clear-origin-attributes-data");
obs->RemoveObserver(service, "extension:purge-localStorage");
obs->RemoveObserver(service, REPORTING_PURGE_HOST);
obs->RemoveObserver(service, REPORTING_PURGE_ALL);
}
ReportingHeader::ReportingHeader() = default;
@ -111,7 +114,7 @@ ReportingHeader::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
if (!strcmp(aTopic, "browser:purge-domain-data")) {
if (!strcmp(aTopic, REPORTING_PURGE_HOST)) {
RemoveOriginsFromHost(nsDependentString(aData));
return NS_OK;
}
@ -127,7 +130,7 @@ ReportingHeader::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
if (!strcmp(aTopic, "extension:purge-localStorage")) {
if (!strcmp(aTopic, REPORTING_PURGE_ALL)) {
RemoveOrigins();
return NS_OK;
}

View file

@ -67,10 +67,10 @@ add_task(async function() {
ok(ChromeUtils.hasReportingHeaderForOrigin(TEST_DOMAIN), "We have data");
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOM_QUOTA, value => resolve());
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_REPORTS, value => resolve());
});
ok(!ChromeUtils.hasReportingHeaderForOrigin(TEST_DOMAIN), "No data before a quota cleanup");
ok(!ChromeUtils.hasReportingHeaderForOrigin(TEST_DOMAIN), "No data before a reports cleanup");
info("Removing the tab");
BrowserTestUtils.removeTab(tab);
@ -91,10 +91,10 @@ add_task(async function() {
ok(ChromeUtils.hasReportingHeaderForOrigin(TEST_DOMAIN), "We have data");
await new Promise(resolve => {
Services.clearData.deleteDataFromHost(TEST_HOST, true, Ci.nsIClearDataService.CLEAR_DOM_QUOTA, value => resolve());
Services.clearData.deleteDataFromHost(TEST_HOST, true, Ci.nsIClearDataService.CLEAR_REPORTS, value => resolve());
});
ok(!ChromeUtils.hasReportingHeaderForOrigin(TEST_DOMAIN), "No data before a quota cleanup");
ok(!ChromeUtils.hasReportingHeaderForOrigin(TEST_DOMAIN), "No data before a reports cleanup");
info("Removing the tab");
BrowserTestUtils.removeTab(tab);

View file

@ -15,6 +15,7 @@
#include "nsNetUtil.h"
#include "nsQueryObject.h"
#include "mozilla/dom/nsCSPUtils.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/NullPrincipal.h"
using namespace mozilla;
@ -257,8 +258,10 @@ static bool ShouldIgnoreFrameOptions(nsIChannel* aChannel,
RefPtr<NullPrincipal> principal =
NullPrincipal::CreateWithInheritedAttributes(
loadInfo->TriggeringPrincipal());
webNav->LoadURI(NS_LITERAL_STRING("about:blank"), 0, nullptr, nullptr,
nullptr, principal);
LoadURIOptions loadURIOptions;
loadURIOptions.mTriggeringPrincipal = principal;
webNav->LoadURI(NS_LITERAL_STRING("about:blank"), loadURIOptions);
}
}
return false;

View file

@ -0,0 +1,60 @@
/* 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/. */
interface Principal;
interface URI;
interface InputStream;
/**
* This dictionary holds load arguments for docshell loads.
*/
dictionary LoadURIOptions {
/**
* The principal that initiated the load.
*/
Principal? triggeringPrincipal = null;
/**
* Flags modifying load behaviour. This parameter is a bitwise
* combination of the load flags defined in nsIWebNavigation.idl.
*/
long loadFlags = 0;
/**
* The referring URI. If this argument is null, then the referring
* URI will be inferred internally.
*/
URI? referrerURI = null;
/**
* Referrer Policy for the load, defaults to REFERRER_POLICY_UNSET.
* Alternatively use one of REFERRER_POLICY_* constants from
* nsIHttpChannel.
*/
long referrerPolicy = 0;
/**
* If the URI to be loaded corresponds to a HTTP request, then this stream is
* appended directly to the HTTP request headers. It may be prefixed
* with additional HTTP headers. This stream must contain a "\r\n"
* sequence separating any HTTP headers from the HTTP request body.
*/
InputStream? postData = null;
/**
* If the URI corresponds to a HTTP request, then any HTTP headers
* contained in this stream are set on the HTTP request. The HTTP
* header stream is formatted as:
* ( HEADER "\r\n" )*
*/
InputStream? headers = null;
/**
* Set to indicate a base URI to be associated with the load. Note
* that at present this argument is only used with view-source aURIs
* and cannot be used to resolve aURI.
*/
URI? baseURI = null;
};

View file

@ -10,6 +10,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
dictionary TextEncoderEncodeIntoResult {
unsigned long long read;
unsigned long long written;
};
[Constructor, Exposed=(Window,Worker)]
interface TextEncoder {
[Constant]
@ -24,4 +29,9 @@ interface TextEncoder {
*/
[NewObject]
Uint8Array encode(optional DOMString input = "");
/*
* The same comment about USVString as above applies here.
*/
TextEncoderEncodeIntoResult encodeInto(DOMString source, Uint8Array destination);
};

View file

@ -633,6 +633,7 @@ WEBIDL_FILES = [
'L10nUtils.webidl',
'LegacyQueryInterface.webidl',
'LinkStyle.webidl',
'LoadURIOptions.webidl',
'Location.webidl',
'MediaCapabilities.webidl',
'MediaDeviceInfo.webidl',

View file

@ -286,7 +286,7 @@ void LoadContextOptions(const char* aPrefName, void* /* aClosure */) {
.setWasmForceCranelift(
GetWorkerPref<bool>(NS_LITERAL_CSTRING("wasm_cranelift")))
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(GetWorkerPref<bool>(NS_LITERAL_CSTRING("wasm_gc")))
#endif
.setWasmVerbose(GetWorkerPref<bool>(NS_LITERAL_CSTRING("wasm_verbose")))

View file

@ -100,4 +100,5 @@ if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
CXXFLAGS += ['-Wno-error=shadow']
if CONFIG['NIGHTLY_BUILD']:
DEFINES['ENABLE_WASM_REFTYPES'] = True
DEFINES['ENABLE_WASM_GC'] = True

View file

@ -50,6 +50,7 @@
#include "mozilla/dom/Selection.h" // for AutoHideSelectionChanges, etc
#include "nsFrameSelection.h" // for nsFrameSelection
#include "nsBaseCommandController.h" // for nsBaseCommandController
#include "mozilla/dom/LoadURIOptionsBinding.h"
class nsISupports;
class nsIURI;
@ -940,8 +941,10 @@ void nsEditingSession::TimerCallback(nsITimer* aTimer, void* aClosure) {
if (docShell) {
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
if (webNav) {
webNav->LoadURI(NS_LITERAL_STRING("about:blank"), 0, nullptr, nullptr,
nullptr, nsContentUtils::GetSystemPrincipal());
LoadURIOptions loadURIOptions;
loadURIOptions.mTriggeringPrincipal =
nsContentUtils::GetSystemPrincipal();
webNav->LoadURI(NS_LITERAL_STRING("about:blank"), loadURIOptions);
}
}
}

View file

@ -18,8 +18,10 @@ add_task(async function test_windowlessBrowserTroubleshootCrash() {
};
Services.obs.addObserver(listener, "content-document-global-created");
});
let triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal({});
webNav.loadURI("about:blank", 0, null, null, null, triggeringPrincipal);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
};
webNav.loadURI("about:blank", loadURIOptions);
await onLoaded;

View file

@ -602,6 +602,21 @@ pub unsafe extern "C" fn encoding_mem_convert_utf16_to_utf8(
)
}
#[no_mangle]
pub unsafe extern "C" fn encoding_mem_convert_utf16_to_utf8_partial(
src: *const u16,
src_len: *mut usize,
dst: *mut u8,
dst_len: *mut usize,
) {
let (read, written) = encoding_rs::mem::convert_utf16_to_utf8_partial(
::std::slice::from_raw_parts(src, *src_len),
::std::slice::from_raw_parts_mut(dst, *dst_len),
);
*src_len = read;
*dst_len = written;
}
#[no_mangle]
pub unsafe extern "C" fn encoding_mem_convert_utf8_to_utf16(
src: *const u8,

View file

@ -670,23 +670,19 @@ static bool WasmBulkMemSupported(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
static bool TestGCEnabled(JSContext* cx) {
#ifdef ENABLE_WASM_GC
bool isSupported = cx->options().wasmBaseline() && cx->options().wasmGc();
#ifdef ENABLE_WASM_CRANELIFT
if (cx->options().wasmForceCranelift()) {
isSupported = false;
}
#endif
return isSupported;
#else
return false;
#endif
static bool WasmReftypesEnabled(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setBoolean(wasm::HasReftypesSupport(cx));
return true;
}
static bool WasmGcEnabled(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setBoolean(TestGCEnabled(cx));
#ifdef ENABLE_WASM_GC
args.rval().setBoolean(wasm::HasReftypesSupport(cx));
#else
args.rval().setBoolean(false);
#endif
return true;
}
@ -695,7 +691,7 @@ static bool WasmGeneralizedTables(JSContext* cx, unsigned argc, Value* vp) {
#ifdef ENABLE_WASM_GENERALIZED_TABLES
// Generalized tables depend on anyref, though not currently on (ref T)
// types nor on structures or other GC-proposal features.
bool isSupported = TestGCEnabled(cx);
bool isSupported = wasm::HasReftypesSupport(cx);
#else
bool isSupported = false;
#endif
@ -5971,9 +5967,13 @@ gc::ZealModeHelpText),
" Returns a boolean indicating whether a given module has finished compiled code for tier2. \n"
"This will return true early if compilation isn't two-tiered. "),
JS_FN_HELP("wasmReftypesEnabled", WasmReftypesEnabled, 1, 0,
"wasmReftypesEnabled(bool)",
" Returns a boolean indicating whether the WebAssembly reftypes proposal is enabled."),
JS_FN_HELP("wasmGcEnabled", WasmGcEnabled, 1, 0,
"wasmGcEnabled(bool)",
" Returns a boolean indicating whether the WebAssembly GC support is enabled."),
" Returns a boolean indicating whether the WebAssembly GC types proposal is enabled."),
JS_FN_HELP("wasmGeneralizedTables", WasmGeneralizedTables, 1, 0,
"wasmGeneralizedTables(bool)",

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Moving a JS value through a wasm anyref is a pair of boxing/unboxing
// conversions that leaves the value unchanged. There are many cases,

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled() || typeof WebAssembly.Global !== 'function'
// |jit-test| skip-if: !wasmReftypesEnabled() || typeof WebAssembly.Global !== 'function'
// Dummy object.
function Baguette(calories) {

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
const { startProfiling, endProfiling, assertEqPreciseStacks, isSingleStepProfilingEnabled } = WasmHelpers;

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Do not run the test if we're jit-compiling JS, since it's the wasm frames
// we're interested in and eager JS compilation can upset the test.

View file

@ -0,0 +1,22 @@
// |jit-test| skip-if: !wasmGcEnabled()
//
// ref.eq is part of the gc feature, not the reftypes feature.
let { exports } = wasmEvalText(`(module
(gc_feature_opt_in 2)
(func (export "ref_eq") (param $a anyref) (param $b anyref) (result i32)
(ref.eq (get_local $a) (get_local $b)))
(func (export "ref_eq_for_control") (param $a anyref) (param $b anyref) (result f64)
(if f64 (ref.eq (get_local $a) (get_local $b))
(f64.const 5.0)
(f64.const 3.0))))`);
assertEq(exports.ref_eq(null, null), 1);
assertEq(exports.ref_eq(null, {}), 0);
assertEq(exports.ref_eq(this, this), 1);
assertEq(exports.ref_eq_for_control(null, null), 5);
assertEq(exports.ref_eq_for_control(null, {}), 3);
assertEq(exports.ref_eq_for_control(this, this), 5);

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
gczeal(14, 1);
let { exports } = wasmEvalText(`(module

View file

@ -1,5 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// Ensure that if gc types aren't enabled, test cases properly fail.
// |jit-test| skip-if: !wasmReftypesEnabled()
// Dummy constructor.
function Baguette(calories) {
@ -90,25 +89,11 @@ let { exports } = wasmEvalText(`(module
get_local 0
ref.is_null
)
(func (export "ref_eq") (param $a anyref) (param $b anyref) (result i32)
(ref.eq (get_local $a) (get_local $b)))
(func (export "ref_eq_for_control") (param $a anyref) (param $b anyref) (result f64)
(if f64 (ref.eq (get_local $a) (get_local $b))
(f64.const 5.0)
(f64.const 3.0)))
)`);
assertEq(exports.is_null(), 1);
assertEq(exports.is_null_spill(), 1);
assertEq(exports.is_null_local(), 1);
assertEq(exports.ref_eq(null, null), 1);
assertEq(exports.ref_eq(null, {}), 0);
assertEq(exports.ref_eq(this, this), 1);
assertEq(exports.ref_eq_for_control(null, null), 5);
assertEq(exports.ref_eq_for_control(null, {}), 3);
assertEq(exports.ref_eq_for_control(this, this), 5);
// Anyref param and result in wasm functions.

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
load(libdir + "wasm-binary.js");

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled() || !wasmDebuggingIsSupported()
// |jit-test| skip-if: !wasmReftypesEnabled() || !wasmDebuggingIsSupported()
(function() {
let g = newGlobal();

View file

@ -0,0 +1,4 @@
// |jit-test| skip-if: wasmGcEnabled()
assertErrorMessage(() => wasmEvalText(`(module (func (param (ref 0)) (unreachable)))`),
WebAssembly.CompileError, /reference types not enabled/);

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: wasmGcEnabled()
// |jit-test| skip-if: wasmReftypesEnabled()
const { CompileError, validate } = WebAssembly;

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
enableShellAllocationMetadataBuilder();
gczeal(9, 1);

View file

@ -0,0 +1,41 @@
// |jit-test| skip-if: !wasmGcEnabled()
//
// Struct types are only available if we opt in, so test that.
let CURRENT_VERSION = 2;
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in ${CURRENT_VERSION})
(type (struct (field i32))))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(type (struct (field i32))))`)),
WebAssembly.CompileError,
/Structure types not enabled/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.new 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.get 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.set 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.narrow anyref anyref)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);

View file

@ -1,4 +1,6 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
//
// Also see gc-feature-opt-in-struct.js for tests that use the struct feature.
// Version numbers
@ -44,19 +46,6 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
WebAssembly.CompileError,
/GC feature version is unknown/);
// Struct types are only available if we opt in.
new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in ${CURRENT_VERSION})
(type (struct (field i32))))`));
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(type (struct (field i32))))`)),
WebAssembly.CompileError,
/Structure types not enabled/);
// Parameters of ref type are only available if we opt in.
new WebAssembly.Module(wasmTextToBinary(
@ -137,26 +126,3 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.new 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.get 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.set 0 0)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);
assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(func (struct.narrow anyref anyref)))`)),
WebAssembly.CompileError,
/unrecognized opcode/);

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Attempt to test intercalls from ion to baseline and back.
//

View file

@ -1,8 +1,4 @@
if (!wasmGcEnabled()) {
assertErrorMessage(() => wasmEvalText(`(module (func (param (ref 0)) (unreachable)))`),
WebAssembly.CompileError, /reference types not enabled/);
quit(0);
}
// |jit-test| skip-if: !wasmGcEnabled()
// Parsing and resolving.

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Tests wasm frame tracing. Only tests for direct and indirect call chains
// in wasm that lead to JS allocation. Does not test any timeout or interrupt

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Tests wasm frame tracing in the presence of interrupt handlers that perform
// allocation. The structure is

View file

@ -1,4 +1,4 @@
// |jit-test| skip-if: !wasmGcEnabled()
// |jit-test| skip-if: !wasmReftypesEnabled()
// Generates a bunch of numbers-on-the-heap, and tries to ensure that they are
// held live -- at least for a short while -- only by references from the wasm

View file

@ -0,0 +1,50 @@
// |jit-test| skip-if: !wasmGeneralizedTables() || !wasmGcEnabled()
// table.set in bounds with i32 x anyref - works, no value generated
// table.set with (ref T) - works
// table.set with null - works
// table.set out of bounds - fails
{
let ins = wasmEvalText(
`(module
(gc_feature_opt_in 2)
(table (export "t") 10 anyref)
(type $dummy (struct (field i32)))
(func (export "set_anyref") (param i32) (param anyref)
(table.set (get_local 0) (get_local 1)))
(func (export "set_null") (param i32)
(table.set (get_local 0) (ref.null)))
(func (export "set_ref") (param i32) (param anyref)
(table.set (get_local 0) (struct.narrow anyref (ref $dummy) (get_local 1))))
(func (export "make_struct") (result anyref)
(struct.new $dummy (i32.const 37))))`);
let x = {};
ins.exports.set_anyref(3, x);
assertEq(ins.exports.t.get(3), x);
ins.exports.set_null(3);
assertEq(ins.exports.t.get(3), null);
let dummy = ins.exports.make_struct();
ins.exports.set_ref(5, dummy);
assertEq(ins.exports.t.get(5), dummy);
assertErrorMessage(() => ins.exports.set_anyref(10, x), RangeError, /index out of bounds/);
assertErrorMessage(() => ins.exports.set_anyref(-1, x), RangeError, /index out of bounds/);
}
// table.grow on table of anyref with non-null ref value
{
let ins = wasmEvalText(
`(module
(gc_feature_opt_in 2)
(type $S (struct (field i32) (field f64)))
(table (export "t") 2 anyref)
(func (export "f") (result i32)
(table.grow (i32.const 1) (struct.new $S (i32.const 0) (f64.const 3.14)))))`);
assertEq(ins.exports.t.length, 2);
assertEq(ins.exports.f(), 2);
assertEq(ins.exports.t.length, 3);
assertEq(typeof ins.exports.t.get(2), "object");
}

View file

@ -223,7 +223,6 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
/table index out of range for table.get/);
// table.set in bounds with i32 x anyref - works, no value generated
// table.set with (ref T) - works
// table.set with null - works
// table.set out of bounds - fails
@ -232,23 +231,15 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
`(module
(gc_feature_opt_in 2)
(table (export "t") 10 anyref)
(type $dummy (struct (field i32)))
(func (export "set_anyref") (param i32) (param anyref)
(table.set (get_local 0) (get_local 1)))
(func (export "set_null") (param i32)
(table.set (get_local 0) (ref.null)))
(func (export "set_ref") (param i32) (param anyref)
(table.set (get_local 0) (struct.narrow anyref (ref $dummy) (get_local 1))))
(func (export "make_struct") (result anyref)
(struct.new $dummy (i32.const 37))))`);
(table.set (get_local 0) (ref.null))))`);
let x = {};
ins.exports.set_anyref(3, x);
assertEq(ins.exports.t.get(3), x);
ins.exports.set_null(3);
assertEq(ins.exports.t.get(3), null);
let dummy = ins.exports.make_struct();
ins.exports.set_ref(5, dummy);
assertEq(ins.exports.t.get(5), dummy);
assertErrorMessage(() => ins.exports.set_anyref(10, x), RangeError, /index out of bounds/);
assertErrorMessage(() => ins.exports.set_anyref(-1, x), RangeError, /index out of bounds/);
@ -378,22 +369,6 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
WebAssembly.CompileError,
/table index out of range for table.grow/);
// table.grow on table of anyref with non-null ref value
{
let ins = wasmEvalText(
`(module
(gc_feature_opt_in 2)
(type $S (struct (field i32) (field f64)))
(table (export "t") 2 anyref)
(func (export "f") (result i32)
(table.grow (i32.const 1) (struct.new $S (i32.const 0) (f64.const 3.14)))))`);
assertEq(ins.exports.t.length, 2);
assertEq(ins.exports.f(), 2);
assertEq(ins.exports.t.length, 3);
assertEq(typeof ins.exports.t.get(2), "object");
}
// table.size on table of anyref
for (let visibility of ['', '(export "t")', '(import "m" "t")']) {

View file

@ -211,7 +211,7 @@ JitCompileOptions::JitCompileOptions()
: cloneSingletons_(false),
profilerSlowAssertionsEnabled_(false),
offThreadCompilationAvailable_(false)
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
,
wasmGcEnabled_(false)
#endif
@ -224,7 +224,7 @@ JitCompileOptions::JitCompileOptions(JSContext* cx) {
cx->runtime()->geckoProfiler().enabled() &&
cx->runtime()->geckoProfiler().slowAssertionsEnabled();
offThreadCompilationAvailable_ = OffThreadCompilationAvailable(cx);
#ifdef ENABLE_WASM_GC
wasmGcEnabled_ = cx->options().wasmGc();
#ifdef ENABLE_WASM_REFTYPES
wasmGcEnabled_ = wasm::HasReftypesSupport(cx);
#endif
}

View file

@ -130,7 +130,7 @@ class JitCompileOptions {
return offThreadCompilationAvailable_;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGcEnabled() const { return wasmGcEnabled_; }
#endif
@ -138,7 +138,7 @@ class JitCompileOptions {
bool cloneSingletons_;
bool profilerSlowAssertionsEnabled_;
bool offThreadCompilationAvailable_;
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGcEnabled_;
#endif
};

View file

@ -6,10 +6,20 @@
# Nightly-only features
if CONFIG['NIGHTLY_BUILD']:
# TypedObject
DEFINES['ENABLE_BINARYDATA'] = True
# The evolving bulk-copy proposal - mem.fill, mem.copy,
# table.copy, etc
DEFINES['ENABLE_WASM_BULKMEM_OPS'] = True
DEFINES['ENABLE_WASM_GC'] = True
# Support the evolving reftypes proposal - anyref, funcref, null,
# and a few other things
DEFINES['ENABLE_WASM_REFTYPES'] = True
# Support table of anyref, multiple tables - requires reftypes
DEFINES['ENABLE_WASM_GENERALIZED_TABLES'] = True
# Support the evolving gc types proposal (struct types, etc)
DEFINES['ENABLE_WASM_GC'] = True
# Prevent (ref T) types from being exposed to JS content so that
# wasm need do no typechecking at the JS/wasm boundary
DEFINES['WASM_PRIVATE_REFTYPES'] = True
# Some huge-mapping optimization instead of bounds checks on supported

View file

@ -398,7 +398,7 @@ class JS_PUBLIC_API ContextOptions {
#ifdef ENABLE_WASM_CRANELIFT
wasmForceCranelift_(false),
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
wasmGc_(false),
#endif
testWasmAwaitTier2_(false),
@ -489,7 +489,7 @@ class JS_PUBLIC_API ContextOptions {
return *this;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGc() const { return wasmGc_; }
ContextOptions& setWasmGc(bool flag) {
wasmGc_ = flag;
@ -580,7 +580,7 @@ class JS_PUBLIC_API ContextOptions {
setWasm(false);
setWasmBaseline(false);
setWasmIon(false);
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
setWasmGc(false);
#endif
setNativeRegExp(false);
@ -597,7 +597,7 @@ class JS_PUBLIC_API ContextOptions {
#ifdef ENABLE_WASM_CRANELIFT
bool wasmForceCranelift_ : 1;
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool wasmGc_ : 1;
#endif
bool testWasmAwaitTier2_ : 1;

View file

@ -494,7 +494,7 @@ static bool enableWasmIon = false;
#ifdef ENABLE_WASM_CRANELIFT
static bool wasmForceCranelift = false;
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static bool enableWasmGc = false;
#endif
static bool enableWasmVerbose = false;
@ -10173,7 +10173,7 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
#ifdef ENABLE_WASM_CRANELIFT
wasmForceCranelift = op.getBoolOption("wasm-force-cranelift");
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
enableWasmGc = op.getBoolOption("wasm-gc");
#ifdef ENABLE_WASM_CRANELIFT
if (enableWasmGc && wasmForceCranelift) {
@ -10202,7 +10202,7 @@ static bool SetContextOptions(JSContext* cx, const OptionParser& op) {
#ifdef ENABLE_WASM_CRANELIFT
.setWasmForceCranelift(wasmForceCranelift)
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(enableWasmGc)
#endif
.setWasmVerbose(enableWasmVerbose)
@ -10529,7 +10529,7 @@ static void SetWorkerContextOptions(JSContext* cx) {
#ifdef ENABLE_WASM_CRANELIFT
.setWasmForceCranelift(wasmForceCranelift)
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(enableWasmGc)
#endif
.setWasmVerbose(enableWasmVerbose)
@ -10932,7 +10932,7 @@ int main(int argc, char** argv, char** envp) {
!op.addBoolOption('\0', "test-wasm-await-tier2",
"Forcibly activate tiering and block "
"instantiation on completion of tier2")
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
|| !op.addBoolOption('\0', "wasm-gc", "Enable wasm GC features")
#else
|| !op.addBoolOption('\0', "wasm-gc", "No-op")

View file

@ -1292,7 +1292,7 @@ class AstModule : public AstNode {
NameVector funcImportNames_;
AstTableVector tables_;
AstMemoryVector memories_;
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
uint32_t gcFeatureOptIn_;
#endif
ExportVector exports_;
@ -1313,7 +1313,7 @@ class AstModule : public AstNode {
funcImportNames_(lifo),
tables_(lifo),
memories_(lifo),
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
gcFeatureOptIn_(0),
#endif
exports_(lifo),
@ -1328,7 +1328,7 @@ class AstModule : public AstNode {
}
bool hasMemory() const { return !!memories_.length(); }
const AstMemoryVector& memories() const { return memories_; }
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool addGcFeatureOptIn(uint32_t version) {
gcFeatureOptIn_ = version;
return true;

View file

@ -11454,6 +11454,8 @@ bool BaseCompiler::emitBody() {
}
CHECK_NEXT(
emitComparison(emitCompareRef, ValType::AnyRef, Assembler::Equal));
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(Op::RefNull):
if (env_.gcTypesEnabled() == HasGcTypes::False) {
return iter_.unrecognizedOpcode(&op);

View file

@ -74,11 +74,7 @@ uint32_t wasm::ObservedCPUFeatures() {
CompileArgs::CompileArgs(JSContext* cx, ScriptedCaller&& scriptedCaller)
: scriptedCaller(std::move(scriptedCaller)) {
#ifdef ENABLE_WASM_GC
bool gcEnabled = cx->options().wasmGc();
#else
bool gcEnabled = false;
#endif
bool gcEnabled = HasReftypesSupport(cx);
baselineEnabled = cx->options().wasmBaseline();
ionEnabled = cx->options().wasmIon();

View file

@ -3650,6 +3650,8 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
#ifdef ENABLE_WASM_GC
case uint16_t(Op::RefEq):
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(Op::RefNull):
case uint16_t(Op::RefIsNull):
// Not yet supported

View file

@ -57,6 +57,19 @@ using mozilla::RangedPtr;
extern mozilla::Atomic<bool> fuzzingSafe;
bool wasm::HasReftypesSupport(JSContext* cx) {
#ifdef ENABLE_WASM_CRANELIFT
if (cx->options().wasmForceCranelift()) {
return false;
}
#endif
#ifdef ENABLE_WASM_REFTYPES
return cx->options().wasmGc() && cx->options().wasmBaseline();
#else
return false;
#endif
}
bool wasm::HasCompilerSupport(JSContext* cx) {
#if !MOZ_LITTLE_ENDIAN || defined(JS_CODEGEN_NONE)
return false;
@ -2047,7 +2060,7 @@ bool WasmTableObject::isNewborn() const {
tableKind = TableKind::AnyFunction;
#ifdef ENABLE_WASM_GENERALIZED_TABLES
} else if (StringEqualsAscii(elementLinearStr, "anyref")) {
if (!cx->options().wasmGc()) {
if (!HasReftypesSupport(cx)) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_WASM_BAD_ELEMENT);
return false;
@ -2459,8 +2472,8 @@ const Class WasmGlobalObject::class_ = {
globalType = ValType::F32;
} else if (StringEqualsAscii(typeLinearStr, "f64")) {
globalType = ValType::F64;
#ifdef ENABLE_WASM_GC
} else if (cx->options().wasmGc() &&
#ifdef ENABLE_WASM_REFTYPES
} else if (HasReftypesSupport(cx) &&
StringEqualsAscii(typeLinearStr, "anyref")) {
globalType = ValType::AnyRef;
#endif

View file

@ -53,6 +53,11 @@ bool HasStreamingSupport(JSContext* cx);
bool HasCachingSupport(JSContext* cx);
// Returns true if WebAssembly as configured by compile-time flags and run-time
// options can support reference types and stack walking.
bool HasReftypesSupport(JSContext* cx);
// Compiles the given binary wasm module given the ArrayBufferObject
// and links the module's imports with the given import object.

View file

@ -23,15 +23,24 @@ using namespace js::jit;
using namespace js::wasm;
#ifdef ENABLE_WASM_GENERALIZED_TABLES
// Actually we depend only on the reftypes proposal; this guard will change once
// reftypes and GC are pried apart properly.
#ifndef ENABLE_WASM_GC
#error "Generalized tables require the GC feature"
#ifndef ENABLE_WASM_REFTYPES
#error "Generalized tables require the reftypes feature"
#endif
#endif
#ifdef ENABLE_WASM_GC
#ifndef ENABLE_WASM_REFTYPES
#error "GC types require the reftypes feature"
#endif
#endif
#ifdef DEBUG
#ifdef ENABLE_WASM_REFTYPES
#define WASM_REF_OP(code) return code
#else
#define WASM_REF_OP(code) break
#endif
#ifdef ENABLE_WASM_GC
#define WASM_GC_OP(code) return code
#else
@ -172,7 +181,6 @@ OpKind wasm::Classify(OpBytes op) {
case Op::F64Le:
case Op::F64Gt:
case Op::F64Ge:
case Op::RefEq:
return OpKind::Comparison;
case Op::I32Eqz:
case Op::I32WrapI64:
@ -201,7 +209,6 @@ OpKind wasm::Classify(OpBytes op) {
case Op::F64ConvertUI64:
case Op::F64ReinterpretI64:
case Op::F64PromoteF32:
case Op::RefIsNull:
case Op::I32Extend8S:
case Op::I32Extend16S:
case Op::I64Extend8S:
@ -264,7 +271,11 @@ OpKind wasm::Classify(OpBytes op) {
case Op::GrowMemory:
return OpKind::GrowMemory;
case Op::RefNull:
WASM_GC_OP(OpKind::RefNull);
WASM_REF_OP(OpKind::RefNull);
case Op::RefIsNull:
WASM_REF_OP(OpKind::Conversion);
case Op::RefEq:
WASM_GC_OP(OpKind::Comparison);
case Op::MiscPrefix: {
switch (MiscOp(op.b1)) {
case MiscOp::Limit:

View file

@ -222,7 +222,7 @@ static const unsigned NonVolatileRegsPushSize =
NonVolatileRegs.fpus().getPushSizeInBytes();
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static const unsigned NumExtraPushed = 2; // tls and argv
#else
static const unsigned NumExtraPushed = 1; // argv
@ -346,7 +346,7 @@ static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe,
WasmTlsReg);
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
WasmPush(masm, WasmTlsReg);
#endif
@ -403,7 +403,7 @@ static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe,
// Recover the 'argv' pointer which was saved before aligning the stack.
WasmPop(masm, argv);
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
WasmPop(masm, WasmTlsReg);
#endif

View file

@ -88,7 +88,7 @@ class WasmToken {
Field,
Float,
Func,
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
GcFeatureOptIn,
#endif
GetGlobal,
@ -365,7 +365,7 @@ class WasmToken {
case Field:
case Float:
case Func:
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
case GcFeatureOptIn:
#endif
case Global:
@ -1308,7 +1308,7 @@ WasmToken WasmTokenStream::next() {
break;
case 'g':
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
if (consume(u"gc_feature_opt_in")) {
return WasmToken(WasmToken::GcFeatureOptIn, begin, cur_);
}
@ -4532,7 +4532,7 @@ static bool ParseMemory(WasmParseContext& c, AstModule* module) {
return module->addMemory(name, memory);
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
// Custom section for experimental work. The size of this section should always
// be 1 byte, and that byte is a nonzero varint7 carrying the version number
// being opted into.
@ -5076,7 +5076,7 @@ static AstModule* ParseModule(const char16_t* text, uintptr_t stackLimit,
}
break;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
case WasmToken::GcFeatureOptIn: {
if (!ParseGcFeatureOptIn(c, module)) {
return nullptr;
@ -6560,7 +6560,7 @@ static bool EncodeExpr(Encoder& e, AstExpr& expr) {
/*****************************************************************************/
// wasm AST binary serialization
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static bool EncodeGcFeatureOptInSection(Encoder& e, AstModule& module) {
uint32_t optInVersion = module.gcFeatureOptIn();
if (!optInVersion) {
@ -7158,7 +7158,7 @@ static bool EncodeModule(AstModule& module, Uint32Vector* offsets,
return false;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
if (!EncodeGcFeatureOptInSection(e, module)) {
return false;
}

View file

@ -981,6 +981,8 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
CHECK(iter.readComparison(ValType::AnyRef, &nothing, &nothing));
break;
}
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(Op::RefNull): {
if (env.gcTypesEnabled() == HasGcTypes::False) {
return iter.unrecognizedOpcode(&op);
@ -1414,7 +1416,7 @@ static bool DecodeStructType(Decoder& d, ModuleEnvironment* env,
return true;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
static bool DecodeGCFeatureOptInSection(Decoder& d, ModuleEnvironment* env) {
MaybeSectionRange range;
if (!d.startSection(SectionId::GcFeatureOptIn, env, &range, "type")) {
@ -2416,7 +2418,7 @@ bool wasm::DecodeModuleEnvironment(Decoder& d, ModuleEnvironment* env) {
return false;
}
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
if (!DecodeGCFeatureOptInSection(d, env)) {
return false;
}
@ -2790,9 +2792,9 @@ bool wasm::Validate(JSContext* cx, const ShareableBytes& bytecode,
UniqueChars* error) {
Decoder d(bytecode.bytes, 0, error);
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
HasGcTypes gcTypesConfigured =
cx->options().wasmGc() ? HasGcTypes::True : HasGcTypes::False;
HasReftypesSupport(cx) ? HasGcTypes::True : HasGcTypes::False;
#else
HasGcTypes gcTypesConfigured = HasGcTypes::False;
#endif

View file

@ -144,7 +144,7 @@ struct ModuleEnvironment {
// Module fields decoded from the module environment (or initialized while
// validating an asm.js module) and immutable during compilation:
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
// `gcFeatureOptIn` reflects the presence in a module of a GcFeatureOptIn
// section. This variable will be removed eventually, allowing it to be
// replaced everywhere by the value HasGcTypes::True.
@ -185,7 +185,7 @@ struct ModuleEnvironment {
sharedMemoryEnabled(sharedMemoryEnabled),
gcTypesConfigured(gcTypesConfigured),
compilerEnv(compilerEnv),
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
gcFeatureOptIn(HasGcTypes::False),
#endif
memoryUsage(MemoryUsage::None),

View file

@ -774,7 +774,7 @@ static void ReloadPrefsCallback(const char* pref, XPCJSContext* xpccx) {
bool useWasmCranelift =
Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_cranelift");
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
bool useWasmGc = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_gc");
#endif
bool useWasmVerbose = Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_verbose");
@ -867,7 +867,7 @@ static void ReloadPrefsCallback(const char* pref, XPCJSContext* xpccx) {
#ifdef ENABLE_WASM_CRANELIFT
.setWasmForceCranelift(useWasmCranelift)
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
.setWasmGc(useWasmGc)
#endif
.setWasmVerbose(useWasmVerbose)

View file

@ -64,4 +64,5 @@ if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
CXXFLAGS += ['-Wno-shadow', '-Werror=format']
if CONFIG['NIGHTLY_BUILD']:
DEFINES['ENABLE_WASM_REFTYPES'] = True
DEFINES['ENABLE_WASM_GC'] = True

View file

@ -318,7 +318,7 @@ load 499858-1.xhtml
load 500467-1.html
load 501878-1.html
load 503936-1.html
load 507119.html
skip-if(Android&&AndroidVersion<21) load 507119.html
load 522374-1.html
load 522374-2.html
load 526378-1.xul

View file

@ -13,7 +13,32 @@
#error This header/class should only be used within Mozilla code. It should not be used by extensions.
#endif
#define MAX_REFLOW_DEPTH 200
#if (defined(XP_WIN) && !defined(HAVE_64BIT_BUILD)) || defined(ANDROID)
// Blink's magic depth limit from its HTML parser (513) plus as much as fits in the
// default run-time stack on armv7 Android on Dalvik when using display: block minus
// a bit just to be sure. The Dalvik default stack crashes at 588. ART can do a few
// frames more. Using the same number for 32-bit Windows for consistency. Over there,
// Blink's magic depth of 513 doesn't fit in the default stack of 1 MB, but this magic
// depth fits when the default is grown by mere 192 KB (tested in 64 KB increments).
//
// 32-bit Windows has a different limit compared to 64-bit desktop, because the
// default stack size affects all threads and consumes address space. Fixing that
// is bug 1257522.
//
// 32-bit Android on ARM already happens to have defaults that are close enough to
// what makes sense as a temporary measure on Windows, so adjusting the Android
// stack can be a follow-up. The stack on 64-bit ARM needs adjusting in any case
// before 64-bit ARM can become tier-1. See bug 1400811.
//
// Ideally, we'd get rid of this smaller limit and make 32-bit Windows and Android
// capable of working with the Linux/Mac/Win64 number below.
#define MAX_REFLOW_DEPTH 585
#else
// Blink's magic depth limit from its HTML parser times two. Also just about fits
// within the system default runtime stack limit of 8 MB on 64-bit Mac and Linux with
// display: table-cell.
#define MAX_REFLOW_DEPTH 1026
#endif
/* nsIFrame is in the process of being deCOMtaminated, i.e., this file is
eventually going to be eliminated, and all callers will use nsFrame instead.

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>1026-deep display: table-cell</title>
</head>
<body>
<h1>1026-element-deep display: table-cell</h1>
<p>Actual depth (including text leaves): 1027
</body>
</html>

View file

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>1026-element-deep display: table-cell</title>
<script>
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
function count() {
var depth = 0;
var deepest = 0;
var current = document;
var next = null;
outer: for (;;) {
if ((next = current.firstChild)) {
depth++;
if (depth > deepest) {
deepest = depth;
}
current = next;
continue;
}
for (;;) {
if ((next = current.nextSibling)) {
current = next;
break;
}
current = current.parentNode;
depth--;
if (current == document) {
break outer;
}
}
}
var h1 = document.getElementsByTagName("h1")[0];
var p = document.createElement("p");
var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
p.appendChild(t);
h1.parentNode.insertBefore(p, h1.nextSibling);
}
function deep() {
var t = document.createTextNode("PASS");
var div = document.createElement("div");
div.appendChild(t);
for (var i = 0; i < 1023; i++) {
var another = document.createElement("div");
another.appendChild(div);
div = another;
}
document.body.appendChild(div);
count();
}
window.addEventListener('DOMContentLoaded', deep, false);
</script>
<style>
div {
display: table-cell;
}
</style>
</head>
<body>
<h1>1026-element-deep display: table-cell</h1>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>585-deep display: table-cell</title>
</head>
<body>
<h1>585-element-deep display: table-cell</h1>
<p>Actual depth (including text leaves): 586
</body>
</html>

View file

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>585-element-deep display: table-cell</title>
<script>
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
function count() {
var depth = 0;
var deepest = 0;
var current = document;
var next = null;
outer: for (;;) {
if ((next = current.firstChild)) {
depth++;
if (depth > deepest) {
deepest = depth;
}
current = next;
continue;
}
for (;;) {
if ((next = current.nextSibling)) {
current = next;
break;
}
current = current.parentNode;
depth--;
if (current == document) {
break outer;
}
}
}
var h1 = document.getElementsByTagName("h1")[0];
var p = document.createElement("p");
var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
p.appendChild(t);
h1.parentNode.insertBefore(p, h1.nextSibling);
}
function deep() {
var t = document.createTextNode("PASS");
var div = document.createElement("div");
div.appendChild(t);
for (var i = 0; i < 582; i++) {
var another = document.createElement("div");
another.appendChild(div);
div = another;
}
document.body.appendChild(div);
count();
}
window.addEventListener('DOMContentLoaded', deep, false);
</script>
<style>
div {
display: table-cell;
}
</style>
</head>
<body>
<h1>585-element-deep display: table-cell</h1>
</body>
</html>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>1026-deep display: block</title>
</head>
<body>
<h1>1026-element-deep display: block</h1>
<p>Actual depth (including text leaves): 1027
<div>PASS</div>
</body>
</html>

View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>1026-element-deep display: block</title>
<script>
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
function count() {
var depth = 0;
var deepest = 0;
var current = document;
var next = null;
outer: for (;;) {
if ((next = current.firstChild)) {
depth++;
if (depth > deepest) {
deepest = depth;
}
current = next;
continue;
}
for (;;) {
if ((next = current.nextSibling)) {
current = next;
break;
}
current = current.parentNode;
depth--;
if (current == document) {
break outer;
}
}
}
var h1 = document.getElementsByTagName("h1")[0];
var p = document.createElement("p");
var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
p.appendChild(t);
h1.parentNode.insertBefore(p, h1.nextSibling);
}
function deep() {
var t = document.createTextNode("PASS");
var div = document.createElement("div");
div.appendChild(t);
for (var i = 0; i < 1023; i++) {
var another = document.createElement("div");
another.appendChild(div);
div = another;
}
document.body.appendChild(div);
count();
}
window.addEventListener('DOMContentLoaded', deep, false);
</script>
</head>
<body>
<h1>1026-element-deep display: block</h1>
</body>
</html>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>585-deep display: block</title>
</head>
<body>
<h1>585-element-deep display: block</h1>
<p>Actual depth (including text leaves): 586
<div>PASS</div>
</body>
</html>

View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>585-element-deep display: block</title>
<script>
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
function count() {
var depth = 0;
var deepest = 0;
var current = document;
var next = null;
outer: for (;;) {
if ((next = current.firstChild)) {
depth++;
if (depth > deepest) {
deepest = depth;
}
current = next;
continue;
}
for (;;) {
if ((next = current.nextSibling)) {
current = next;
break;
}
current = current.parentNode;
depth--;
if (current == document) {
break outer;
}
}
}
var h1 = document.getElementsByTagName("h1")[0];
var p = document.createElement("p");
var t = document.createTextNode("Actual depth (including text leaves): " + deepest);
p.appendChild(t);
h1.parentNode.insertBefore(p, h1.nextSibling);
}
function deep() {
var t = document.createTextNode("PASS");
var div = document.createElement("div");
div.appendChild(t);
for (var i = 0; i < 582; i++) {
var another = document.createElement("div");
another.appendChild(div);
div = another;
}
document.body.appendChild(div);
count();
}
window.addEventListener('DOMContentLoaded', deep, false);
</script>
</head>
<body>
<h1>585-element-deep display: block</h1>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -38,6 +38,19 @@
== 23604-1.html 23604-1-ref.html
== 23604-2.html 23604-2-ref.html
!= 24998-1.html 24998-1-ref.html
# Debug builds and ASAN builds have larger stack frames, so skipped.
# 32-bit Windows doesn't have enough run-time stack to deal with the test, so skipped.
skip-if(isDebugBuild||AddressSanitizer||(winWidget&&(!is64Bit))||(Android&&AndroidVersion<21)) == 256180-1.html 256180-1-ref.html
# Debug builds have larger stack frames, so skipped.
# 32-bit Windows doesn't have enough run-time stack to deal with the test, so skipped.
skip-if(isDebugBuild||(winWidget&&(!is64Bit))||(Android&&AndroidVersion<21)) == 256180-2.html 256180-2-ref.html
# Debug builds and ASAN builds have larger stack frames, so skipped.
# 32-bit Windows doesn't have enough run-time stack to deal with the test, so skipped.
skip-if(isDebugBuild||AddressSanitizer||(winWidget&&(!is64Bit))||(Android&&AndroidVersion<21)) == 256180-3.html 256180-3-ref.html
# Debug builds have larger stack frames, so skipped.
skip-if(isDebugBuild) == 256180-4.html 256180-4-ref.html
skip-if(isDebugBuild) == 256180-6.html 256180-6-ref.html
skip-if(isDebugBuild) == 256180-5.html 256180-5-ref.html
== 25888-1l.html 25888-1l-ref.html
!= 25888-1l.html 25888-1l-notref.html
== 25888-1r.html 25888-1r-ref.html

View file

@ -208,9 +208,9 @@ load font-face-truncated-src.html
load large_border_image_width.html
load link-transition-before.html
load long-url-list-stack-overflow.html
load 1383981.html
load 1383981-2.html
load 1383981-3.html
skip-if(Android&&AndroidVersion<21) load 1383981.html
skip-if(Android&&AndroidVersion<21) load 1383981-2.html
skip-if(Android&&AndroidVersion<21) load 1383981-3.html
load 1384824-1.html
load 1384824-2.html
load 1386773.html

View file

@ -463,6 +463,8 @@ function BuildConditionSandbox(aURL) {
sandbox.qtWidget = xr.widgetToolkit == "qt";
sandbox.winWidget = xr.widgetToolkit == "windows";
sandbox.is64Bit = xr.is64Bit;
// Scrollbars that are semi-transparent. See bug 1169666.
sandbox.transparentScrollbars = xr.widgetToolkit == "gtk3";

View file

@ -1080,9 +1080,10 @@ function DoAssertionCheck()
function LoadURI(uri)
{
var flags = webNavigation().LOAD_FLAGS_NONE;
var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
webNavigation().loadURI(uri, flags, null, null, null, systemPrincipal);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
};
webNavigation().loadURI(uri, loadURIOptions);
}
function LogWarning(str)

View file

@ -101,14 +101,22 @@ var wrapper = {
// Set the iframe's location with loadURI/LOAD_FLAGS_BYPASS_HISTORY to
// avoid having a new history entry being added.
let webNav = iframe.frameLoader.docShell.QueryInterface(Ci.nsIWebNavigation);
webNav.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, null, null);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
};
webNav.loadURI(url, loadURIOptions);
},
retry: function() {
deferTransitionToRemoteAfterLoaded();
let webNav = this.iframe.frameLoader.docShell.QueryInterface(Ci.nsIWebNavigation);
webNav.loadURI(this.url, Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, null, null);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
};
webNav.loadURI(this.url, loadURIOptions);
},
iframeListener: {

View file

@ -3904,8 +3904,11 @@ Tab.prototype = {
// We were redirected; reload the original URL
url = this.originalURI.spec;
}
this.browser.docShell.loadURI(url, flags, null, null, null, this.browser.contentPrincipal);
let loadURIOptions = {
triggeringPrincipal: this.browser.contentPrincipal,
loadFlags: flags,
};
this.browser.docShell.loadURI(url, loadURIOptions);
},
destroy: function() {
@ -5079,8 +5082,11 @@ var ErrorPageEventHandler = {
attrs["privateBrowsingId"] = 1;
}
let triggeringPrincipal = nullServices.scriptSecurityManager.createNullPrincipal(attrs);
webNav.loadURI(location, Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER, null, null, triggeringPrincipal);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(attrs),
loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
};
webNav.loadURI(location, loadURIOptions);
// ....but add a notify bar as a reminder, so that they don't lose
// track after, e.g., tab switching.

View file

@ -6,6 +6,15 @@ ac_add_options --target=aarch64-linux-android
ac_add_options --with-branding=mobile/android/branding/nightly
export AR="$topsrcdir/clang/bin/llvm-ar"
export NM="$topsrcdir/clang/bin/llvm-nm"
export RANLIB="$topsrcdir/clang/bin/llvm-ranlib"
# Enable LTO if the NDK is available.
if [ -z "$NO_NDK" ]; then
ac_add_options --enable-lto
fi
export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
export MOZ_ANDROID_POCKET=1

View file

@ -16,4 +16,13 @@ export MOZ_TELEMETRY_REPORTING=1
export MOZ_ANDROID_MMA=1
export MOZ_ANDROID_POCKET=1
export AR="$topsrcdir/clang/bin/llvm-ar"
export NM="$topsrcdir/clang/bin/llvm-nm"
export RANLIB="$topsrcdir/clang/bin/llvm-ranlib"
# Enable LTO if the NDK is available.
if [ -z "$NO_NDK" ]; then
ac_add_options --enable-lto
fi
. "$topsrcdir/mobile/android/config/mozconfigs/common.override"

View file

@ -14,4 +14,13 @@ export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
export MOZ_ANDROID_POCKET=1
export AR="$topsrcdir/clang/bin/llvm-ar"
export NM="$topsrcdir/clang/bin/llvm-nm"
export RANLIB="$topsrcdir/clang/bin/llvm-ranlib"
# Enable LTO if the NDK is available.
if [ -z "$NO_NDK" ]; then
ac_add_options --enable-lto
fi
. "$topsrcdir/mobile/android/config/mozconfigs/common.override"

View file

@ -164,8 +164,11 @@ this.tabExtras = class extends ExtensionAPI {
},
};
windowTracker.addListener("progress", listener);
tab.browser.webNavigation.loadURIWithOptions(url, null, null, null,
post, null, null, null);
let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
postData: post,
};
tab.browser.webNavigation.loadURI(url, loadURIOptions);
});
},
async getWebcompatInfo(tabId) {

View file

@ -158,7 +158,9 @@ public class GeckoThread extends Thread {
}
GeckoThread() {
setName("Gecko");
// Request more (virtual) stack space to avoid overflows in the CSS frame
// constructor. 8 MB matches desktop.
super(null, null, "Gecko", 8 * 1024 * 1024);
}
@WrapForJNI

View file

@ -1467,7 +1467,7 @@ pref("javascript.options.wasm_baselinejit", true);
#ifdef ENABLE_WASM_CRANELIFT
pref("javascript.options.wasm_cranelift", false);
#endif
#ifdef ENABLE_WASM_GC
#ifdef ENABLE_WASM_REFTYPES
pref("javascript.options.wasm_gc", false);
#endif
pref("javascript.options.native_regexp", true);

View file

@ -46,6 +46,7 @@ if CONFIG['MOZ_ENABLE_WEBRENDER']:
DEFINES['MOZ_ENABLE_WEBRENDER'] = True
if CONFIG['NIGHTLY_BUILD']:
DEFINES['ENABLE_WASM_REFTYPES'] = True
DEFINES['ENABLE_WASM_GC'] = True
FINAL_TARGET_PP_FILES += [

View file

@ -37,8 +37,6 @@ public class StateSnapshot<T> implements TreeBuilderState<T> {
private final T headPointer;
private final T deepTreeSurrogateParent;
private final int mode;
private final int originalMode;
@ -62,23 +60,21 @@ public class StateSnapshot<T> implements TreeBuilderState<T> {
* @param needToDropLF
* @param quirks
*/
StateSnapshot(StackNode<T>[] stack,
StackNode<T>[] listOfActiveFormattingElements, int[] templateModeStack, T formPointer,
T headPointer, T deepTreeSurrogateParent, int mode, int originalMode,
boolean framesetOk, boolean needToDropLF, boolean quirks) {
this.stack = stack;
this.listOfActiveFormattingElements = listOfActiveFormattingElements;
this.templateModeStack = templateModeStack;
this.formPointer = formPointer;
this.headPointer = headPointer;
this.deepTreeSurrogateParent = deepTreeSurrogateParent;
this.mode = mode;
this.originalMode = originalMode;
this.framesetOk = framesetOk;
this.needToDropLF = needToDropLF;
this.quirks = quirks;
StateSnapshot(StackNode<T>[] stack, StackNode<T>[] listOfActiveFormattingElements,
int[] templateModeStack, T formPointer, T headPointer, int mode, int originalMode,
boolean framesetOk, boolean needToDropLF, boolean quirks) {
this.stack = stack;
this.listOfActiveFormattingElements = listOfActiveFormattingElements;
this.templateModeStack = templateModeStack;
this.formPointer = formPointer;
this.headPointer = headPointer;
this.mode = mode;
this.originalMode = originalMode;
this.framesetOk = framesetOk;
this.needToDropLF = needToDropLF;
this.quirks = quirks;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
*/
@ -121,16 +117,6 @@ public class StateSnapshot<T> implements TreeBuilderState<T> {
return headPointer;
}
/**
* Returns the deepTreeSurrogateParent.
*
* @return the deepTreeSurrogateParent
*/
@Override
public T getDeepTreeSurrogateParent() {
return deepTreeSurrogateParent;
}
/**
* Returns the mode.
*

View file

@ -444,11 +444,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private T headPointer;
/**
* Used to work around Gecko limitations. Not used in Java.
*/
private T deepTreeSurrogateParent;
protected @Auto char[] charBuffer;
protected int charBufferLen = 0;
@ -615,7 +610,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
listPtr = -1;
formPointer = null;
headPointer = null;
deepTreeSurrogateParent = null;
// [NOCPP[
html4 = false;
idLocations.clear();
@ -1644,7 +1638,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
public final void endTokenization() throws SAXException {
formPointer = null;
headPointer = null;
deepTreeSurrogateParent = null;
templateModeStack = null;
if (stack != null) {
while (currentPtr > -1) {
@ -4741,7 +4734,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
removeFromListOfActiveFormattingElements(formattingEltListPos);
return true;
}
// commonAncestor is used for running the algorithm and
// insertionCommonAncestor is used for the actual insertions to
// keep them depth-limited.
StackNode<T> commonAncestor = stack[formattingEltStackPos - 1]; // weak ref
T insertionCommonAncestor =
nodeFromStackWithBlinkCompat(formattingEltStackPos - 1); // weak ref
StackNode<T> furthestBlock = stack[furthestBlockPos]; // weak ref
// detachFromParent(furthestBlock.node); XXX AAA CHANGE
int bookmark = formattingEltListPos;
@ -4788,10 +4786,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// if (hasChildren(node.node)) { XXX AAA CHANGE
assert node == listOfActiveFormattingElements[nodeListPos];
assert node == stack[nodePos];
T clone = createElement("http://www.w3.org/1999/xhtml",
node.name, node.attributes.cloneAttributes(), commonAncestor.node
// CPPONLY: , htmlCreator(node.getHtmlCreator())
);
T clone = createElement("http://www.w3.org/1999/xhtml", node.name,
node.attributes.cloneAttributes(), insertionCommonAncestor
// CPPONLY: , htmlCreator(node.getHtmlCreator())
);
StackNode<T> newNode = createStackNode(node.getFlags(), node.ns,
node.name, clone, node.popName, node.attributes
// CPPONLY: , node.getHtmlCreator()
@ -4808,16 +4806,18 @@ public abstract class TreeBuilder<T> implements TokenHandler,
node = newNode;
// } XXX AAA CHANGE
detachFromParent(lastNode.node);
appendElement(lastNode.node, node.node);
appendElement(lastNode.node, nodeFromStackWithBlinkCompat(nodePos));
lastNode = node;
}
// If we insert into a foster parent, for simplicity, we insert
// accoding to the spec without Blink's depth limit.
if (commonAncestor.isFosterParenting()) {
fatal();
detachFromParent(lastNode.node);
insertIntoFosterParent(lastNode.node);
} else {
detachFromParent(lastNode.node);
appendElement(lastNode.node, commonAncestor.node);
appendElement(lastNode.node, insertionCommonAncestor);
}
T clone = createElement("http://www.w3.org/1999/xhtml",
formattingElt.name,
@ -5003,20 +5003,21 @@ public abstract class TreeBuilder<T> implements TokenHandler,
while (entryPos < listPtr) {
entryPos++;
StackNode<T> entry = listOfActiveFormattingElements[entryPos];
StackNode<T> currentNode = stack[currentPtr];
StackNode<T> current = stack[currentPtr];
T clone;
if (currentNode.isFosterParenting()) {
clone = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", entry.name,
entry.attributes.cloneAttributes()
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
);
if (current.isFosterParenting()) {
clone = createAndInsertFosterParentedElement(
"http://www.w3.org/1999/xhtml", entry.name, entry.attributes.cloneAttributes()
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
);
} else {
clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
entry.attributes.cloneAttributes(), currentNode.node
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
);
appendElement(clone, currentNode.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
entry.attributes.cloneAttributes(), currentNode
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
);
appendElement(clone, currentNode);
}
StackNode<T> entryClone = createStackNode(entry.getFlags(),
@ -5370,7 +5371,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// [NOCPP[
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
T currentNode = stack[currentPtr].node;
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode
/*
* head uses NS_NewHTMLSharedElement creator
@ -5412,10 +5413,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, current.node
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, currentNode
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
);
appendElement(elt, currentNode);
}
if (!isTemplateContents()) {
@ -5449,10 +5451,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement(
"http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, currentNode);
}
StackNode<T> node = createStackNode(elementName, elt, clone
// [NOCPP[
@ -5471,7 +5475,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
// This method can't be called for custom elements
T currentNode = stack[currentPtr].node;
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
@ -5505,10 +5509,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, currentNode);
}
StackNode<T> node = createStackNode(elementName, elt, popName
// [NOCPP[
@ -5543,10 +5548,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(null)
);
} else {
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
// CPPONLY: , htmlCreator(null)
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
// CPPONLY: , htmlCreator(null)
);
appendElement(elt, currentNode);
}
StackNode<T> node = createStackNode(elementName, elt, popName,
markAsHtmlIntegrationPoint
@ -5596,10 +5602,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
} else {
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
appendElement(elt, currentNode);
}
StackNode<T> node = createStackNode(elementName, popName, elt
// [NOCPP[
@ -5626,11 +5633,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(),
attributes, formOwner, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes,
formOwner, currentNode
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, currentNode);
}
StackNode<T> node = createStackNode(elementName, elt
// [NOCPP[
@ -5657,11 +5665,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", name,
attributes, formOwner, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt =
createElement("http://www.w3.org/1999/xhtml", name, attributes, formOwner, currentNode
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, currentNode);
}
elementPushed("http://www.w3.org/1999/xhtml", name, elt);
elementPopped("http://www.w3.org/1999/xhtml", name, elt);
@ -5685,10 +5694,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, currentNode);
}
elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
elementPopped("http://www.w3.org/1999/xhtml", popName, elt);
@ -5712,10 +5722,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
} else {
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
appendElement(elt, currentNode);
}
elementPushed("http://www.w3.org/2000/svg", popName, elt);
elementPopped("http://www.w3.org/2000/svg", popName, elt);
@ -5739,10 +5750,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: , htmlCreator(null)
);
} else {
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
// CPPONLY: , htmlCreator(null)
);
appendElement(elt, current.node);
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
// CPPONLY: , htmlCreator(null)
);
appendElement(elt, currentNode);
}
elementPushed("http://www.w3.org/1998/Math/MathML", popName, elt);
elementPopped("http://www.w3.org/1998/Math/MathML", popName, elt);
@ -5753,7 +5765,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
// Can't be called for custom elements
T currentNode = stack[currentPtr].node;
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
T elt = createElement("http://www.w3.org/1999/xhtml", "input", attributes,
form == null || fragment || isTemplateContents() ? null : form, currentNode
// CPPONLY: , htmlCreator(NS_NewHTMLInputElement)
@ -5767,7 +5779,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// [NOCPP[
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
T currentNode = stack[currentPtr].node;
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
T elt = createElement("http://www.w3.org/1999/xhtml", "form",
attributes, currentNode
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
@ -6179,8 +6191,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
System.arraycopy(templateModeStack, 0, templateModeStackCopy, 0,
templateModeStackCopy.length);
return new StateSnapshot<T>(stackCopy, listCopy, templateModeStackCopy, formPointer,
headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk,
needToDropLF, quirks);
headPointer, mode, originalMode, framesetOk, needToDropLF, quirks);
}
public boolean snapshotMatches(TreeBuilderState<T> snapshot) {
@ -6196,7 +6207,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|| templateModeStackLen != templateModePtr + 1
|| formPointer != snapshot.getFormPointer()
|| headPointer != snapshot.getHeadPointer()
|| deepTreeSurrogateParent != snapshot.getDeepTreeSurrogateParent()
|| mode != snapshot.getMode()
|| originalMode != snapshot.getOriginalMode()
|| framesetOk != snapshot.isFramesetOk()
@ -6303,7 +6313,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
System.arraycopy(templateModeStackCopy, 0, templateModeStack, 0, templateModeStackLen);
formPointer = snapshot.getFormPointer();
headPointer = snapshot.getHeadPointer();
deepTreeSurrogateParent = snapshot.getDeepTreeSurrogateParent();
mode = snapshot.getMode();
originalMode = snapshot.getOriginalMode();
framesetOk = snapshot.isFramesetOk();
@ -6320,6 +6329,32 @@ public abstract class TreeBuilder<T> implements TokenHandler,
return -1;
}
/**
* Returns <code>stack[stackPos].node</code> if <code>stackPos</code> is
* smaller than Blink's magic limit or the node at Blink's magic limit
* otherwise.
*
* In order to get Blink-compatible handling of excessive deeply-nested
* markup, this method must be used to obtain the node that is used as the
* parent node of an insertion.
*
* Blink's magic number is 512, but our counting is off by one compared to
* Blink's way of counting, so in order to get the same
* externally-observable outcome, we use 511 as our magic number.
*
* @param stackPos the stack position to attempt to read
* @return node at the position capped to Blink's magic number
* @throws SAXException
*/
private T nodeFromStackWithBlinkCompat(int stackPos) throws SAXException {
// Magic number if off by one relative to Blink's magic number, but the
// outcome is the same, because the counting is different by one.
if (stackPos > 511) {
errDeepTree();
return stack[511].node;
}
return stack[stackPos].node;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
*/
@ -6338,16 +6373,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
return headPointer;
}
/**
* Returns the deepTreeSurrogateParent.
*
* @return the deepTreeSurrogateParent
*/
@Override
public T getDeepTreeSurrogateParent() {
return deepTreeSurrogateParent;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
*/
@ -6446,6 +6471,16 @@ public abstract class TreeBuilder<T> implements TokenHandler,
return templateModePtr + 1;
}
/**
* Complains about an over-deep tree. Theoretically this should just be
* a warning, but in practice authors should take this as an error.
*
* @throws SAXException
*/
private void errDeepTree() throws SAXException {
err("The document tree is more than 513 elements deep, which causes Firefox and Chrome flatten the tree.");
}
/**
* Reports a stray start tag.
* @param name the name of the stray tag

View file

@ -31,8 +31,6 @@ class nsAHtml5TreeBuilderState {
virtual nsIContentHandle* getHeadPointer() = 0;
virtual nsIContentHandle* getDeepTreeSurrogateParent() = 0;
virtual int32_t getMode() = 0;
virtual int32_t getOriginalMode() = 0;

View file

@ -58,15 +58,13 @@ nsHtml5StateSnapshot::nsHtml5StateSnapshot(
jArray<nsHtml5StackNode*, int32_t> stack,
jArray<nsHtml5StackNode*, int32_t> listOfActiveFormattingElements,
jArray<int32_t, int32_t> templateModeStack, nsIContentHandle* formPointer,
nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent,
int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF,
bool quirks)
nsIContentHandle* headPointer, int32_t mode, int32_t originalMode,
bool framesetOk, bool needToDropLF, bool quirks)
: stack(stack),
listOfActiveFormattingElements(listOfActiveFormattingElements),
templateModeStack(templateModeStack),
formPointer(formPointer),
headPointer(headPointer),
deepTreeSurrogateParent(deepTreeSurrogateParent),
mode(mode),
originalMode(originalMode),
framesetOk(framesetOk),
@ -92,10 +90,6 @@ nsIContentHandle* nsHtml5StateSnapshot::getFormPointer() { return formPointer; }
nsIContentHandle* nsHtml5StateSnapshot::getHeadPointer() { return headPointer; }
nsIContentHandle* nsHtml5StateSnapshot::getDeepTreeSurrogateParent() {
return deepTreeSurrogateParent;
}
int32_t nsHtml5StateSnapshot::getMode() { return mode; }
int32_t nsHtml5StateSnapshot::getOriginalMode() { return originalMode; }

Some files were not shown because too many files have changed in this diff Show more