Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-02-04 12:08:00 +01:00
commit 2a07da30de
353 changed files with 5338 additions and 2123 deletions

View File

@ -39,7 +39,6 @@ parser/**
probes/**
python/**
rdf/**
services/**
startupcache/**
testing/**
tools/**
@ -170,6 +169,11 @@ mobile/android/components/Snippets.js
# Bug 1178739: Ignore this file as a quick fix for "Illegal yield expression"
mobile/android/modules/HomeProvider.jsm
# services/ exclusions
# Uses `#filter substitution`
services/sync/modules/constants.js
# toolkit/ exclusions
# Not part of the default build

View File

@ -39,7 +39,7 @@ public:
}
xpcAccessibleGeneric(ProxyAccessible* aProxy, uint32_t aInterfaces) :
mIntl(aProxy)
mIntl(aProxy), mSupportedIfaces(0)
{
if (aInterfaces & Interfaces::SELECTION) {
mSupportedIfaces |= eSelectable;

View File

@ -66,7 +66,7 @@ function toHexString(data) {
let hexString = "";
if (typeof data === "string") {
hexString = Array.from(data, (c, i) => toHexChar(data.charCodeAt(i))).join("");
} else if (typeof data === "array") {
} else if (data instanceof Array) {
hexString = data.map(toHexChar).join("");
}
return hexString;

View File

@ -33,7 +33,7 @@ function toHexString(data) {
let hexString = "";
if (typeof data === "string") {
hexString = Array.from(data, (c, i) => toHexChar(data.charCodeAt(i))).join("");
} else if (typeof data === "array") {
} else if (data instanceof Array) {
hexString = data.map(toHexChar).join("");
}
return hexString;

View File

@ -543,3 +543,5 @@ skip-if = !e10s || !crashreporter
skip-if = !e10s || !crashreporter
[browser_aboutTabCrashed_showForm.js]
skip-if = !e10s || !crashreporter
[browser_aboutTabCrashed_withoutDump.js]
skip-if = !e10s

View File

@ -0,0 +1,44 @@
"use strict";
const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
/**
* Monkey patches TabCrashHandler.getDumpID to return null in order to test
* about:tabcrashed when a dump is not available.
*/
add_task(function* setup() {
let originalGetDumpID = TabCrashHandler.getDumpID;
TabCrashHandler.getDumpID = function(browser) { return null; };
registerCleanupFunction(() => {
TabCrashHandler.getDumpID = originalGetDumpID;
});
});
/**
* Tests tab crash page when a dump is not available.
*/
add_task(function* test_without_dump() {
return BrowserTestUtils.withNewTab({
gBrowser,
url: PAGE,
}, function*(browser) {
let tab = gBrowser.getTabForBrowser(browser);
yield BrowserTestUtils.crashBrowser(browser);
let tabRemovedPromise = BrowserTestUtils.removeTab(tab, { dontRemove: true });
yield ContentTask.spawn(browser, null, function*() {
let doc = content.document;
ok(!doc.documentElement.classList.contains("crashDumpAvailable"),
"doesn't have crash dump");
let container = doc.getElementById("crash-reporter-container");
ok(container, "has crash-reporter-container");
ok(container.hidden, "crash-reporter-container is hidden");
doc.getElementById("closeTab").click();
});
yield tabRemovedPromise;
});
});

View File

@ -32,6 +32,7 @@ const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/NetUtil.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
'resource://gre/modules/PrivateBrowsingUtils.jsm');
@ -304,17 +305,10 @@ ShumwayStreamConverterBase.prototype = {
// Create a new channel that loads the viewer as a chrome resource.
var viewerUrl = 'chrome://shumway/content/viewer.wrapper.html';
// TODO use only newChannel2 after FF37 is released.
var channel = Services.io.newChannel2 ?
Services.io.newChannel2(viewerUrl,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER) :
Services.io.newChannel(viewerUrl, null, null);
var channel = NetUtil.newChannel({
uri: viewerUrl,
loadUsingSystemPrincipal: true
});
var converter = this;
var listener = this.listener;
@ -370,7 +364,7 @@ ShumwayStreamConverterBase.prototype = {
.getService(Ci.nsIScriptSecurityManager);
var resourcePrincipal = securityManager.getSystemPrincipal();
aRequest.owner = resourcePrincipal;
channel.asyncOpen(proxy, aContext);
channel.asyncOpen2(proxy);
},
// nsIRequestObserver::onStopRequest

View File

@ -228,7 +228,7 @@ this.TabCrashHandler = {
let dumpID = this.getDumpID(browser);
if (!dumpID) {
message.target.sendAsyncMessge("SetCrashReportAvailable", {
message.target.sendAsyncMessage("SetCrashReportAvailable", {
hasReport: false,
});
return;

View File

@ -189,19 +189,12 @@ OS_LDFLAGS += $(_DEBUG_LDFLAGS)
# XXX: What does this? Bug 482434 filed for better explanation.
ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_)
ifdef MOZ_DEBUG
ifneq (,$(MOZ_BROWSE_INFO)$(MOZ_BSCFILE))
OS_CFLAGS += -FR
OS_CXXFLAGS += -FR
endif
else # ! MOZ_DEBUG
ifndef MOZ_DEBUG
# MOZ_DEBUG_SYMBOLS generates debug symbols in separate PDB files.
# Used for generating an optimized build with debugging symbols.
# Used in the Windows nightlies to generate symbols for crash reporting.
ifdef MOZ_DEBUG_SYMBOLS
OS_CXXFLAGS += -UDEBUG -DNDEBUG
OS_CFLAGS += -UDEBUG -DNDEBUG
ifdef HAVE_64BIT_BUILD
OS_LDFLAGS += -DEBUG -OPT:REF,ICF
else
@ -211,10 +204,8 @@ endif
#
# Handle DMD in optimized builds.
# No opt to give sane callstacks.
#
ifdef MOZ_DMD
MOZ_OPTIMIZE_FLAGS=-Zi -Od -UDEBUG -DNDEBUG
ifdef HAVE_64BIT_BUILD
OS_LDFLAGS = -DEBUG -OPT:REF,ICF
else

View File

@ -8748,7 +8748,6 @@ if test -n "$MOZ_TELEMETRY_REPORTING" || test -n "$MOZ_SERVICES_HEALTHREPORT" ||
fi
dnl win32 options
AC_SUBST(MOZ_BROWSE_INFO)
AC_SUBST(WIN32_REDIST_DIR)
AC_SUBST(MAKENSISU)

View File

@ -294,6 +294,10 @@ pref("devtools.webconsole.persistlog", false);
// any timestamps.
pref("devtools.webconsole.timestampMessages", false);
// Web Console automatic multiline mode: |true| if you want incomplete statements
// to automatically trigger multiline editing (equivalent to shift + enter).
pref("devtools.webconsole.autoMultiline", true);
// The number of lines that are displayed in the web console for the Net,
// CSS, JS and Web Developer categories. These defaults should be kept in sync
// with DEFAULT_LOG_LIMIT in the webconsole frontend.

View File

@ -329,6 +329,7 @@ skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
[browser_webconsole_live_filtering_of_message_types.js]
[browser_webconsole_live_filtering_on_search_strings.js]
[browser_webconsole_message_node_id.js]
[browser_webconsole_multiline_input.js]
[browser_webconsole_netlogging.js]
[browser_webconsole_netlogging_basic.js]
[browser_webconsole_netlogging_panel.js]

View File

@ -7,9 +7,13 @@
const TEST_URI = "data:text/html;charset=utf-8,<p>bug 585991 - autocomplete " +
"popup keyboard usage test";
// We should turn off auto-multiline editing during these tests
const PREF_AUTO_MULTILINE = "devtools.webconsole.autoMultiline";
var HUD, popup, jsterm, inputNode, completeNode;
add_task(function*() {
Services.prefs.setBoolPref(PREF_AUTO_MULTILINE, false);
yield loadTab(TEST_URI);
let hud = yield openConsole();
@ -23,6 +27,7 @@ add_task(function*() {
yield popupHideAfterCompletionInText();
HUD = popup = jsterm = inputNode = completeNode = null;
Services.prefs.setBoolPref(PREF_AUTO_MULTILINE, true);
});
var consoleOpened = Task.async(function*(aHud) {

View File

@ -0,0 +1,70 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* 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/. */
// Tests that the console waits for more input instead of evaluating
// when valid, but incomplete, statements are present upon pressing enter
// -or- when the user ends a line with shift + enter.
"use strict";
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
"test/test-console.html";
let SHOULD_ENTER_MULTILINE = [
{input: "function foo() {" },
{input: "var a = 1," },
{input: "var a = 1;", shiftKey: true },
{input: "function foo() { }", shiftKey: true },
{input: "function" },
{input: "(x) =>" },
{input: "let b = {" },
{input: "let a = [" },
{input: "{" },
{input: "{ bob: 3343," },
{input: "function x(y=" },
{input: "Array.from(" },
// shift + enter creates a new line despite parse errors
{input: "{2,}", shiftKey: true },
];
let SHOULD_EXECUTE = [
{input: "function foo() { }" },
{input: "var a = 1;" },
{input: "function foo() { var a = 1; }" },
{input: '"asdf"' },
{input: '99 + 3' },
{input: '1, 2, 3' },
// errors
{input: 'function f(x) { let y = 1, }' },
{input: 'function f(x=,) {' },
{input: '{2,}' },
];
add_task(function* () {
let { tab, browser } = yield loadTab(TEST_URI);
let hud = yield openConsole();
let inputNode = hud.jsterm.inputNode;
for (let test of SHOULD_ENTER_MULTILINE) {
hud.jsterm.setInputValue(test.input);
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: test.shiftKey });
let inputValue = hud.jsterm.getInputValue();
is(inputNode.selectionStart, inputNode.selectionEnd,
"selection is collapsed");
is(inputNode.selectionStart, inputValue.length,
"caret at end of multiline input");
let inputWithNewline = test.input + "\n";
is(inputValue, inputWithNewline, "Input value is correct");
}
for (let test of SHOULD_EXECUTE) {
hud.jsterm.setInputValue(test.input);
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: test.shiftKey });
let inputValue = hud.jsterm.getInputValue();
is(inputNode.selectionStart, 0, "selection starts/ends at 0");
is(inputNode.selectionEnd, 0, "selection starts/ends at 0");
is(inputValue, "", "Input value is cleared");
}
});

View File

@ -11,6 +11,7 @@ const {Cc, Ci, Cu} = require("chrome");
const {Utils: WebConsoleUtils, CONSOLE_WORKER_IDS} =
require("devtools/shared/webconsole/utils");
const promise = require("promise");
const Debugger = require("Debugger");
loader.lazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1",
@ -198,6 +199,7 @@ const MIN_FONT_SIZE = 10;
const PREF_CONNECTION_TIMEOUT = "devtools.debugger.remote-timeout";
const PREF_PERSISTLOG = "devtools.webconsole.persistlog";
const PREF_MESSAGE_TIMESTAMP = "devtools.webconsole.timestampMessages";
const PREF_AUTO_MULTILINE = "devtools.webconsole.autoMultiline";
const PREF_INPUT_HISTORY_COUNT = "devtools.webconsole.inputHistoryCount";
/**
@ -3880,11 +3882,13 @@ JSTerm.prototype = {
break;
}
return;
} else if (event.shiftKey &&
event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN) {
// shift return
// TODO: expand the inputNode height by one line
return;
} else if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN) {
let autoMultiline = Services.prefs.getBoolPref(PREF_AUTO_MULTILINE);
if (event.shiftKey ||
(!Debugger.isCompilableUnit(inputNode.value) && autoMultiline)) {
// shift return or incomplete statement
return;
}
}
switch (event.keyCode) {

View File

@ -2272,7 +2272,7 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
// Refresh the principal on the compartment.
if (nsPIDOMWindowInner* win = GetInnerWindow()) {
win->RefreshCompartmentPrincipal();
nsGlobalWindow::Cast(win)->RefreshCompartmentPrincipal();
}
}
@ -13413,5 +13413,5 @@ nsIDocument::ReportHasScrollLinkedEffect()
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Async Pan/Zoom"),
this, nsContentUtils::eLAYOUT_PROPERTIES,
"ScrollLinkedEffectFound");
"ScrollLinkedEffectFound2");
}

View File

@ -480,7 +480,7 @@ public:
bool DispatchResizeEvent(const mozilla::CSSIntSize& aSize);
// Inner windows only.
virtual void RefreshCompartmentPrincipal() override;
void RefreshCompartmentPrincipal();
// For accessing protected field mFullScreen
friend class FullscreenTransitionTask;
@ -1427,7 +1427,7 @@ public:
// |interval| is in milliseconds.
nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
int32_t interval,
bool aIsInterval, int32_t* aReturn) override;
bool aIsInterval, int32_t* aReturn);
int32_t SetTimeoutOrInterval(JSContext* aCx,
mozilla::dom::Function& aFunction,
int32_t aTimeout,
@ -1437,13 +1437,7 @@ public:
int32_t aTimeout, bool aIsInterval,
mozilla::ErrorResult& aError);
void ClearTimeoutOrInterval(int32_t aTimerID,
mozilla::ErrorResult& aError);
nsresult ClearTimeoutOrInterval(int32_t aTimerID) override
{
mozilla::ErrorResult rv;
ClearTimeoutOrInterval(aTimerID, rv);
return rv.StealNSResult();
}
mozilla::ErrorResult& aError);
// JS specific timeout functions (JS args grabbed from context).
nsresult ResetTimersForNonBackgroundWindow();

View File

@ -151,32 +151,6 @@ public:
return mParentTarget;
}
bool HasMutationListeners(uint32_t aMutationEventType) const
{
MOZ_ASSERT(IsInnerWindow());
if (!mOuterWindow) {
NS_ERROR("HasMutationListeners() called on orphan inner window!");
return false;
}
return (mMutationBits & aMutationEventType) != 0;
}
void SetMutationListeners(uint32_t aType)
{
MOZ_ASSERT(IsInnerWindow());
if (!mOuterWindow) {
NS_ERROR("HasMutationListeners() called on orphan inner window!");
return;
}
mMutationBits |= aType;
}
virtual void MaybeUpdateTouchState() {}
nsIDocument* GetExtantDoc() const
@ -242,14 +216,6 @@ public:
virtual bool IsFrozen() const = 0;
// Add a timeout to this window.
virtual nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
int32_t interval,
bool aIsInterval, int32_t *aReturn) = 0;
// Clear a timeout from this window.
virtual nsresult ClearTimeoutOrInterval(int32_t aTimerID) = 0;
nsPIDOMWindowOuter* GetOuterWindow()
{
return mIsInnerWindow ? mOuterWindow.get() : AsOuter();
@ -383,43 +349,6 @@ public:
*/
virtual void FinishFullscreenChange(bool aIsFullscreen) = 0;
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a mouseenter/leave event listener.
*/
bool HasMouseEnterLeaveEventListeners()
{
return mMayHaveMouseEnterLeaveEventListener;
}
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a mouseenter/leave event listener.
*/
void SetHasMouseEnterLeaveEventListeners()
{
mMayHaveMouseEnterLeaveEventListener = true;
}
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a Pointerenter/leave event listener.
*/
bool HasPointerEnterLeaveEventListeners()
{
return mMayHavePointerEnterLeaveEventListener;
}
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a Pointerenter/leave event listener.
*/
void SetHasPointerEnterLeaveEventListeners()
{
mMayHavePointerEnterLeaveEventListener = true;
}
virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
JS::Handle<JSObject*> aHandler) = 0;
@ -578,14 +507,6 @@ public:
*/
virtual bool DispatchCustomEvent(const nsAString& aEventName) = 0;
/**
* Call when the document principal may have changed and the compartment
* principal needs to be updated.
*
* Inner windows only.
*/
virtual void RefreshCompartmentPrincipal() = 0;
/**
* Like nsIDOMWindow::Open, except that we don't navigate to the given URL.
*
@ -798,6 +719,65 @@ public:
nsPerformance* GetPerformance();
bool HasMutationListeners(uint32_t aMutationEventType) const
{
if (!mOuterWindow) {
NS_ERROR("HasMutationListeners() called on orphan inner window!");
return false;
}
return (mMutationBits & aMutationEventType) != 0;
}
void SetMutationListeners(uint32_t aType)
{
if (!mOuterWindow) {
NS_ERROR("HasMutationListeners() called on orphan inner window!");
return;
}
mMutationBits |= aType;
}
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a mouseenter/leave event listener.
*/
bool HasMouseEnterLeaveEventListeners()
{
return mMayHaveMouseEnterLeaveEventListener;
}
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a mouseenter/leave event listener.
*/
void SetHasMouseEnterLeaveEventListeners()
{
mMayHaveMouseEnterLeaveEventListener = true;
}
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a Pointerenter/leave event listener.
*/
bool HasPointerEnterLeaveEventListeners()
{
return mMayHavePointerEnterLeaveEventListener;
}
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a Pointerenter/leave event listener.
*/
void SetHasPointerEnterLeaveEventListeners()
{
mMayHavePointerEnterLeaveEventListener = true;
}
protected:
void CreatePerformanceObjectIfNeeded();
};

View File

@ -511,7 +511,7 @@ nsXHTMLContentSerializer::CheckElementStart(nsIContent * aContent,
}
bool
nsXHTMLContentSerializer::CheckElementEnd(Element* aElement,
nsXHTMLContentSerializer::CheckElementEnd(mozilla::dom::Element* aElement,
bool& aForceFormat,
nsAString& aStr)
{

View File

@ -5,20 +5,34 @@
import sys
import string
# Generates a line of WebIDL with the given spelling of the property name
# (whether camelCase, _underscorePrefixed, etc.) and the given array of
# extended attributes.
def generateLine(propName, extendedAttrs):
return " [%s] attribute DOMString %s;\n" % (", ".join(extendedAttrs),
propName)
propList = eval(sys.stdin.read())
props = ""
for [name, prop, id, flags, pref, proptype] in propList:
if "CSS_PROPERTY_INTERNAL" in flags:
continue
# Unfortunately, even some of the getters here are fallible
# (e.g. on nsComputedDOMStyle).
extendedAttrs = ["Throws", "TreatNullAs=EmptyString"]
if pref is not "":
extendedAttrs.append('Pref="%s"' % pref)
# webkit properties get a capitalized "WebkitFoo" accessor (added here)
# as well as a camelcase "webkitFoo" accessor (added next).
if (prop.startswith("Webkit")):
props += generateLine(prop, extendedAttrs)
# Generate a line with camelCase spelling of property-name (or capitalized,
# for Moz-prefixed properties):
if not prop.startswith("Moz"):
prop = prop[0].lower() + prop[1:]
# Unfortunately, even some of the getters here are fallible
# (e.g. on nsComputedDOMStyle).
props += " [%s] attribute DOMString %s;\n" % (", ".join(extendedAttrs),
prop)
props += generateLine(prop, extendedAttrs)
# Per spec, what's actually supposed to happen here is that we're supposed
# to have properties for:
#
@ -30,18 +44,17 @@ for [name, prop, id, flags, pref, proptype] in propList:
# Note that "float" will cause a property called "float" to exist due to (1)
# in that list.
#
# In practice, cssFloat is the only case in which "name" doesn't contain "-"
# but also doesn't match "prop". So the stuff we did with "prop" covers (3)
# and all of (1) except "float". If we now output attributes for all the
# cases where "name" doesn't match "prop" and "name" doesn't start with "-",
# that will cover "float" and (2).
# In practice, cssFloat is the only case in which "name" doesn't contain
# "-" but also doesn't match "prop". So the above generatePropLine() call
# covered (3) and all of (1) except "float". If we now output attributes
# for all the cases where "name" doesn't match "prop" and "name" doesn't
# start with "-", that will cover "float" and (2).
if prop != name and name[0] != "-":
extendedAttrs.append('BinaryName="%s"' % prop)
# Throw in a '_' before the attribute name, because some of these
# property names collide with IDL reserved words.
props += " [%s] attribute DOMString _%s;\n" % (
", ".join(extendedAttrs),
name)
props += generateLine("_" + name, extendedAttrs)
idlFile = open(sys.argv[1], "r")
idlTemplate = idlFile.read()

View File

@ -1304,8 +1304,7 @@ WebGLContext::ClearScreen()
const bool changeDrawBuffers = (mDefaultFB_DrawBuffer0 != LOCAL_GL_BACK);
if (changeDrawBuffers) {
const GLenum back = LOCAL_GL_BACK;
gl->fDrawBuffers(1, &back);
gl->Screen()->SetDrawBuffer(LOCAL_GL_BACK);
}
GLbitfield bufferBits = LOCAL_GL_COLOR_BUFFER_BIT;
@ -1317,7 +1316,7 @@ WebGLContext::ClearScreen()
ForceClearFramebufferWithDefaultValues(bufferBits, mNeedsFakeNoAlpha);
if (changeDrawBuffers) {
gl->fDrawBuffers(1, &mDefaultFB_DrawBuffer0);
gl->Screen()->SetDrawBuffer(mDefaultFB_DrawBuffer0);
}
}

View File

@ -827,7 +827,8 @@ protected:
public:
void Disable(GLenum cap);
void Enable(GLenum cap);
bool GetStencilBits(GLint* out_stencilBits);
bool GetStencilBits(GLint* const out_stencilBits);
bool GetChannelBits(const char* funcName, GLenum pname, GLint* const out_val);
virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
void GetParameter(JSContext* cx, GLenum pname,

View File

@ -994,6 +994,10 @@ WebGLContext::Hint(GLenum target, GLenum mode)
switch (target) {
case LOCAL_GL_GENERATE_MIPMAP_HINT:
// Deprecated and removed in desktop GL Core profiles.
if (gl->IsCoreProfile())
return;
isValid = true;
break;

View File

@ -73,7 +73,7 @@ StringValue(JSContext* cx, const nsAString& str, ErrorResult& rv)
}
bool
WebGLContext::GetStencilBits(GLint* out_stencilBits)
WebGLContext::GetStencilBits(GLint* const out_stencilBits)
{
*out_stencilBits = 0;
if (mBoundDrawFramebuffer) {
@ -97,9 +97,107 @@ WebGLContext::GetStencilBits(GLint* out_stencilBits)
return true;
}
bool
WebGLContext::GetChannelBits(const char* funcName, GLenum pname, GLint* const out_val)
{
if (mBoundDrawFramebuffer) {
if (!mBoundDrawFramebuffer->ValidateAndInitAttachments(funcName))
return false;
}
if (!mBoundDrawFramebuffer) {
switch (pname) {
case LOCAL_GL_RED_BITS:
case LOCAL_GL_GREEN_BITS:
case LOCAL_GL_BLUE_BITS:
*out_val = 8;
break;
case LOCAL_GL_ALPHA_BITS:
*out_val = (mOptions.alpha ? 8 : 0);
break;
case LOCAL_GL_DEPTH_BITS:
if (mOptions.depth) {
const auto& glFormats = gl->GetGLFormats();
GLenum depthFormat = glFormats.depth;
if (mOptions.stencil && glFormats.depthStencil) {
depthFormat = glFormats.depthStencil;
}
if (depthFormat == LOCAL_GL_DEPTH_COMPONENT16) {
*out_val = 16;
} else {
*out_val = 24;
}
} else {
*out_val = 0;
}
break;
case LOCAL_GL_STENCIL_BITS:
*out_val = (mOptions.stencil ? 8 : 0);
break;
default:
MOZ_CRASH("bad pname");
}
return true;
}
if (!gl->IsCoreProfile()) {
gl->fGetIntegerv(pname, out_val);
return true;
}
GLenum fbAttachment = 0;
GLenum fbPName = 0;
switch (pname) {
case LOCAL_GL_RED_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
break;
case LOCAL_GL_GREEN_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
break;
case LOCAL_GL_BLUE_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
break;
case LOCAL_GL_ALPHA_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE;
break;
case LOCAL_GL_DEPTH_BITS:
fbAttachment = LOCAL_GL_DEPTH_ATTACHMENT;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE;
break;
case LOCAL_GL_STENCIL_BITS:
fbAttachment = LOCAL_GL_STENCIL_ATTACHMENT;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE;
break;
default:
MOZ_CRASH("bad pname");
}
gl->fGetFramebufferAttachmentParameteriv(LOCAL_GL_DRAW_FRAMEBUFFER, fbAttachment,
fbPName, out_val);
return true;
}
JS::Value
WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
{
const char funcName[] = "getParameter";
if (IsContextLost())
return JS::NullValue();
@ -356,11 +454,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::Int32Value(refValue & stencilMask);
}
case LOCAL_GL_STENCIL_BITS: {
GLint stencilBits = 0;
GetStencilBits(&stencilBits);
return JS::Int32Value(stencilBits);
}
case LOCAL_GL_STENCIL_CLEAR_VALUE:
case LOCAL_GL_UNPACK_ALIGNMENT:
case LOCAL_GL_PACK_ALIGNMENT:
@ -370,28 +464,26 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_MAX_VERTEX_ATTRIBS:
case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
case LOCAL_GL_RED_BITS:
case LOCAL_GL_GREEN_BITS:
case LOCAL_GL_BLUE_BITS: {
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
}
case LOCAL_GL_DEPTH_BITS: {
GLint i = 0;
if (!mNeedsFakeNoDepth) {
gl->fGetIntegerv(pname, &i);
}
return JS::Int32Value(i);
}
case LOCAL_GL_ALPHA_BITS: {
GLint i = 0;
if (!mNeedsFakeNoAlpha) {
gl->fGetIntegerv(pname, &i);
}
return JS::Int32Value(i);
case LOCAL_GL_RED_BITS:
case LOCAL_GL_GREEN_BITS:
case LOCAL_GL_BLUE_BITS:
case LOCAL_GL_ALPHA_BITS:
case LOCAL_GL_DEPTH_BITS:
case LOCAL_GL_STENCIL_BITS: {
// Deprecated and removed in GL Core profiles, so special handling required.
GLint val;
if (!GetChannelBits(funcName, pname, &val))
return JS::NullValue();
return JS::Int32Value(val);
}
case LOCAL_GL_MAX_TEXTURE_SIZE:
return JS::Int32Value(mImplMaxTextureSize);

View File

@ -32,15 +32,17 @@ WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl)
fua->AllowUnsizedTexFormat(pi, usage);
};
const bool needSizedInternal = !gl->IsGLES();
MOZ_ASSERT_IF(needSizedInternal, gl->IsSupported(gl::GLFeature::texture_swizzle));
const bool needsSwizzle = gl->IsCoreProfile();
MOZ_ASSERT_IF(needsSwizzle, gl->IsSupported(gl::GLFeature::texture_swizzle));
const bool needsSizedFormat = !gl->IsGLES();
////////////////
pi = {LOCAL_GL_RGBA, LOCAL_GL_FLOAT};
dui = {pi.format, pi.format, pi.type};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_RGBA32F;
}
fnAdd(webgl::EffectiveFormat::RGBA32F);
@ -50,7 +52,7 @@ WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl)
pi = {LOCAL_GL_RGB, LOCAL_GL_FLOAT};
dui = {pi.format, pi.format, pi.type};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_RGB32F;
}
fnAdd(webgl::EffectiveFormat::RGB32F);
@ -60,9 +62,11 @@ WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl)
pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_FLOAT};
dui = {pi.format, pi.format, pi.type};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSwizzle) {
dui = {LOCAL_GL_R32F, LOCAL_GL_RED, LOCAL_GL_FLOAT};
swizzle = webgl::FormatUsageInfo::kLuminanceSwizzleRGBA;
} else if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_LUMINANCE32F_ARB;
}
fnAdd(webgl::EffectiveFormat::Luminance32F);
@ -71,9 +75,11 @@ WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl)
pi = {LOCAL_GL_ALPHA, LOCAL_GL_FLOAT};
dui = {pi.format, pi.format, pi.type};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSwizzle) {
dui = {LOCAL_GL_R32F, LOCAL_GL_RED, LOCAL_GL_FLOAT};
swizzle = webgl::FormatUsageInfo::kAlphaSwizzleRGBA;
} else if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_ALPHA32F_ARB;
}
fnAdd(webgl::EffectiveFormat::Alpha32F);
@ -82,9 +88,11 @@ WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl)
pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_FLOAT};
dui = {pi.format, pi.format, pi.type};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSwizzle) {
dui = {LOCAL_GL_RG32F, LOCAL_GL_RG, LOCAL_GL_FLOAT};
swizzle = webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA;
} else if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_LUMINANCE_ALPHA32F_ARB;
}
fnAdd(webgl::EffectiveFormat::Luminance32FAlpha32F);
}
@ -101,10 +109,9 @@ WebGLExtensionTextureFloat::IsSupported(const WebGLContext* webgl)
if (!gl->IsSupported(gl::GLFeature::texture_float))
return false;
const bool needSizedInternal = !gl->IsGLES();
const bool needsSwizzle = gl->IsCoreProfile();
const bool hasSwizzle = gl->IsSupported(gl::GLFeature::texture_swizzle);
if (needSizedInternal && !hasSwizzle)
if (needsSwizzle && !hasSwizzle)
return false;
return true;

View File

@ -30,8 +30,10 @@ WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* web
fua->AllowUnsizedTexFormat(pi, usage);
};
const bool needSizedInternal = !gl->IsGLES();
MOZ_ASSERT_IF(needSizedInternal, gl->IsSupported(gl::GLFeature::texture_swizzle));
const bool needsSwizzle = gl->IsCoreProfile();
MOZ_ASSERT_IF(needsSwizzle, gl->IsSupported(gl::GLFeature::texture_swizzle));
const bool needsSizedFormat = !gl->IsGLES();
GLenum driverUnpackType = LOCAL_GL_HALF_FLOAT;
if (!gl->IsSupported(gl::GLFeature::texture_half_float)) {
@ -44,7 +46,7 @@ WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* web
pi = {LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT_OES};
dui = {pi.format, pi.format, driverUnpackType};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_RGBA16F;
}
fnAdd(webgl::EffectiveFormat::RGBA16F);
@ -54,7 +56,7 @@ WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* web
pi = {LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT_OES};
dui = {pi.format, pi.format, driverUnpackType};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_RGB16F;
}
fnAdd(webgl::EffectiveFormat::RGB16F);
@ -64,9 +66,11 @@ WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* web
pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_HALF_FLOAT_OES};
dui = {pi.format, pi.format, driverUnpackType};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSwizzle) {
dui = {LOCAL_GL_R16F, LOCAL_GL_RED, driverUnpackType};
swizzle = webgl::FormatUsageInfo::kLuminanceSwizzleRGBA;
} else if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_LUMINANCE16F_ARB;
}
fnAdd(webgl::EffectiveFormat::Luminance16F);
@ -75,9 +79,11 @@ WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* web
pi = {LOCAL_GL_ALPHA, LOCAL_GL_HALF_FLOAT_OES};
dui = {pi.format, pi.format, driverUnpackType};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSwizzle) {
dui = {LOCAL_GL_R16F, LOCAL_GL_RED, driverUnpackType};
swizzle = webgl::FormatUsageInfo::kAlphaSwizzleRGBA;
} else if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_ALPHA16F_ARB;
}
fnAdd(webgl::EffectiveFormat::Alpha16F);
@ -86,9 +92,11 @@ WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* web
pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_HALF_FLOAT_OES};
dui = {pi.format, pi.format, driverUnpackType};
swizzle = nullptr;
if (needSizedInternal) {
if (needsSwizzle) {
dui = {LOCAL_GL_RG16F, LOCAL_GL_RG, driverUnpackType};
swizzle = webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA;
} else if (needsSizedFormat) {
dui.internalFormat = LOCAL_GL_LUMINANCE_ALPHA16F_ARB;
}
fnAdd(webgl::EffectiveFormat::Luminance16FAlpha16F);
}
@ -108,10 +116,9 @@ WebGLExtensionTextureHalfFloat::IsSupported(const WebGLContext* webgl)
return false;
}
const bool needSizedInternal = !gl->IsGLES();
const bool needsSwizzle = gl->IsCoreProfile();
const bool hasSwizzle = gl->IsSupported(gl::GLFeature::texture_swizzle);
if (needSizedInternal && !hasSwizzle)
if (needsSwizzle && !hasSwizzle)
return false;
return true;

View File

@ -7,7 +7,7 @@
TEST_DIRS += ['compiledtest']
# Number changes to this file to avoid bug 1081323 (clobber after changing a manifest):
# 3
# 5
MOCHITEST_MANIFESTS += [
'test/crossorigin/mochitest.ini',

View File

@ -3,10 +3,51 @@ subsuite = webgl
skip-if = ((os == 'linux') && (buildapp == 'b2g'))
support-files =
webgl-mochitest/ensure-exts/ensure-ext.js
webgl-mochitest/driver-info.js
webgl-mochitest/es3-data.js
webgl-mochitest/webgl-util.js
[webgl-mochitest/ensure-exts/test_ANGLE_instanced_arrays.html]
fail-if = (os == 'android') || (os == 'mac' && os_version == '10.6')
[webgl-mochitest/ensure-exts/test_EXT_blend_minmax.html]
fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_EXT_color_buffer_half_float.html]
fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_EXT_disjoint_timer_query.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
[webgl-mochitest/ensure-exts/test_EXT_frag_depth.html]
fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_EXT_sRGB.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac' && os_version == '10.6') || (os == 'win')
[webgl-mochitest/ensure-exts/test_EXT_shader_texture_lod.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac')
[webgl-mochitest/ensure-exts/test_EXT_texture_filter_anisotropic.html]
fail-if = (os == 'android') || (os == 'linux')
[webgl-mochitest/ensure-exts/test_OES_standard_derivatives.html]
fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_WEBGL_color_buffer_float.html]
fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_atc.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
[webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_es3.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
[webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_etc1.html]
# Win7 is 6.1
fail-if = (os == 'linux') || (os == 'mac') || (os == 'win' && (os_version == '5.1' || os_version == '6.1'))
[webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_pvrtc.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
[webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_s3tc.html]
fail-if = (os == 'android') || (os == 'linux')
[webgl-mochitest/ensure-exts/test_WEBGL_depth_texture.html]
fail-if = (os == 'mac' && os_version == '10.6')
[webgl-mochitest/ensure-exts/test_WEBGL_draw_buffers.html]
# Win7 is 6.1
fail-if = (os == 'android') || (os == 'win' && (os_version == '5.1' || os_version == '6.1'))
[webgl-mochitest/ensure-exts/test_common.html]
[webgl-mochitest/test_backbuffer_channels.html]
fail-if = (os == 'b2g')
[webgl-mochitest/test_depth_readpixels.html]

View File

@ -0,0 +1,32 @@
'use strict';
function EnsureExt(name, shouldBe = true) {
var c = document.createElement('canvas');
var gl = c.getContext('experimental-webgl');
if (shouldBe) {
ok(gl.getExtension(name), 'Should have extension ' + name + '.');
} else {
ok(!gl.getExtension(name), 'Should not have extension ' + name + '.');
}
}
function EnsureDraftExt(name, shouldBe = true) {
SimpleTest.waitForExplicitFinish();
var fnEnsure = function() {
EnsureExt(name, shouldBe);
SimpleTest.finish();
};
if ('SpecialPowers' in window) {
var prefStateList = [
['webgl.enable-draft-extensions', true],
];
var prefEnv = {'set': prefStateList};
SpecialPowers.pushPrefEnv(prefEnv, fnEnsure);
} else {
console.log('Couldn\'t use SpecialPowers to enable draft extensions.');
fnEnsure();
}
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('ANGLE_instanced_arrays');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('EXT_blend_minmax');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('EXT_color_buffer_half_float');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureDraftExt('EXT_disjoint_timer_query');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('EXT_frag_depth');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('EXT_sRGB');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('EXT_shader_texture_lod');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('EXT_texture_filter_anisotropic');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('OES_standard_derivatives');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('WEBGL_color_buffer_float');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('WEBGL_compressed_texture_atc');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureDraftExt('WEBGL_compressed_texture_es3');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('WEBGL_compressed_texture_etc1');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('WEBGL_compressed_texture_pvrtc');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('WEBGL_compressed_texture_s3tc');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('WEBGL_depth_texture');
</script>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
EnsureExt('WEBGL_draw_buffers');
</script>
</body>
</html>

View File

@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
</head>
<body>
<script>
'use strict';
var c = document.createElement('canvas');
var gl = c.getContext('experimental-webgl');
function ensureExt(name) {
ok(gl.getExtension(name), 'Should have extension ' + name + '.');
}
function ensureNoExt(name) {
ok(!gl.getExtension(name), 'Should not have extension ' + name + '.');
}
do {
if (!gl)
break;
// These aren't all guaranteed, but they're common to all our test slaves.
// If you're adding a slave config that is missing one of these, comment the line out
// and split it into its own test.
// Implemented. (commented out if not test-slave-universal)
//ensureExt('ANGLE_instanced_arrays');
//ensureExt('EXT_blend_minmax');
//ensureExt('EXT_color_buffer_half_float');
//ensureExt('EXT_frag_depth');
//ensureExt('EXT_shader_texture_lod');
//ensureExt('EXT_sRGB');
//ensureExt('EXT_texture_filter_anisotropic');
ensureExt('OES_element_index_uint');
//ensureExt('OES_standard_derivatives');
ensureExt('OES_texture_float');
ensureExt('OES_texture_float_linear');
ensureExt('OES_texture_half_float');
ensureExt('OES_texture_half_float_linear');
ensureExt('OES_vertex_array_object');
//ensureExt('WEBGL_color_buffer_float');
//ensureExt('WEBGL_compressed_texture_atc');
//ensureExt('WEBGL_compressed_texture_es3');
//ensureExt('WEBGL_compressed_texture_etc1');
//ensureExt('WEBGL_compressed_texture_pvrtc');
//ensureExt('WEBGL_compressed_texture_s3tc');
//ensureExt('WEBGL_depth_texture');
//ensureExt('WEBGL_draw_buffers');
ensureExt('WEBGL_lose_context');
// Draft extensions, which should not be exposed by default.
ensureNoExt('EXT_disjoint_timer_query');
ensureNoExt('WEBGL_compressed_texture_es3');
// Not implemented.
ensureNoExt('EXT_color_buffer_float');
ensureNoExt('OES_fbo_render_mipmap');
ensureNoExt('WEBGL_compressed_texture_astc');
ensureNoExt('WEBGL_security_sensitive_resources');
ensureNoExt('WEBGL_shared_resources');
// Privileged
//ensureExt('WEBGL_debug_renderer_info');
//ensureExt('WEBGL_debug_shaders');
} while (false);
</script>
</body>
</html>

View File

@ -28,7 +28,8 @@ def ReadLocalFile(include):
return data
kSimpleTestReplacement = '''\n
kSimpleTestReplacement = '''
<script>
// SimpleTest.js replacement
@ -52,10 +53,12 @@ function todo(val, text) {
SimpleTest = {
waitForExplicitFinish: function() {},
finish: function() {},
requestFlakyTimeout: function() {},
};
</script>
<div id='mochi-to-testcase-output'></div>
\n'''
'''
fin = open(mochiPath, 'rb')
fout = open(testPath, 'wb')

View File

@ -10,7 +10,6 @@ support-files = devicestorage_common.js
[test_available.html]
[test_basic.html]
[test_dirs.html]
skip-if = e10s # Bug 1063569.
# [test_diskSpace.html]
# Possible race between the time we write a file, and the
# time it takes to be reflected by statfs(). Bug # 791287

View File

@ -1017,7 +1017,7 @@ HTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL,
do_QueryInterface(inst));
if (formSubmitObserver) {
rv = formSubmitObserver->Notify(this,
window->GetCurrentInnerWindow(),
window ? window->GetCurrentInnerWindow() : nullptr,
aActionURL,
aCancelSubmit);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -9,4 +9,4 @@ ImageMapPolyWrongNumberOfCoords=The "coords" attribute of the <area shape="poly"
ImageMapPolyOddNumberOfCoords=The "coords" attribute of the <area shape="poly"> tag is missing the last "y" coordinate (the correct format is "x1,y1,x2,y2 …").
TablePartRelPosWarning=Relative positioning of table rows and row groups is now supported. This site may need to be updated because it may depend on this feature having no effect.
ScrollLinkedEffectFound=This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developers.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!
ScrollLinkedEffectFound2=This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!

View File

@ -936,6 +936,7 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
mVideoTracks.mDemuxer = mInputDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
MOZ_ASSERT(mVideoTracks.mDemuxer);
info.mVideo = *mVideoTracks.mDemuxer->GetInfo()->GetAsVideoInfo();
info.mVideo.mTrackId = 2;
}
uint32_t numAudios = mInputDemuxer->GetNumberTracks(TrackInfo::kAudioTrack);
@ -944,6 +945,7 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
mAudioTracks.mDemuxer = mInputDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
MOZ_ASSERT(mAudioTracks.mDemuxer);
info.mAudio = *mAudioTracks.mDemuxer->GetInfo()->GetAsAudioInfo();
info.mAudio.mTrackId = 1;
}
int64_t videoDuration = numVideos ? info.mVideo.mDuration : 0;

View File

@ -31,14 +31,6 @@ const UNSUPPORTED_PERMISSIONS = [
'midi'
];
function setup() {
return new Promise((resolve, reject) => {
SpecialPowers.pushPrefEnv({'set': [
['dom.permissions.enabled', true],
]}, resolve);
});
}
function setPermissions(action) {
let permissions = PERMISSIONS.map(x => {
return { 'type': x.perm, 'allow': action, 'context': document };
@ -111,8 +103,7 @@ function testInvalidQuery() {
}
function runTests() {
setup()
.then(checkUnsupportedPermissions)
checkUnsupportedPermissions()
.then(checkUserVisiblePushPermission)
.then(() => setPermissions(UNKNOWN_ACTION))
.then(() => checkPermissions('prompt'))

View File

@ -1850,7 +1850,8 @@ nsPluginHost::GetSpecialType(const nsACString & aMIMEType)
}
if (aMIMEType.LowerCaseEqualsASCII("application/x-shockwave-flash") ||
aMIMEType.LowerCaseEqualsASCII("application/futuresplash")) {
aMIMEType.LowerCaseEqualsASCII("application/futuresplash") ||
aMIMEType.LowerCaseEqualsASCII("application/x-shockwave-flash-test")) {
return eSpecialType_Flash;
}

View File

@ -673,6 +673,7 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit)
, mNPPIface(nullptr)
, mPlugin(nullptr)
, mTaskFactory(this)
, mSandboxLevel(0)
, mIsFlashPlugin(false)
, mIsStartingAsync(false)
, mNPInitialized(false)
@ -736,7 +737,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath,
, mHangUIParent(nullptr)
, mHangUIEnabled(true)
, mIsTimerReset(true)
, mSandboxLevel(aSandboxLevel)
#ifdef MOZ_CRASHREPORTER
, mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex")
, mCrashReporter(nullptr)
@ -754,6 +754,7 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath,
{
NS_ASSERTION(mSubprocess, "Out of memory!");
sInstantiated = true;
mSandboxLevel = aSandboxLevel;
mRunID = GeckoChildProcessHost::GetUniqueID();
#ifdef MOZ_ENABLE_PROFILER_SPS
@ -2669,6 +2670,23 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
if (mIsFlashPlugin) {
parentInstance->InitMetadata(strPluginType, srcAttribute);
#ifdef XP_WIN
// Force windowless mode (bug 1201904) when sandbox level >= 2
if (mSandboxLevel >= 2) {
NS_NAMED_LITERAL_CSTRING(wmodeAttributeName, "wmode");
NS_NAMED_LITERAL_CSTRING(opaqueAttributeValue, "opaque");
auto wmodeAttributeIndex =
names.IndexOf(wmodeAttributeName, 0, comparator);
if (wmodeAttributeIndex != names.NoIndex) {
if (!values[wmodeAttributeIndex].EqualsLiteral("transparent")) {
values[wmodeAttributeIndex].Assign(opaqueAttributeValue);
}
} else {
names.AppendElement(wmodeAttributeName);
values.AppendElement(opaqueAttributeValue);
}
}
#endif
}
// Release the surrogate reference that was in pdata

View File

@ -325,6 +325,7 @@ protected:
TimeDuration mTimeBlocked;
nsCString mPluginName;
nsCString mPluginVersion;
int32_t mSandboxLevel;
bool mIsFlashPlugin;
#ifdef MOZ_X11
@ -548,7 +549,6 @@ private:
PluginHangUIParent *mHangUIParent;
bool mHangUIEnabled;
bool mIsTimerReset;
int32_t mSandboxLevel;
#ifdef MOZ_CRASHREPORTER
/**
* This mutex protects the crash reporter when the Plugin Hang UI event

View File

@ -120,6 +120,8 @@ skip-if = toolkit != "cocoa"
[test_twostreams.html]
[test_windowed_invalidate.html]
skip-if = os != "win"
[test_windowless_flash.html]
skip-if = !(os == "win" && processor == "x86_64")
[test_windowless_ime.html]
skip-if = os != "win" || e10s
[test_visibility.html]

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="runTests()">
<script type="application/javascript" src="plugin-utils.js"></script>
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
function runTests() {
var p1 = document.getElementById('plugin1');
var p2 = document.getElementById('plugin2');
var p3 = document.getElementById('plugin3');
is(p1.hasWidget(), false, "Flash is always windowless mode even if wmode=window");
is(p2.hasWidget(), false, "Flash is always windowless mode even if wmode=anything");
is(p3.hasWidget(), false, "Flash is always windowless mode even if no wmode");
SimpleTest.finish();
}
</script>
<p id="display"></p>
<div id="div1">
<embed id="plugin1" type="application/x-shockwave-flash-test" width="200" height="200" wmode="window"></embed>
<embed id="plugin2" type="application/x-shockwave-flash-test" width="200" height="200" wmode="test"></embed>
<embed id="plugin3" type="application/x-shockwave-flash-test" width="200" height="200"></embed>
</div>
</body>
</html>

View File

@ -564,9 +564,16 @@ DOMStorageCache::Clear(const DOMStorage* aStorage)
void
DOMStorageCache::CloneFrom(const DOMStorageCache* aThat)
{
mLoaded = aThat->mLoaded;
// This will never be called on anything else than SessionStorage.
// This means mData will never be touched on any other thread than
// the main thread and it never went through the loading process.
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mPersistent);
MOZ_ASSERT(!(bool)aThat->mLoaded);
mLoaded = false;
mInitialized = aThat->mInitialized;
mPersistent = aThat->mPersistent;
mPersistent = false;
mSessionOnlyDataSetActive = aThat->mSessionOnlyDataSetActive;
for (uint32_t i = 0; i < kDataSetCount; ++i) {

View File

@ -15,6 +15,7 @@
#include "nsHashKeys.h"
#include "mozilla/Monitor.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Atomics.h"
#include "nsAutoPtr.h"
namespace mozilla {
@ -220,8 +221,9 @@ private:
// Flag that is initially false. When the cache is about to work with
// the database (i.e. it is persistent) this flags is set to true after
// all keys and coresponding values are loaded from the database.
// This flag never goes from true back to false.
bool mLoaded;
// This flag never goes from true back to false. Since this flag is
// critical for mData hashtable synchronization, it's made atomic.
Atomic<bool, ReleaseAcquire> mLoaded;
// Result of load from the database. Valid after mLoaded flag has been set.
nsresult mLoadResult;

View File

@ -5,8 +5,11 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SystemProperty.h"
#include <dlfcn.h>
#include <dlfcn.h>
#include <string.h>
#include "nsDebug.h"
#include "prinit.h"
namespace mozilla {

View File

@ -48,13 +48,13 @@ public:
// Response codes from the 200, 400, and 500 series all indicated that
// the command has completed.
return (mResponseCode >= ResponseCode::CommandOkay)
&& (mResponseCode < ResponseCode::UnsolicitedInformational);
return (mResponseCode >= ::ResponseCode::CommandOkay)
&& (mResponseCode < ::ResponseCode::UnsolicitedInformational);
}
bool WasSuccessful() const
{
return mResponseCode == ResponseCode::CommandOkay;
return mResponseCode == ::ResponseCode::CommandOkay;
}
bool IsPending() const { return mPending; }
@ -79,7 +79,7 @@ private:
#else
mResponseStr = aResponseStr;
#endif
if (mResponseCode >= ResponseCode::CommandOkay) {
if (mResponseCode >= ::ResponseCode::CommandOkay) {
// This is a final response.
mPending = false;
}

View File

@ -100,7 +100,7 @@ interface NavigatorFeatures {
};
partial interface Navigator {
[Throws, Pref="dom.permissions.enabled"]
[Throws]
readonly attribute Permissions permissions;
};

View File

@ -13,8 +13,7 @@ enum PermissionState {
"prompt"
};
[Exposed=(Window),
Pref="dom.permissions.enabled"]
[Exposed=(Window)]
interface PermissionStatus : EventTarget {
readonly attribute PermissionState state;
attribute EventHandler onchange;

View File

@ -22,8 +22,7 @@ dictionary PushPermissionDescriptor : PermissionDescriptor {
boolean userVisible = false;
};
[Exposed=(Window),
Pref="dom.permissions.enabled"]
[Exposed=(Window)]
interface Permissions {
[Throws]
Promise<PermissionStatus> query(object permission);

View File

@ -1242,11 +1242,6 @@ public:
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
WhichServiceWorker::INSTALLING_WORKER | WhichServiceWorker::WAITING_WORKER);
// "If registration's waiting worker's skip waiting flag is set"
if (mRegistration->mWaitingWorker->SkipWaitingFlag()) {
mRegistration->PurgeActiveWorker();
}
Done(NS_OK);
// Activate() is invoked out of band of atomic.
mRegistration->TryToActivate();

View File

@ -1480,7 +1480,7 @@ nsEditor::JoinNodes(nsINode& aLeftNode, nsINode& aRightNode)
parent->AsDOMNode());
}
nsresult result;
nsresult result = NS_OK;
RefPtr<JoinNodeTxn> txn = CreateTxnForJoinNode(aLeftNode, aRightNode);
if (txn) {
result = DoTransaction(txn);

View File

@ -547,7 +547,7 @@ nsHTMLEditor::BeginningOfDocument()
// Find first editable thingy
bool done = false;
nsCOMPtr<nsINode> curNode = rootElement.get(), selNode;
int32_t curOffset = 0, selOffset;
int32_t curOffset = 0, selOffset = 0;
while (!done) {
nsWSRunObject wsObj(this, curNode, curOffset);
int32_t visOffset = 0;

View File

@ -2754,7 +2754,7 @@ nsTextServicesDocument::GetUncollapsedSelection(nsITextServicesDocument::TSDBloc
nsCOMPtr<nsIDOMNode> startParent, endParent;
int32_t startOffset, endOffset;
int32_t rangeCount, tableCount, i;
int32_t e1s1, e1s2, e2s1, e2s2;
int32_t e1s1 = 0, e1s2 = 0, e2s1 = 0, e2s2 = 0;
OffsetEntry *eStart, *eEnd;
int32_t eStartOffset, eEndOffset;

View File

@ -21,10 +21,10 @@ struct Sides final {
mBits = aSideBits;
}
bool IsEmpty() const { return mBits == 0; }
bool Top() const { return mBits & eSideBitsTop; }
bool Right() const { return mBits & eSideBitsRight; }
bool Bottom() const { return mBits & eSideBitsBottom; }
bool Left() const { return mBits & eSideBitsLeft; }
bool Top() const { return (mBits & eSideBitsTop) != 0; }
bool Right() const { return (mBits & eSideBitsRight) != 0; }
bool Bottom() const { return (mBits & eSideBitsBottom) != 0; }
bool Left() const { return (mBits & eSideBitsLeft) != 0; }
bool Contains(SideBits aSideBits) const
{
MOZ_ASSERT((aSideBits & ~eSideBitsAll) == 0, "illegal side bits");

View File

@ -298,8 +298,8 @@ public:
*/
bool HasNonIntegerTranslation() const {
return HasNonTranslation() ||
!FuzzyEqual(_31, floor(_31 + 0.5)) ||
!FuzzyEqual(_32, floor(_32 + 0.5));
!FuzzyEqual(_31, floor(_31 + Float(0.5))) ||
!FuzzyEqual(_32, floor(_32 + Float(0.5)));
}
/**

View File

@ -846,7 +846,8 @@ DrawBuffer::Create(GLContext* const gl,
DrawBuffer::~DrawBuffer()
{
mGL->MakeCurrent();
if (!mGL->MakeCurrent())
return;
GLuint fb = mFB;
GLuint rbs[] = {
@ -923,7 +924,8 @@ ReadBuffer::Create(GLContext* gl,
ReadBuffer::~ReadBuffer()
{
mGL->MakeCurrent();
if (!mGL->MakeCurrent())
return;
GLuint fb = mFB;
GLuint rbs[] = {

View File

@ -137,7 +137,7 @@ APZCTreeManager::UpdateHitTestingTree(CompositorParent* aCompositor,
{
APZThreadUtils::AssertOnCompositorThread();
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
// For testing purposes, we log some data to the APZTestData associated with
// the layers id that originated this update.
@ -1186,7 +1186,7 @@ void
APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
const Maybe<ZoomConstraints>& aConstraints)
{
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
RefPtr<HitTestingTreeNode> node = GetTargetNode(aGuid, nullptr);
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
@ -1245,7 +1245,7 @@ APZCTreeManager::FlushRepaintsToClearScreenToGeckoTransform()
// matched APZCs is the same. It is simplest to ensure that by flushing the
// pending repaint requests, which makes all of the untransforms empty (and
// therefore equal).
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
mTreeLock.AssertCurrentThreadOwns();
ForEachNode(mRootNode.get(),
@ -1270,7 +1270,7 @@ APZCTreeManager::CancelAnimation(const ScrollableLayerGuid &aGuid)
void
APZCTreeManager::AdjustScrollForSurfaceShift(const ScreenPoint& aShift)
{
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
RefPtr<AsyncPanZoomController> apzc = FindRootContentOrRootApzc();
if (apzc) {
apzc->AdjustScrollForSurfaceShift(aShift);
@ -1286,7 +1286,7 @@ APZCTreeManager::ClearTree()
APZThreadUtils::RunOnControllerThread(NewRunnableMethod(
mInputQueue.get(), &InputQueue::Clear));
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
// Collect the nodes into a list, and then destroy each one.
// We can't destroy them as we collect them, because ForEachNode()
@ -1308,7 +1308,7 @@ APZCTreeManager::ClearTree()
RefPtr<HitTestingTreeNode>
APZCTreeManager::GetRootNode() const
{
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
return mRootNode;
}
@ -1500,7 +1500,7 @@ APZCTreeManager::HitTestAPZC(const ScreenIntPoint& aPoint)
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTargetAPZC(const ScrollableLayerGuid& aGuid)
{
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
RefPtr<HitTestingTreeNode> node = GetTargetNode(aGuid, nullptr);
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
RefPtr<AsyncPanZoomController> apzc = node ? node->GetApzc() : nullptr;
@ -1519,7 +1519,7 @@ APZCTreeManager::GetTargetNode(const ScrollableLayerGuid& aGuid,
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint, HitTestResult* aOutHitResult)
{
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
HitTestResult hitResult = HitNothing;
ParentLayerPoint point = ViewAs<ParentLayerPixel>(aPoint,
PixelCastJustification::ScreenIsParentLayerForRoot);
@ -1552,7 +1552,7 @@ APZCTreeManager::BuildOverscrollHandoffChain(const RefPtr<AsyncPanZoomController
// order in which scroll will be handed off to them.
// Grab tree lock since we'll be walking the APZC tree.
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
// Build the chain. If there is a scroll parent link, we use that. This is
// needed to deal with scroll info layers, because they participate in handoff
@ -1655,7 +1655,7 @@ APZCTreeManager::FindTargetNode(HitTestingTreeNode* aNode,
RefPtr<HitTestingTreeNode>
APZCTreeManager::FindScrollNode(const AsyncDragMetrics& aDragMetrics)
{
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
return DepthFirstSearch(mRootNode.get(),
[&aDragMetrics](HitTestingTreeNode* aNode) {
@ -1877,7 +1877,7 @@ ScreenToParentLayerMatrix4x4
APZCTreeManager::GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const
{
Matrix4x4 result;
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment above. This function is called with aApzc at L, and the loop
@ -1918,7 +1918,7 @@ ParentLayerToScreenMatrix4x4
APZCTreeManager::GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const
{
Matrix4x4 result;
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment above. This function is called with aApzc at L, and the loop
@ -1947,7 +1947,7 @@ APZCTreeManager::GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) co
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const
{
MonitorAutoLock lock(mTreeLock);
MutexAutoLock lock(mTreeLock);
RefPtr<AsyncPanZoomController> apzc;
// For now, we only ever want to do pinching on the root-content APZC for
// a given layers id.

View File

@ -17,7 +17,7 @@
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/layers/APZUtils.h" // for HitTestResult
#include "mozilla/layers/TouchCounter.h"// for TouchCounter
#include "mozilla/Monitor.h" // for Monitor
#include "mozilla/Mutex.h" // for Mutex
#include "mozilla/TimeStamp.h" // for mozilla::TimeStamp
#include "mozilla/Vector.h" // for mozilla::Vector
#include "nsAutoPtr.h" // for nsRefPtr
@ -534,7 +534,7 @@ private:
* is considered part of the APZC tree management state.
* Finally, the lock needs to be held when accessing mZoomConstraints.
* IMPORTANT: See the note about lock ordering at the top of this file. */
mutable mozilla::Monitor mTreeLock;
mutable mozilla::Mutex mTreeLock;
RefPtr<HitTestingTreeNode> mRootNode;
/* Holds the zoom constraints for scrollable layers, as determined by the
* the main-thread gecko code. */

View File

@ -155,6 +155,14 @@ using mozilla::gfx::PointTyped;
* pixels would make us drop to low-res at y=490...990.\n
* This value is in layer pixels.
*
* \li\b apz.displayport_expiry_ms
* While a scrollable frame is scrolling async, we set a displayport on it
* to make sure it is layerized. However this takes up memory, so once the
* scrolling stops we want to remove the displayport. This pref controls how
* long after scrolling stops the displayport is removed. A value of 0 will
* disable the expiry behavior entirely.
* Units: milliseconds
*
* \li\b apz.enlarge_displayport_when_clipped
* Pref that enables enlarging of the displayport along one axis when the
* generated displayport's size is beyond that of the scrollable rect on the
@ -2887,6 +2895,7 @@ AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
aFrameMetrics.GetScrollOffset().x) < EPSILON &&
fabsf(mLastPaintRequestMetrics.GetScrollOffset().y -
aFrameMetrics.GetScrollOffset().y) < EPSILON &&
aFrameMetrics.GetPresShellResolution() == mLastPaintRequestMetrics.GetPresShellResolution() &&
aFrameMetrics.GetZoom() == mLastPaintRequestMetrics.GetZoom() &&
fabsf(aFrameMetrics.GetViewport().width -
mLastPaintRequestMetrics.GetViewport().width) < EPSILON &&
@ -3315,6 +3324,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
/ mFrameMetrics.GetCumulativeResolution();
float presShellResolutionChange = aLayerMetrics.GetPresShellResolution()
/ mFrameMetrics.GetPresShellResolution();
if (presShellResolutionChange != 1.0f) {
needContentRepaint = true;
}
mFrameMetrics.ZoomBy(totalResolutionChange / presShellResolutionChange);
} else {
// Take the new zoom as either device scale or composition width or

View File

@ -30,6 +30,13 @@
namespace mozilla {
namespace layers {
// When we compute the velocity we do so by taking two input events and
// dividing the distance delta over the time delta. In some cases the time
// delta can be really small, which can make the velocity computation very
// volatile. To avoid this we impose a minimum time delta below which we do
// not recompute the velocity.
const uint32_t MIN_VELOCITY_SAMPLE_TIME_MS = 5;
bool FuzzyEqualsCoordinate(float aValue1, float aValue2)
{
return FuzzyEqualsAdditive(aValue1, aValue2, COORDINATE_EPSILON)
@ -40,7 +47,8 @@ extern StaticAutoPtr<ComputedTimingFunction> gVelocityCurveFunction;
Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
: mPos(0),
mPosTimeMs(0),
mVelocitySampleTimeMs(0),
mVelocitySamplePos(0),
mVelocity(0.0f),
mAxisLocked(false),
mAsyncPanZoomController(aAsyncPanZoomController),
@ -67,16 +75,20 @@ void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, ParentLayerCoord
// mVelocityQueue is controller-thread only
APZThreadUtils::AssertOnControllerThread();
if (aTimestampMs == mPosTimeMs) {
// This could be a duplicate event, or it could be a legitimate event
// on some platforms that generate events really fast. As a compromise
// update mPos so we don't run into problems like bug 1042734, even though
// that means the velocity will be stale. Better than doing a divide-by-zero.
if (aTimestampMs <= mVelocitySampleTimeMs + MIN_VELOCITY_SAMPLE_TIME_MS) {
// See also the comment on MIN_VELOCITY_SAMPLE_TIME_MS.
// We still update mPos so that the positioning is correct (and we don't run
// into problems like bug 1042734) but the velocity will remain where it was.
// In particular we don't update either mVelocitySampleTimeMs or
// mVelocitySamplePos so that eventually when we do get an event with the
// required time delta we use the corresponding distance delta as well.
AXIS_LOG("%p|%s skipping velocity computation for small time delta %dms\n",
mAsyncPanZoomController, Name(), (aTimestampMs - mVelocitySampleTimeMs));
mPos = aPos;
return;
}
float newVelocity = mAxisLocked ? 0.0f : (float)(mPos - aPos + aAdditionalDelta) / (float)(aTimestampMs - mPosTimeMs);
float newVelocity = mAxisLocked ? 0.0f : (float)(mVelocitySamplePos - aPos + aAdditionalDelta) / (float)(aTimestampMs - mVelocitySampleTimeMs);
if (gfxPrefs::APZMaxVelocity() > 0.0f) {
bool velocityIsNegative = (newVelocity < 0);
newVelocity = fabs(newVelocity);
@ -107,7 +119,8 @@ void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, ParentLayerCoord
mAsyncPanZoomController, Name(), newVelocity);
mVelocity = newVelocity;
mPos = aPos;
mPosTimeMs = aTimestampMs;
mVelocitySampleTimeMs = aTimestampMs;
mVelocitySamplePos = aPos;
// Limit queue size pased on pref
mVelocityQueue.AppendElement(std::make_pair(aTimestampMs, mVelocity));
@ -119,7 +132,8 @@ void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, ParentLayerCoord
void Axis::StartTouch(ParentLayerCoord aPos, uint32_t aTimestampMs) {
mStartPos = aPos;
mPos = aPos;
mPosTimeMs = aTimestampMs;
mVelocitySampleTimeMs = aTimestampMs;
mVelocitySamplePos = aPos;
mAxisLocked = false;
}

View File

@ -251,7 +251,14 @@ public:
protected:
ParentLayerCoord mPos;
uint32_t mPosTimeMs;
// mVelocitySampleTimeMs and mVelocitySamplePos are the time and position
// used in the last velocity sampling. They get updated when a new sample is
// taken (which may not happen on every input event, if the time delta is too
// small).
uint32_t mVelocitySampleTimeMs;
ParentLayerCoord mVelocitySamplePos;
ParentLayerCoord mStartPos;
float mVelocity; // Units: ParentLayerCoords per millisecond
bool mAxisLocked; // Whether movement on this axis is locked.

View File

@ -3,7 +3,7 @@ body {
}
.inner-frame {
margin-top: 25%;
margin-top: 50px; /* this should be at least 30px */
height: 200%;
width: 75%;
overflow: scroll;

View File

@ -72,6 +72,8 @@ function scrollWheelOver(element) {
var gTestContinuation = null;
var utils;
const DISPLAYPORT_EXPIRY = 100;
// Return whether the element with id |elementId| has been layerized.
// Assumes |elementId| will be present in the content description for the
// element, and not in the content descriptions of other elements.
@ -91,6 +93,14 @@ function isLayerized(elementId) {
return false;
}
// Helper function to pass to waitForAllPaints rather than passing driveTest
// directly. If there are no paints pending waitForAllPaints will invoke the
// callback synchronously, and if we did waitForAllPaints(driveTest) that might
// cause reentrancy into driveTest which is bad.
function callDriveTestAsync() {
setTimeout(driveTest, 0);
}
function* runTest() {
utils = SpecialPowers.getDOMWindowUtils(window);
@ -126,6 +136,72 @@ function* runTest() {
yield scrollWheelOver(document.getElementById('outer4').contentDocument.getElementById('inner4'));
ok(isLayerized('inner4'), "scrolling 'inner4' should cause it to be layerized");
ok(isLayerized('outer4'), "scrolling 'inner4' should also cause 'outer4' to be layerized");
// Now we enable displayport expiry, and verify that things are still
// layerized as they were before.
yield SpecialPowers.pushPrefEnv({"set": [["apz.displayport_expiry_ms", DISPLAYPORT_EXPIRY]]}, driveTest);
ok(isLayerized('outer1'), "outer1 is still layerized after enabling expiry");
ok(!isLayerized('inner1'), "inner1 is still not layerized after enabling expiry");
ok(isLayerized('outer2'), "outer2 is still layerized after enabling expiry");
ok(isLayerized('inner2'), "inner2 is still layerized after enabling expiry");
ok(isLayerized('outer3'), "outer3 is still layerized after enabling expiry");
ok(!isLayerized('inner3'), "inner3 is still not layerized after enabling expiry");
ok(isLayerized('outer4'), "outer4 is still layerized after enabling expiry");
ok(isLayerized('inner4'), "inner4 is still layerized after enabling expiry");
// Now we trigger a scroll on some of the things still layerized, so that
// the displayport expiry gets triggered.
// Expire displayport with scrolling on outer1
yield scrollWheelOver(document.getElementById('outer1'));
yield waitForAllPaints(function() {
flushApzRepaints(driveTest);
});
yield setTimeout(driveTest, DISPLAYPORT_EXPIRY);
yield waitForAllPaints(callDriveTestAsync);
ok(!isLayerized('outer1'), "outer1 is no longer layerized after displayport expiry");
ok(!isLayerized('inner1'), "inner1 is still not layerized after displayport expiry");
// Expire displayport with scrolling on inner2
yield scrollWheelOver(document.getElementById('inner2'));
yield waitForAllPaints(function() {
flushApzRepaints(driveTest);
});
// Once the expiry elapses, it will trigger expiry on outer2, so we check
// both, one at a time.
yield setTimeout(driveTest, DISPLAYPORT_EXPIRY);
yield waitForAllPaints(callDriveTestAsync);
ok(!isLayerized('inner2'), "inner2 is no longer layerized after displayport expiry");
yield setTimeout(driveTest, DISPLAYPORT_EXPIRY);
yield waitForAllPaints(callDriveTestAsync);
ok(!isLayerized('outer2'), "outer2 got de-layerized with inner2");
// Scroll on inner3. inner3 isn't layerized, and this will cause it to
// get layerized, but it will also trigger displayport expiration for inner3
// which will eventually trigger displayport expiration on outer3.
yield scrollWheelOver(document.getElementById('outer3').contentDocument.getElementById('inner3'));
yield waitForAllPaints(function() {
flushApzRepaints(driveTest);
});
ok(isLayerized('inner3'), "inner3 becomes layerized after scroll");
yield setTimeout(driveTest, DISPLAYPORT_EXPIRY);
yield waitForAllPaints(callDriveTestAsync);
ok(!isLayerized('inner3'), "inner3 becomes unlayerized after expiry");
yield setTimeout(driveTest, DISPLAYPORT_EXPIRY);
yield waitForAllPaints(callDriveTestAsync);
ok(!isLayerized('outer3'), "outer3 is no longer layerized after inner3 triggered expiry");
// Scroll outer4 and wait for the expiry. It should NOT get expired because
// inner4 is still layerized
yield scrollWheelOver(document.getElementById('outer4').contentDocument.documentElement);
yield waitForAllPaints(function() {
flushApzRepaints(driveTest);
});
// Wait for the expiry to elapse
yield setTimeout(driveTest, DISPLAYPORT_EXPIRY);
yield waitForAllPaints(callDriveTestAsync);
ok(isLayerized('inner4'), "inner4 is still layerized because it never expired");
ok(isLayerized('outer4'), "outer4 is still layerized because inner4 is still layerized");
}
function driveTest() {
@ -153,7 +229,8 @@ function startTest() {
}
SimpleTest.waitForExplicitFinish();
SimpleTest.testInChaosMode();
SimpleTest.requestFlakyTimeout("we are testing code that measures an actual timeout");
SimpleTest.expectAssertions(0, 8); // we get a bunch of "ASSERTION: Bounds computation mismatch" sometimes (bug 1232856)
// Disable smooth scrolling, because it results in long-running scroll
// animations that can result in a 'scroll' event triggered by an earlier
@ -161,6 +238,7 @@ SimpleTest.testInChaosMode();
// Also enable APZ test logging, since we use that data to determine whether
// a scroll frame was layerized.
SpecialPowers.pushPrefEnv({"set": [["general.smoothScroll", false],
["apz.displayport_expiry_ms", 0],
["apz.test.logging_enabled", true]]},
function() {
SimpleTest.waitForFocus(startTest, window);

View File

@ -178,11 +178,12 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
#endif
RefPtr<TextureClient> texture = image->GetTextureClient(this);
const bool hasTextureClient = !!texture;
for (int32_t i = mBuffers.Length() - 1; i >= 0; --i) {
if (mBuffers[i].mImageSerial == image->GetSerial()) {
if (texture) {
MOZ_ASSERT(texture == mBuffers[i].mTextureClient);
if (hasTextureClient) {
MOZ_ASSERT(image->GetTextureClient(this) == mBuffers[i].mTextureClient);
} else {
texture = mBuffers[i].mTextureClient;
}

View File

@ -339,12 +339,14 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
NS_WARNING("No D3D device to update the texture.");
return false;
}
mSize = aSurface->GetSize();
uint32_t bpp = 0;
uint32_t bpp = BytesPerPixel(aSurface->GetFormat());
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
mSize = aSurface->GetSize();
mFormat = aSurface->GetFormat();
_D3DFORMAT format = D3DFMT_A8R8G8B8;
mFormat = aSurface->GetFormat();
switch (mFormat) {
case SurfaceFormat::B8G8R8X8:
format = D3DFMT_X8R8G8B8;
@ -364,18 +366,100 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
}
int32_t maxSize = mCompositor->GetMaxTextureSize();
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
if ((mSize.width <= maxSize && mSize.height <= maxSize) ||
(mFlags & TextureFlags::DISALLOW_BIGIMAGE)) {
mTexture = DataToTexture(deviceManager,
aSurface->GetData(), aSurface->Stride(),
IntSize(mSize), format, bpp);
(mFlags & TextureFlags::DISALLOW_BIGIMAGE)) {
mIsTiled = false;
if (mTexture) {
D3DSURFACE_DESC currentDesc;
mTexture->GetLevelDesc(0, &currentDesc);
// Make sure there's no size mismatch, if there is, recreate.
if (currentDesc.Width != mSize.width || currentDesc.Height != mSize.height ||
currentDesc.Format != format) {
mTexture = nullptr;
// Make sure we upload the whole surface.
aDestRegion = nullptr;
}
}
if (!mTexture) {
NS_WARNING("Could not upload texture");
// TODO Improve: Reallocating this texture is costly enough
// that it causes us to skip frames on scrolling
// important pages like Facebook.
mTexture = deviceManager->CreateTexture(mSize, format, D3DPOOL_DEFAULT, this);
mIsTiled = false;
if (!mTexture) {
Reset();
return false;
}
if (mFlags & TextureFlags::COMPONENT_ALPHA) {
aDestRegion = nullptr;
}
}
DataSourceSurface::MappedSurface map;
if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) {
gfxCriticalError() << "Failed to map surface.";
Reset();
return false;
}
mIsTiled = false;
nsIntRegion regionToUpdate = aDestRegion ? *aDestRegion : nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height));
RefPtr<IDirect3DTexture9> srcTexture;
RefPtr<IDirect3DSurface9> srcSurface;
if (mFormat == SurfaceFormat::A8) {
// A8 doesn't appear to work with CreateOffscreenPlainSurface
srcTexture = deviceManager->CreateTexture(mSize, format, D3DPOOL_SYSTEMMEM, this);
if (!srcTexture) {
aSurface->Unmap();
return false;
}
srcTexture->GetSurfaceLevel(0, getter_AddRefs(srcSurface));
} else {
HRESULT hr = mCompositor->device()->CreateOffscreenPlainSurface(mSize.width, mSize.height, format, D3DPOOL_SYSTEMMEM, getter_AddRefs(srcSurface), nullptr);
if (FAILED(hr)) {
aSurface->Unmap();
return false;
}
}
RefPtr<IDirect3DSurface9> destSurface;
mTexture->GetSurfaceLevel(0, getter_AddRefs(destSurface));
D3DLOCKED_RECT rect;
srcSurface->LockRect(&rect, nullptr, 0);
for (auto iter = regionToUpdate.RectIter(); !iter.Done(); iter.Next()) {
const nsIntRect& iterRect = iter.Get();
uint8_t* src = map.mData + map.mStride * iterRect.y + BytesPerPixel(aSurface->GetFormat()) * iterRect.x;
uint8_t* dest = reinterpret_cast<uint8_t*>(rect.pBits) + rect.Pitch * iterRect.y + BytesPerPixel(aSurface->GetFormat()) * iterRect.x;
for (int y = 0; y < iterRect.height; y++) {
memcpy(dest + rect.Pitch * y,
src + map.mStride * y,
iterRect.width * bpp);
}
}
srcSurface->UnlockRect();
aSurface->Unmap();
for (auto iter = regionToUpdate.RectIter(); !iter.Done(); iter.Next()) {
const nsIntRect& iterRect = iter.Get();
RECT updateRect;
updateRect.left = iterRect.x;
updateRect.top = iterRect.y;
updateRect.right = iterRect.XMost();
updateRect.bottom = iterRect.YMost();
POINT point = { updateRect.left, updateRect.top };
mCompositor->device()->UpdateSurface(srcSurface, &updateRect, destSurface, &point);
}
} else {
mIsTiled = true;
uint32_t tileCount = GetRequiredTilesD3D9(mSize.width, maxSize) *

View File

@ -51,7 +51,8 @@ bool SkROLockPixelsPixelRef::onLockPixelsAreWritable() const {
///////////////////////////////////////////////////////////////////////////////
static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorType dstCT,
SkColorProfileType dstPT, const SkIRect* subset) {
SkAlphaType dstAT, SkColorProfileType dstPT,
const SkIRect* subset) {
if (nullptr == texture || kUnknown_SkColorType == dstCT) {
return nullptr;
}
@ -75,7 +76,7 @@ static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorTyp
srcRect = *subset;
}
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT);
desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, dstAT, dstPT);
GrTexture* dst = context->textureProvider()->createTexture(desc, false, nullptr, 0);
if (nullptr == dst) {
@ -88,8 +89,7 @@ static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorTyp
context->copySurface(dst->asRenderTarget(), texture, srcRect, SkIPoint::Make(0,0),
GrContext::kFlushWrites_PixelOp);
SkImageInfo info = SkImageInfo::Make(desc.fWidth, desc.fHeight, dstCT, kPremul_SkAlphaType,
dstPT);
SkImageInfo info = SkImageInfo::Make(desc.fWidth, desc.fHeight, dstCT, dstAT, dstPT);
SkGrPixelRef* pixelRef = new SkGrPixelRef(info, dst);
SkSafeUnref(dst);
return pixelRef;
@ -142,7 +142,8 @@ SkPixelRef* SkGrPixelRef::deepCopy(SkColorType dstCT, SkColorProfileType dstPT,
// a GrTexture owned elsewhere (e.g., SkGpuDevice), and cannot live
// independently of that texture. Texture-backed pixel refs, on the other
// hand, own their GrTextures, and are thus self-contained.
return copy_to_new_texture_pixelref(fSurface->asTexture(), dstCT, dstPT, subset);
return copy_to_new_texture_pixelref(fSurface->asTexture(), dstCT, this->info().alphaType(),
dstPT, subset);
}
static bool tryAllocBitmapPixels(SkBitmap* bitmap) {

View File

@ -52,29 +52,7 @@ nsFont::Init()
variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
}
nsFont::nsFont(const nsFont& aOther)
: fontlist(aOther.fontlist)
{
style = aOther.style;
systemFont = aOther.systemFont;
weight = aOther.weight;
stretch = aOther.stretch;
smoothing = aOther.smoothing;
size = aOther.size;
sizeAdjust = aOther.sizeAdjust;
kerning = aOther.kerning;
synthesis = aOther.synthesis;
fontFeatureSettings = aOther.fontFeatureSettings;
languageOverride = aOther.languageOverride;
variantAlternates = aOther.variantAlternates;
variantCaps = aOther.variantCaps;
variantEastAsian = aOther.variantEastAsian;
variantLigatures = aOther.variantLigatures;
variantNumeric = aOther.variantNumeric;
variantPosition = aOther.variantPosition;
alternateValues = aOther.alternateValues;
featureValueLookup = aOther.featureValueLookup;
}
nsFont::nsFont(const nsFont& aOther) = default;
nsFont::nsFont()
{
@ -111,30 +89,7 @@ bool nsFont::Equals(const nsFont& aOther) const
return false;
}
nsFont& nsFont::operator=(const nsFont& aOther)
{
fontlist = aOther.fontlist;
style = aOther.style;
systemFont = aOther.systemFont;
weight = aOther.weight;
stretch = aOther.stretch;
smoothing = aOther.smoothing;
size = aOther.size;
sizeAdjust = aOther.sizeAdjust;
kerning = aOther.kerning;
synthesis = aOther.synthesis;
fontFeatureSettings = aOther.fontFeatureSettings;
languageOverride = aOther.languageOverride;
variantAlternates = aOther.variantAlternates;
variantCaps = aOther.variantCaps;
variantEastAsian = aOther.variantEastAsian;
variantLigatures = aOther.variantLigatures;
variantNumeric = aOther.variantNumeric;
variantPosition = aOther.variantPosition;
alternateValues = aOther.alternateValues;
featureValueLookup = aOther.featureValueLookup;
return *this;
}
nsFont& nsFont::operator=(const nsFont& aOther) = default;
void
nsFont::CopyAlternates(const nsFont& aOther)

View File

@ -950,11 +950,6 @@ namespace {
result.mSize = result.mSizeContainingRect = kVeryLargeNegativeNumber;
return result;
}
SizePair& operator=(const SizePair& aOther) {
mSizeContainingRect = aOther.mSizeContainingRect;
mSize = aOther.mSize;
return *this;
}
bool operator<(const SizePair& aOther) const {
if (mSizeContainingRect < aOther.mSizeContainingRect)
return true;

View File

@ -148,6 +148,7 @@ private:
DECL_GFX_PREF(Live, "apz.content_response_timeout", APZContentResponseTimeout, int32_t, 300);
DECL_GFX_PREF(Live, "apz.danger_zone_x", APZDangerZoneX, int32_t, 50);
DECL_GFX_PREF(Live, "apz.danger_zone_y", APZDangerZoneY, int32_t, 100);
DECL_GFX_PREF(Live, "apz.displayport_expiry_ms", APZDisplayPortExpiryTime, uint32_t, 15000);
DECL_GFX_PREF(Live, "apz.drag.enabled", APZDragEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.enlarge_displayport_when_clipped", APZEnlargeDisplayPortWhenClipped, bool, false);
DECL_GFX_PREF(Live, "apz.fling_accel_base_mult", APZFlingAccelBaseMultiplier, float, 1.0f);

View File

@ -178,8 +178,15 @@ public:
: mUserFontEntry(aUserFontEntry) {}
virtual ots::TableAction GetTableAction(uint32_t aTag) override {
// preserve Graphite, color glyph and SVG tables
if (aTag == TRUETYPE_TAG('S', 'i', 'l', 'f') ||
// Preserve Graphite, color glyph and SVG tables
if (
#ifdef RELEASE_BUILD // For Beta/Release, also allow OT Layout tables through
// unchecked, and rely on harfbuzz to handle them safely.
aTag == TRUETYPE_TAG('G', 'D', 'E', 'F') ||
aTag == TRUETYPE_TAG('G', 'P', 'O', 'S') ||
aTag == TRUETYPE_TAG('G', 'S', 'U', 'B') ||
#endif
aTag == TRUETYPE_TAG('S', 'i', 'l', 'f') ||
aTag == TRUETYPE_TAG('S', 'i', 'l', 'l') ||
aTag == TRUETYPE_TAG('G', 'l', 'o', 'c') ||
aTag == TRUETYPE_TAG('G', 'l', 'a', 't') ||

View File

@ -2584,12 +2584,15 @@ SimdToExpr(SimdType type, SimdOperation op)
switch (type) {
case SimdType::Int32x4: {
ENUMERATE(I32x4, FORALL_INT32X4_ASMJS_OP, I32CASE)
break;
}
case SimdType::Float32x4: {
ENUMERATE(F32x4, FORALL_FLOAT32X4_ASMJS_OP, F32CASE)
break;
}
case SimdType::Bool32x4: {
ENUMERATE(B32x4, FORALL_BOOL_SIMD_OP, B32CASE)
break;
}
default: break;
}

View File

@ -288,7 +288,7 @@ EvalKernel(JSContext* cx, const CallArgs& args, EvalType evalType, AbstractFrame
if (maybeScript && maybeScript->scriptSource()->introducerFilename())
introducerFilename = maybeScript->scriptSource()->introducerFilename();
RootedObject enclosing(cx);
Rooted<StaticScope*> enclosing(cx);
if (evalType == DIRECT_EVAL)
enclosing = callerScript->innermostStaticScope(pc);
else
@ -374,7 +374,7 @@ js::DirectEvalStringFromIon(JSContext* cx,
if (maybeScript && maybeScript->scriptSource()->introducerFilename())
introducerFilename = maybeScript->scriptSource()->introducerFilename();
RootedObject enclosing(cx, callerScript->innermostStaticScope(pc));
Rooted<StaticScope*> enclosing(cx, callerScript->innermostStaticScope(pc));
Rooted<StaticEvalScope*> staticScope(cx, StaticEvalScope::create(cx, enclosing));
if (!staticScope)
return false;
@ -476,7 +476,8 @@ js::ExecuteInGlobalAndReturnScope(JSContext* cx, HandleObject global, HandleScri
// Unlike the non-syntactic scope chain API used by the subscript loader,
// this API creates a fresh block scope each time.
RootedObject enclosingStaticScope(cx, script->enclosingStaticScope());
Rooted<StaticNonSyntacticScope*> enclosingStaticScope(cx,
&script->enclosingStaticScope()->as<StaticNonSyntacticScope>());
scope = ClonedBlockObject::createNonSyntactic(cx, enclosingStaticScope, scope);
if (!scope)
return false;

View File

@ -573,7 +573,7 @@ ModuleObject::isInstance(HandleValue value)
}
/* static */ ModuleObject*
ModuleObject::create(ExclusiveContext* cx, HandleObject enclosingStaticScope)
ModuleObject::create(ExclusiveContext* cx, Handle<StaticScope*> enclosingStaticScope)
{
RootedObject proto(cx, cx->global()->getModulePrototype());
RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto));
@ -581,7 +581,11 @@ ModuleObject::create(ExclusiveContext* cx, HandleObject enclosingStaticScope)
return nullptr;
RootedModuleObject self(cx, &obj->as<ModuleObject>());
self->initReservedSlot(StaticScopeSlot, ObjectOrNullValue(enclosingStaticScope));
Rooted<StaticModuleScope*> scope(cx, StaticModuleScope::create(cx, self,
enclosingStaticScope));
if (!scope)
return nullptr;
self->initReservedSlot(StaticScopeSlot, ObjectOrNullValue(scope));
Zone* zone = cx->zone();
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(zone);
@ -729,10 +733,10 @@ ModuleObject::initialEnvironment() const
return getReservedSlot(InitialEnvironmentSlot).toObject().as<ModuleEnvironmentObject>();
}
JSObject*
ModuleObject::enclosingStaticScope() const
StaticModuleScope*
ModuleObject::staticScope() const
{
return getReservedSlot(StaticScopeSlot).toObjectOrNull();
return &getReservedSlot(StaticScopeSlot).toObject().as<StaticModuleScope>();
}
/* static */ void

View File

@ -21,6 +21,8 @@ namespace js {
class ModuleEnvironmentObject;
class ModuleObject;
class StaticScope;
class StaticModuleScope;
namespace frontend {
class ParseNode;
@ -225,7 +227,7 @@ class ModuleObject : public NativeObject
static bool isInstance(HandleValue value);
static ModuleObject* create(ExclusiveContext* cx, HandleObject enclosingStaticScope);
static ModuleObject* create(ExclusiveContext* cx, Handle<StaticScope*> enclosingStaticScope);
void init(HandleScript script);
void setInitialEnvironment(Handle<ModuleEnvironmentObject*> initialEnvironment);
void initImportExportData(HandleArrayObject requestedModules,
@ -235,7 +237,7 @@ class ModuleObject : public NativeObject
HandleArrayObject starExportEntries);
JSScript* script() const;
JSObject* enclosingStaticScope() const;
StaticModuleScope* staticScope() const;
ModuleEnvironmentObject& initialEnvironment() const;
ModuleEnvironmentObject* environment() const;
ModuleNamespaceObject* namespace_();

View File

@ -213,6 +213,8 @@ static const JSFunctionSpec SimdTypedObjectMethods[] = {
namespace js {
namespace jit {
static_assert(uint64_t(SimdOperation::Last) <= UINT16_MAX, "SimdOperation must fit in uint16_t");
// See also JitInfo_* in MCallOptimize.cpp. We provide a JSJitInfo for all the
// named functions here. The default JitInfo_SimdInt32x4 etc structs represent the
// SimdOperation::Constructor.

View File

@ -878,7 +878,11 @@ GetBooleanSimdType(SimdType t)
//
// C++ defines keywords and/or/xor/not, so prepend Fn_ to all named functions to
// avoid clashes.
enum class SimdOperation : uint8_t {
//
// Note: because of a gcc < v4.8's compiler bug, uint8_t can't be used as the
// storage class here. See bug 1243810. See also
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64037 .
enum class SimdOperation {
// The constructor call. No Fn_ prefix here.
Constructor,
@ -901,6 +905,8 @@ enum class SimdOperation : uint8_t {
Fn_fromUint32x4Bits,
Fn_fromFloat32x4Bits,
Fn_fromFloat64x2Bits,
Last = Fn_fromFloat64x2Bits
};
class SimdObject : public JSObject

View File

@ -3623,9 +3623,6 @@ AC_SUBST(MOZ_PKG_SPECIAL)
AC_SUBST(MOZILLA_OFFICIAL)
dnl win32 options
AC_SUBST(MOZ_BROWSE_INFO)
dnl Echo the CFLAGS to remove extra whitespace.
CFLAGS=`echo \
$_WARNINGS_CFLAGS \

View File

@ -536,3 +536,13 @@ other kinds of objects.
`TypeError`. Determine which global is designated by <i>global</i>
using the same rules as [`Debugger.prototype.addDebuggee`][add].
## Static methods of the Debugger Object
The functions described below are not called with a `this` value.
<code id="isCompilableUnit">isCompilableUnit(<i>source</i>)</code>
: Given a string of source code, designated by <i>source</i>, return false if
the string might become a valid JavaScript statement with the addition of
more lines. Otherwise return true. The intent is to support interactive
compilation - accumulate lines in a buffer until isCompilableUnit is true,
then pass it to the compiler.

View File

@ -72,7 +72,7 @@ class MOZ_STACK_CLASS BytecodeCompiler
bool canLazilyParse();
bool createParser();
bool createSourceAndParser();
bool createScript(HandleObject staticScope, bool savedCallerFun = false);
bool createScript(Handle<StaticScope*> staticScope, bool savedCallerFun = false);
bool createEmitter(SharedContext* sharedContext, HandleScript evalCaller = nullptr,
bool insideNonGlobalEval = false);
bool isEvalCompilationUnit();
@ -255,7 +255,7 @@ BytecodeCompiler::createSourceAndParser()
}
bool
BytecodeCompiler::createScript(HandleObject staticScope, bool savedCallerFun)
BytecodeCompiler::createScript(Handle<StaticScope*> staticScope, bool savedCallerFun)
{
script = JSScript::Create(cx, staticScope, savedCallerFun, options,
sourceObject, /* sourceStart = */ 0, sourceBuffer.length());
@ -284,11 +284,8 @@ BytecodeCompiler::isEvalCompilationUnit()
bool
BytecodeCompiler::isNonGlobalEvalCompilationUnit()
{
if (!isEvalCompilationUnit())
return false;
StaticEvalScope& eval = enclosingStaticScope->as<StaticEvalScope>();
JSObject* enclosing = eval.enclosingScopeForStaticScopeIter();
return !IsStaticGlobalLexicalScope(enclosing);
return isEvalCompilationUnit() &&
!IsStaticGlobalLexicalScope(enclosingStaticScope->enclosingScope());
}
bool
@ -562,7 +559,8 @@ BytecodeCompiler::compileScript(HandleObject scopeChain, HandleScript evalCaller
return script;
}
ModuleObject* BytecodeCompiler::compileModule()
ModuleObject*
BytecodeCompiler::compileModule()
{
if (!createSourceAndParser())
return nullptr;
@ -571,7 +569,8 @@ ModuleObject* BytecodeCompiler::compileModule()
if (!module)
return nullptr;
if (!createScript(module))
Rooted<StaticModuleScope*> moduleScope(cx, module->staticScope());
if (!createScript(moduleScope))
return nullptr;
module->init(script);
@ -651,7 +650,8 @@ BytecodeCompiler::compileFunctionBody(MutableHandleFunction fun,
if (fn->pn_funbox->function()->isInterpreted()) {
MOZ_ASSERT(fun == fn->pn_funbox->function());
if (!createScript(enclosingStaticScope))
Rooted<StaticScope*> scope(cx, fn->pn_funbox->staticScope());
if (!createScript(scope))
return false;
script->bindings = fn->pn_funbox->bindings;
@ -803,11 +803,12 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
if (!NameFunctions(cx, pn))
return false;
RootedObject enclosingScope(cx, lazy->enclosingScope());
Rooted<StaticScope*> staticScope(cx, pn->pn_funbox->staticScope());
MOZ_ASSERT(staticScope);
RootedScriptSource sourceObject(cx, lazy->sourceObject());
MOZ_ASSERT(sourceObject);
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
Rooted<JSScript*> script(cx, JSScript::Create(cx, staticScope, false, options,
sourceObject, lazy->begin(), lazy->end()));
if (!script)
return false;

View File

@ -733,7 +733,7 @@ BytecodeEmitter::pushLoopStatement(LoopStmtInfo* stmt, StmtType type, ptrdiff_t
}
}
JSObject*
StaticScope*
BytecodeEmitter::innermostStaticScope() const
{
if (StmtInfoBCE* stmt = innermostScopeStmt())
@ -1362,9 +1362,7 @@ BytecodeEmitter::atBodyLevel(StmtInfoBCE* stmt) const
if (sc->staticScope()->is<StaticEvalScope>()) {
bool bl = !stmt->enclosing;
MOZ_ASSERT_IF(bl, stmt->type == StmtType::BLOCK);
MOZ_ASSERT_IF(bl, stmt->staticScope
->as<StaticBlockScope>()
.enclosingStaticScope() == sc->staticScope());
MOZ_ASSERT_IF(bl, stmt->staticScope->enclosingScope() == sc->staticScope());
return bl;
}
return !stmt;
@ -1467,8 +1465,8 @@ BytecodeEmitter::computeDefinitionIsAliased(BytecodeEmitter* bceOfDef, Definitio
// object. Aliased block bindings do not need adjusting; see
// computeAliasedSlots.
uint32_t slot = dn->pn_scopecoord.slot();
if (blockScopeOfDef(dn)->is<JSFunction>() ||
blockScopeOfDef(dn)->is<ModuleObject>())
if (blockScopeOfDef(dn)->is<StaticFunctionScope>() ||
blockScopeOfDef(dn)->is<StaticModuleScope>())
{
MOZ_ASSERT(IsArgOp(*op) || slot < bceOfDef->script->bindings.numBodyLevelLocals());
MOZ_ALWAYS_TRUE(bceOfDef->lookupAliasedName(bceOfDef->script, dn->name(), &slot));
@ -1569,8 +1567,11 @@ BytecodeEmitter::tryConvertFreeName(ParseNode* pn)
// Look up for name in function and block scopes.
if (ssi.type() == StaticScopeIter<NoGC>::Function) {
RootedScript funScript(cx, ssi.funScript());
if (funScript->funHasExtensibleScope() || ssi.fun().atom() == pn->pn_atom)
if (funScript->funHasExtensibleScope() ||
ssi.fun().function().atom() == pn->pn_atom)
{
return false;
}
// Skip the current function, since we're trying to convert a
// free name.
@ -1582,7 +1583,7 @@ BytecodeEmitter::tryConvertFreeName(ParseNode* pn)
}
}
} else if (ssi.type() == StaticScopeIter<NoGC>::Module) {
RootedScript moduleScript(cx, ssi.moduleScript());
RootedScript moduleScript(cx, ssi.module().script());
uint32_t slot_;
if (lookupAliasedName(moduleScript, name, &slot_, pn)) {
slot = Some(slot_);
@ -1590,7 +1591,8 @@ BytecodeEmitter::tryConvertFreeName(ParseNode* pn)
}
// Convert module import accesses to use JSOP_GETIMPORT.
RootedModuleEnvironmentObject env(cx, &ssi.module().initialEnvironment());
RootedModuleEnvironmentObject env(cx, &ssi.module().moduleObject()
.initialEnvironment());
RootedPropertyName propName(cx, name);
MOZ_ASSERT(env);
if (env->hasImportBinding(propName)) {
@ -1833,12 +1835,11 @@ BytecodeEmitter::bindNameToSlotHelper(ParseNode* pn)
* Currently, the ALIASEDVAR ops do not support accessing the
* callee of a DeclEnvObject, so use NAME.
*/
JSFunction* fun = sc->asFunctionBox()->function();
if (blockScopeOfDef(dn) != fun)
if (blockScopeOfDef(dn) != sc->asFunctionBox()->staticScope())
return true;
MOZ_ASSERT(fun->isLambda());
MOZ_ASSERT(pn->pn_atom == fun->atom());
MOZ_ASSERT(sc->asFunctionBox()->function()->isLambda());
MOZ_ASSERT(pn->pn_atom == sc->asFunctionBox()->function()->atom());
/*
* Leave pn->isOp(JSOP_GETNAME) if this->fun needs a CallObject to
@ -3538,9 +3539,9 @@ BytecodeEmitter::emitSetThis(ParseNode* pn)
}
static bool
IsModuleOnScopeChain(JSObject* obj)
IsModuleOnScopeChain(StaticScope* scope)
{
for (StaticScopeIter<NoGC> ssi(obj); !ssi.done(); ssi++) {
for (StaticScopeIter<NoGC> ssi(scope); !ssi.done(); ssi++) {
if (ssi.type() == StaticScopeIter<NoGC>::Module)
return true;
}
@ -6390,14 +6391,21 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
SharedContext* outersc = sc;
if (fun->isInterpretedLazy()) {
if (!fun->lazyScript()->sourceObject()) {
JSObject* scope = innermostStaticScope();
// Two cases that can arise during parsing can cause the static
// scope chain to be incorrectly linked up: (1) the
// transformation of blocks from non-scopeful to scopeful when
// the first block-scoped declaration is found; (2) legacy
// comprehension expression transplantation. The
// setEnclosingScope call below fixes these cases.
Rooted<StaticScope*> enclosingScope(cx, innermostStaticScope());
fun->lazyScript()->staticScope()->setEnclosingScope(enclosingScope);
JSObject* source = script->sourceObject();
fun->lazyScript()->setParent(scope, &source->as<ScriptSourceObject>());
fun->lazyScript()->initSource(&source->as<ScriptSourceObject>());
}
if (emittingRunOnceLambda)
fun->lazyScript()->setTreatAsRunOnce();
} else {
if (outersc->isFunctionBox() && outersc->asFunctionBox()->mightAliasLocals())
funbox->setMightAliasLocals(); // inherit mightAliasLocals from parent
MOZ_ASSERT_IF(outersc->strict(), funbox->strictScript);
@ -6410,9 +6418,13 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
const TransitiveCompileOptions& transitiveOptions = parser->options();
CompileOptions options(cx, transitiveOptions);
Rooted<JSObject*> enclosingScope(cx, innermostStaticScope());
// See comment above regarding funScope->setEnclosingScope().
Rooted<StaticScope*> funScope(cx, funbox->staticScope());
Rooted<StaticScope*> enclosingScope(cx, innermostStaticScope());
funScope->setEnclosingScope(enclosingScope);
Rooted<JSObject*> sourceObject(cx, script->sourceObject());
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
Rooted<JSScript*> script(cx, JSScript::Create(cx, funScope, false, options,
sourceObject,
funbox->bufStart, funbox->bufEnd));
if (!script)
@ -6426,8 +6438,6 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
insideNonGlobalEval, lineNum, emitterMode);
if (!bce2.init())
return false;
/* We measured the max scope depth when we parsed the function. */
if (!bce2.emitFunctionScript(pn->pn_body))
return false;

View File

@ -249,9 +249,9 @@ struct BytecodeEmitter
StmtInfoBCE* innermostStmt() const { return stmtStack.innermost(); }
StmtInfoBCE* innermostScopeStmt() const { return stmtStack.innermostScopeStmt(); }
JSObject* innermostStaticScope() const;
JSObject* blockScopeOfDef(Definition* dn) const {
return parser->blockScopes[dn->pn_blockid];
StaticScope* innermostStaticScope() const;
StaticScope* blockScopeOfDef(Definition* dn) const {
return &parser->blockScopes[dn->pn_blockid].get()->as<StaticScope>();
}
bool atBodyLevel(StmtInfoBCE* stmt) const;

View File

@ -1193,8 +1193,8 @@ FunctionBox::trace(JSTracer* trc)
{
ObjectBox::trace(trc);
bindings.trace(trc);
if (enclosingStaticScope_)
TraceRoot(trc, &enclosingStaticScope_, "funbox-enclosingStaticScope");
if (staticScope_)
TraceRoot(trc, &staticScope_, "funbox-staticScope");
}
void

View File

@ -57,9 +57,9 @@ JSFunction::AutoParseUsingFunctionBox::AutoParseUsingFunctionBox(ExclusiveContex
{
fun_->unsetEnvironment();
fun_->setFunctionBox(funbox);
funbox->computeAllowSyntax(fun_);
funbox->computeInWith(fun_);
funbox->computeThisBinding(fun_);
funbox->computeAllowSyntax(funbox->staticScope_);
funbox->computeInWith(funbox->staticScope_);
funbox->computeThisBinding(funbox->staticScope_);
}
JSFunction::AutoParseUsingFunctionBox::~AutoParseUsingFunctionBox()
@ -119,18 +119,18 @@ MarkUsesAsHoistedLexical(ParseNode* pn)
}
void
SharedContext::computeAllowSyntax(JSObject* staticScope)
SharedContext::computeAllowSyntax(StaticScope* staticScope)
{
for (StaticScopeIter<CanGC> it(context, staticScope); !it.done(); it++) {
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().isArrow()) {
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().function().isArrow()) {
// Any function supports new.target.
allowNewTarget_ = true;
allowSuperProperty_ = it.fun().allowSuperProperty();
allowSuperProperty_ = it.fun().function().allowSuperProperty();
if (it.maybeFunctionBox()) {
superScopeAlreadyNeedsHomeObject_ = it.maybeFunctionBox()->needsHomeObject();
allowSuperCall_ = it.maybeFunctionBox()->isDerivedClassConstructor();
} else {
allowSuperCall_ = it.fun().isDerivedClassConstructor();
allowSuperCall_ = it.fun().function().isDerivedClassConstructor();
}
break;
}
@ -138,7 +138,7 @@ SharedContext::computeAllowSyntax(JSObject* staticScope)
}
void
SharedContext::computeThisBinding(JSObject* staticScope)
SharedContext::computeThisBinding(StaticScope* staticScope)
{
for (StaticScopeIter<CanGC> it(context, staticScope); !it.done(); it++) {
if (it.type() == StaticScopeIter<CanGC>::Module) {
@ -147,9 +147,10 @@ SharedContext::computeThisBinding(JSObject* staticScope)
}
if (it.type() == StaticScopeIter<CanGC>::Function) {
RootedFunction fun(context, &it.fun().function());
// Arrow functions and generator expression lambdas don't have
// their own `this` binding.
if (it.fun().isArrow())
if (fun->isArrow())
continue;
bool isDerived;
if (it.maybeFunctionBox()) {
@ -157,9 +158,9 @@ SharedContext::computeThisBinding(JSObject* staticScope)
continue;
isDerived = it.maybeFunctionBox()->isDerivedClassConstructor();
} else {
if (it.fun().nonLazyScript()->isGeneratorExp())
if (fun->nonLazyScript()->isGeneratorExp())
continue;
isDerived = it.fun().isDerivedClassConstructor();
isDerived = fun->isDerivedClassConstructor();
}
// Derived class constructors (including nested arrow functions and
@ -176,7 +177,7 @@ SharedContext::computeThisBinding(JSObject* staticScope)
}
void
SharedContext::computeInWith(JSObject* staticScope)
SharedContext::computeInWith(StaticScope* staticScope)
{
for (StaticScopeIter<CanGC> it(context, staticScope); !it.done(); it++) {
if (it.type() == StaticScopeIter<CanGC>::With) {
@ -195,8 +196,8 @@ SharedContext::markSuperScopeNeedsHomeObject()
return;
for (StaticScopeIter<CanGC> it(context, staticScope()); !it.done(); it++) {
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().isArrow()) {
MOZ_ASSERT(it.fun().allowSuperProperty());
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().function().isArrow()) {
MOZ_ASSERT(it.fun().function().allowSuperProperty());
// If we are still emitting the outer function that needs a home
// object, mark it as needing one. Otherwise, we must be emitting
// an eval script, and the outer function must already be marked
@ -204,7 +205,7 @@ SharedContext::markSuperScopeNeedsHomeObject()
if (it.maybeFunctionBox())
it.maybeFunctionBox()->setNeedsHomeObject();
else
MOZ_ASSERT(it.fun().nonLazyScript()->needsHomeObject());
MOZ_ASSERT(it.funScript()->needsHomeObject());
superScopeAlreadyNeedsHomeObject_ = true;
return;
}
@ -754,12 +755,12 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj)
template <typename ParseHandler>
FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* outerpc,
ParseContext<ParseHandler>* outerpc,
Directives directives, bool extraWarnings, GeneratorKind generatorKind)
: ObjectBox(fun, traceListHead),
SharedContext(cx, directives, extraWarnings),
bindings(),
enclosingStaticScope_(enclosingStaticScope),
staticScope_(nullptr),
bufStart(0),
bufEnd(0),
startLine(1),
@ -782,13 +783,21 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
MOZ_ASSERT(fun->isTenured());
}
bool
FunctionBox::initStaticScope(Handle<StaticScope*> enclosingScope)
{
RootedFunction fun(context, function());
staticScope_ = StaticFunctionScope::create(context, fun, enclosingScope);
return staticScope_ != nullptr;
}
template <typename ParseHandler>
FunctionBox*
Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
ParseContext<ParseHandler>* outerpc,
Directives inheritedDirectives,
GeneratorKind generatorKind,
JSObject* enclosingStaticScope)
Handle<StaticScope*> enclosingStaticScope)
{
MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
MOZ_ASSERT(fun);
@ -801,15 +810,17 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
* function.
*/
FunctionBox* funbox =
alloc.new_<FunctionBox>(context, traceListHead, fun, enclosingStaticScope, outerpc,
inheritedDirectives, options().extraWarningsOption,
generatorKind);
alloc.new_<FunctionBox>(context, traceListHead, fun, outerpc, inheritedDirectives,
options().extraWarningsOption, generatorKind);
if (!funbox) {
ReportOutOfMemory(context);
return nullptr;
}
traceListHead = funbox;
if (!funbox->initStaticScope(enclosingStaticScope))
return nullptr;
if (fn)
handler.setFunctionBox(fn, funbox);
@ -1158,7 +1169,7 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
GeneratorKind generatorKind,
Directives inheritedDirectives,
Directives* newDirectives,
HandleObject enclosingStaticScope)
Handle<StaticScope*> enclosingStaticScope)
{
MOZ_ASSERT(checkOptionsCalled);
@ -2844,7 +2855,9 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox* funbo
size_t numInnerFunctions = pc->innerFunctions.length();
RootedFunction fun(context, funbox->function());
LazyScript* lazy = LazyScript::CreateRaw(context, fun, numFreeVariables, numInnerFunctions,
Rooted<StaticFunctionScope*> funScope(context, funbox->staticScope());
LazyScript* lazy = LazyScript::CreateRaw(context, fun, funScope,
numFreeVariables, numInnerFunctions,
versionNumber(), funbox->bufStart, funbox->bufEnd,
funbox->startLine, funbox->startColumn);
if (!lazy)
@ -3047,7 +3060,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict
if (!tokenStream.peekTokenPos(&pn->pn_pos))
return null();
RootedObject enclosing(context, fun->lazyScript()->enclosingScope());
Rooted<StaticScope*> enclosing(context, fun->lazyScript()->enclosingScope());
Directives directives(/* strict = */ strict);
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, enclosing);
if (!funbox)
@ -6501,8 +6514,11 @@ template <>
ParseNode*
Parser<FullParseHandler>::withStatement(YieldHandling yieldHandling)
{
// test262/ch12/12.10/12.10-0-1.js fails if we try to parse with-statements
// in syntax-parse mode. See bug 892583.
// This is intentionally different from other abortIfSyntaxParser()
// bailouts: `with` statements rule out syntax-only parsing for the entire
// compilation unit. This `return null()` causes us to bail out all the way
// to BytecodeCompiler::compileScript(), which retries with syntax parsing
// disabled. See bug 892583.
if (handler.syntaxParser) {
handler.disableSyntaxParser();
abortedSyntaxParse = true;

View File

@ -290,7 +290,7 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
StmtInfoPC* innermostStmt() const { return stmtStack.innermost(); }
StmtInfoPC* innermostScopeStmt() const { return stmtStack.innermostScopeStmt(); }
StmtInfoPC* innermostNonLabelStmt() const { return stmtStack.innermostNonLabel(); }
JSObject* innermostStaticScope() const {
StaticScope* innermostStaticScope() const {
if (StmtInfoPC* stmt = innermostScopeStmt())
return stmt->staticScope;
return sc->staticScope();
@ -310,9 +310,7 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
if (sc->staticScope()->is<StaticEvalScope>()) {
bool bl = !stmt->enclosing;
MOZ_ASSERT_IF(bl, stmt->type == StmtType::BLOCK);
MOZ_ASSERT_IF(bl, stmt->staticScope
->template as<StaticBlockScope>()
.enclosingStaticScope() == sc->staticScope());
MOZ_ASSERT_IF(bl, stmt->staticScope->enclosingScope() == sc->staticScope());
return bl;
}
return !stmt;
@ -507,11 +505,11 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
ObjectBox* newObjectBox(JSObject* obj);
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
Directives directives, GeneratorKind generatorKind,
JSObject* enclosingStaticScope);
Handle<StaticScope*> enclosingStaticScope);
// Use when the funbox is the outermost.
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, Directives directives,
GeneratorKind generatorKind, HandleObject enclosingStaticScope)
GeneratorKind generatorKind, Handle<StaticScope*> enclosingStaticScope)
{
return newFunctionBox(fn, fun, nullptr, directives, generatorKind,
enclosingStaticScope);
@ -521,7 +519,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, ParseContext<ParseHandler>* outerpc,
Directives directives, GeneratorKind generatorKind)
{
RootedObject enclosing(context, outerpc->innermostStaticScope());
Rooted<StaticScope*> enclosing(context, outerpc->innermostStaticScope());
return newFunctionBox(fn, fun, outerpc, directives, generatorKind, enclosing);
}
@ -534,7 +532,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind,
HandleObject proto);
bool generateBlockId(JSObject* staticScope, uint32_t* blockIdOut) {
bool generateBlockId(StaticScope* staticScope, uint32_t* blockIdOut) {
if (blockScopes.length() == StmtInfoPC::BlockIdLimit) {
tokenStream.reportError(JSMSG_NEED_DIET, "program");
return false;
@ -600,7 +598,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
Node standaloneFunctionBody(HandleFunction fun, Handle<PropertyNameVector> formals,
GeneratorKind generatorKind,
Directives inheritedDirectives, Directives* newDirectives,
HandleObject enclosingStaticScope);
Handle<StaticScope*> enclosingStaticScope);
// Parse a function, given only its arguments and body. Used for lazily
// parsed functions.

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