Merge m-c to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-09-18 12:38:46 +02:00
commit 7460c5c410
222 changed files with 1742 additions and 3079 deletions

View File

@ -216,8 +216,11 @@
this.mDialog.close();
ok(!isAccessibleInCache(dlgDoc),
"The document accessible for '" + aURL + "' is in cache still!");
// close() is asynchronous.
SimpleTest.executeSoon(function() {
ok(!isAccessibleInCache(dlgDoc),
"The document accessible for '" + aURL + "' is in cache still!");
});
}
this.getID = function openDialogWnd_getID()

View File

@ -22,12 +22,6 @@
src="../browser.js"></script>
<script type="application/javascript">
if (navigator.platform.startsWith("Mac")) {
SimpleTest.expectAssertions(0, 1);
} else {
SimpleTest.expectAssertions(1);
}
function hasTabModalPrompts() {
try {
return SpecialPowers.getBoolPref("prompts.tab_modal.enabled");

View File

@ -5,6 +5,7 @@
const { defer } = require('../core/promise');
const events = require('../system/events');
const { setImmediate } = require('../timers');
const { open: openWindow, onFocus, getToplevelWindow,
isInteractive } = require('./utils');
@ -15,14 +16,18 @@ exports.open = open;
function close(window) {
// We shouldn't wait for unload, as it is dispatched
// before the window is actually closed.
// `domwindowclosed` is a better match.
// before the window is actually closed. 'domwindowclosed' isn't great either,
// because it's fired midway through window teardown (see bug 874502
// comment 15). We could go with xul-window-destroyed, but _that_ doesn't
// provide us with a subject by which to disambiguate notifications. So we
// end up just doing the dumb thing and round-tripping through the event loop
// with setImmediate.
let deferred = defer();
let toplevelWindow = getToplevelWindow(window);
events.on("domwindowclosed", function onclose({subject}) {
if (subject == toplevelWindow) {
events.off("domwindowclosed", onclose);
deferred.resolve(window);
setImmediate(function() deferred.resolve(window));
}
}, true);
window.close();

View File

@ -325,6 +325,11 @@ exports.testTrackWindows = function(assert, done) {
onActivate: function(window) {
let index = windows.indexOf(window);
// Guard against windows that have already been removed.
// See bug 874502 comment 32.
if (index == -1)
return;
assert.equal(actions.join(),
expects.slice(0, index*4).join(),
"expecting " + expects[index*4]);
@ -351,6 +356,11 @@ exports.testTrackWindows = function(assert, done) {
onDeactivate: function(window) {
let index = windows.indexOf(window);
// Guard against windows that have already been removed.
// See bug 874502 comment 32.
if (index == -1)
return;
assert.equal(actions.join(),
expects.slice(0, index*4 + 2).join(),
"expecting " + expects[index*4 + 2]);

View File

@ -3,7 +3,11 @@ var runs = [
is(tabbrowser.browsers.length, 2, "test_bug462673.html has opened a second tab");
is(tabbrowser.selectedTab, tab.nextSibling, "dependent tab is selected");
tabbrowser.removeTab(tab);
ok(win.closed, "Window is closed");
// Closing a tab will also close its parent chrome window, but async
executeSoon(function() {
ok(win.closed, "Window is closed");
testComplete(win);
});
},
function (win, tabbrowser, tab) {
var newTab = tabbrowser.addTab();
@ -17,6 +21,7 @@ var runs = [
is(tabbrowser.selectedBrowser, newBrowser, "Browser for remaining tab is selected");
is(tabbrowser.mTabBox.selectedPanel, newBrowser.parentNode.parentNode.parentNode.parentNode, "Panel for remaining tab is selected");
}
testComplete(win);
}
];
@ -25,6 +30,14 @@ function test() {
runOneTest();
}
function testComplete(win) {
win.close();
if (runs.length)
runOneTest();
else
finish();
}
function runOneTest() {
var win = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
@ -39,11 +52,6 @@ function runOneTest() {
executeSoon(function () {
runs.shift()(win, win.gBrowser, tab);
win.close();
if (runs.length)
runOneTest();
else
finish();
});
}, true);

View File

@ -235,6 +235,9 @@ function runTest() {
// check that the last dir store got cleared in a new PB window
pbWin.close();
// And give it time to close
executeSoon(moveAlong);
yield;
let pbWin = yield createWindow({private: true});
let pbDownloadLastDir = new DownloadLastDir(pbWin);

View File

@ -2596,6 +2596,13 @@ let SessionStoreInternal = {
tabbrowser.unpinTab(tabbrowser.tabs[t]);
}
// We need to keep track of the initially open tabs so that they
// can be moved to the end of the restored tabs.
let initialTabs = [];
if (!overwriteTabs && firstWindow) {
initialTabs = Array.slice(tabbrowser.tabs);
}
// make sure that the selected tab won't be closed in order to
// prevent unnecessary flickering
if (overwriteTabs && tabbrowser.selectedTab._tPos >= newTabCount)
@ -2607,10 +2614,6 @@ let SessionStoreInternal = {
tabs.push(t < openTabCount ?
tabbrowser.tabs[t] :
tabbrowser.addTab("about:blank", {skipAnimation: true}));
// when resuming at startup: add additionally requested pages to the end
if (!overwriteTabs && firstWindow) {
tabbrowser.moveTabTo(tabs[t], t);
}
if (winData.tabs[t].pinned)
tabbrowser.pinTab(tabs[t]);
@ -2624,6 +2627,14 @@ let SessionStoreInternal = {
}
}
if (!overwriteTabs && firstWindow) {
// Move the originally open tabs to the end
let endPosition = tabbrowser.tabs.length - 1;
for (let i = 0; i < initialTabs.length; i++) {
tabbrowser.moveTabTo(initialTabs[i], endPosition);
}
}
// if all tabs to be restored are hidden, make the first one visible
if (!numVisibleTabs && winData.tabs.length) {
winData.tabs[0].hidden = false;

View File

@ -39,48 +39,51 @@ function test() {
newWin.close();
is(ss.getClosedWindowCount(), 1,
"The closed window was added to Recently Closed Windows");
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.title == TEST_URL && JSON.stringify(data).indexOf(uniqueText) > -1,
"The closed window data was stored correctly");
// Now give it time to close
executeSoon(function() {
is(ss.getClosedWindowCount(), 1,
"The closed window was added to Recently Closed Windows");
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.title == TEST_URL && JSON.stringify(data).indexOf(uniqueText) > -1,
"The closed window data was stored correctly");
// reopen the closed window and ensure its integrity
let newWin2 = ss.undoCloseWindow(0);
// reopen the closed window and ensure its integrity
let newWin2 = ss.undoCloseWindow(0);
ok(newWin2 instanceof ChromeWindow,
"undoCloseWindow actually returned a window");
is(ss.getClosedWindowCount(), 0,
"The reopened window was removed from Recently Closed Windows");
ok(newWin2 instanceof ChromeWindow,
"undoCloseWindow actually returned a window");
is(ss.getClosedWindowCount(), 0,
"The reopened window was removed from Recently Closed Windows");
// SSTabRestored will fire more than once, so we need to make sure we count them
let restoredTabs = 0;
let expectedTabs = data.tabs.length;
newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
++restoredTabs;
info("Restored tab " + restoredTabs + "/" + expectedTabs);
if (restoredTabs < expectedTabs) {
return;
}
// SSTabRestored will fire more than once, so we need to make sure we count them
let restoredTabs = 0;
let expectedTabs = data.tabs.length;
newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
++restoredTabs;
info("Restored tab " + restoredTabs + "/" + expectedTabs);
if (restoredTabs < expectedTabs) {
return;
}
is(restoredTabs, expectedTabs, "correct number of tabs restored");
newWin2.removeEventListener("SSTabRestored", sstabrestoredListener, true);
is(restoredTabs, expectedTabs, "correct number of tabs restored");
newWin2.removeEventListener("SSTabRestored", sstabrestoredListener, true);
is(newWin2.gBrowser.tabs.length, 2,
"The window correctly restored 2 tabs");
is(newWin2.gBrowser.currentURI.spec, TEST_URL,
"The window correctly restored the URL");
is(newWin2.gBrowser.tabs.length, 2,
"The window correctly restored 2 tabs");
is(newWin2.gBrowser.currentURI.spec, TEST_URL,
"The window correctly restored the URL");
let [txt, chk] = newWin2.content.document.querySelectorAll("#txt, #chk");
ok(txt.value == uniqueText && chk.checked,
"The window correctly restored the form");
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
"The window correctly restored the data associated with it");
let [txt, chk] = newWin2.content.document.querySelectorAll("#txt, #chk");
ok(txt.value == uniqueText && chk.checked,
"The window correctly restored the form");
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
"The window correctly restored the data associated with it");
// clean up
newWin2.close();
finish();
}, true);
// clean up
newWin2.close();
finish();
}, true);
});
});
}, TEST_URL);
}

View File

@ -40,7 +40,10 @@ function test() {
provideWindow(function onTestURLLoaded(win) {
win.close();
openWindowRec(windowsToOpen, expectedResults, recCallback);
// Give it time to close
executeSoon(function() {
openWindowRec(windowsToOpen, expectedResults, recCallback);
});
}, url, settings);
}

View File

@ -68,9 +68,12 @@ function runNextTest() {
}
}
let currentTest = tests.shift();
info("prepping for " + currentTest.name);
waitForBrowserState(testState, currentTest);
// If we closed a window, give it time to close
executeSoon(function() {
let currentTest = tests.shift();
info("prepping for " + currentTest.name);
waitForBrowserState(testState, currentTest);
});
}
else {
ss.setBrowserState(stateBackup);
@ -319,15 +322,18 @@ function test_undoCloseWindow() {
waitForBrowserState(lameMultiWindowState, function() {
// Close the window which isn't window
newWindow.close();
reopenedWindow = ss.undoCloseWindow(0);
reopenedWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
reopenedWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
// Now give it time to close
executeSoon(function() {
reopenedWindow = ss.undoCloseWindow(0);
reopenedWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
reopenedWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady, false);
reopenedWindow.addEventListener("load", function() {
reopenedWindow.removeEventListener("load", arguments.callee, false);
reopenedWindow.addEventListener("load", function() {
reopenedWindow.removeEventListener("load", arguments.callee, false);
reopenedWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
}, false);
reopenedWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, false);
}, false);
});
});
let busyEventCount = 0,
@ -355,6 +361,7 @@ function test_undoCloseWindow() {
reopenedWindow.close();
runNextTest();
// Give it time to close
executeSoon(runNextTest);
}
}

View File

@ -343,15 +343,18 @@ function newWindowWithState(state, callback) {
whenDelayedStartupFinished(win, function () {
ss.setWindowState(win, JSON.stringify(state), true);
win.close();
win = ss.undoCloseWindow(0);
// Give it time to close
executeSoon(function() {
win = ss.undoCloseWindow(0);
whenWindowLoaded(win, function () {
whenWindowStateReady(win, function () {
afterAllTabsLoaded(check, win);
whenWindowLoaded(win, function () {
whenWindowStateReady(win, function () {
afterAllTabsLoaded(check, win);
});
});
});
whenDelayedStartupFinished(win, check);
whenDelayedStartupFinished(win, check);
});
});
}

View File

@ -327,11 +327,15 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
let name = representAddon(addon);
let message = "";
if (addon.userDisabled) {
message = gcli.lookupFormat("addonAlreadyDisabled", [name]);
} else {
// If the addon is not disabled or is set to "click to play" then
// disable it. Otherwise display the message "Add-on is already
// disabled."
if (!addon.userDisabled ||
addon.userDisabled === AddonManager.STATE_ASK_TO_ACTIVATE) {
addon.userDisabled = true;
message = gcli.lookupFormat("addonDisabled", [name]);
} else {
message = gcli.lookupFormat("addonAlreadyDisabled", [name]);
}
this.resolve(message);
}

View File

@ -80,7 +80,7 @@ function test() {
function testWhenBreakpointEnabledAndSecondSourceShown() {
return Task.spawn(function() {
yield ensureSourceIs(aPanel, "-02.js");
yield ensureSourceIs(aPanel, "-02.js", true);
yield verifyView({ disabled: false, visible: false });
executeSoon(() => aDebuggee.firstCall());
@ -95,7 +95,7 @@ function test() {
function testWhenBreakpointDisabledAndSecondSourceShown() {
return Task.spawn(function() {
yield ensureSourceIs(aPanel, "-02.js");
yield ensureSourceIs(aPanel, "-02.js", true);
yield verifyView({ disabled: true, visible: false });
executeSoon(() => aDebuggee.firstCall());

View File

@ -139,6 +139,14 @@ function testRemoveTab() {
let deferred = promise.defer();
gNewWindow.close();
// give it time to close
executeSoon(function() { continue_remove_tab(deferred) });
return deferred.promise;
}
function continue_remove_tab(deferred)
{
removeTab(gNewTab);
gClient.listTabs(aResponse => {
@ -153,8 +161,6 @@ function testRemoveTab() {
deferred.resolve();
});
return deferred.promise;
}
function closeConnection() {

View File

@ -67,10 +67,13 @@ function onFocus() {
window.removeEventListener("focus", onFocus, true);
// Check if toolbox window got focus.
toolbox._host._window.onfocus = () => {
let onToolboxFocusAgain = () => {
toolbox._host._window.removeEventListener("focus", onToolboxFocusAgain, false);
ok(true, "Toolbox window is the focused window after calling toolbox.raise()");
cleanup();
};
toolbox._host._window.addEventListener("focus", onToolboxFocusAgain, false);
// Now raise toolbox.
toolbox.raise();
}

File diff suppressed because it is too large Load Diff

View File

@ -341,14 +341,13 @@ function waitForEvent(aSubject, aEventName, aTimeoutMs, aTarget) {
eventDeferred.resolve(aEvent);
}
function cleanup() {
function cleanup(aEventOrError) {
// unhook listener in case of success or failure
aSubject.removeEventListener(aEventName, listener);
return aEventOrError;
}
eventDeferred.promise.then(cleanup, cleanup);
aSubject.addEventListener(aEventName, listener, false);
return eventDeferred.promise;
return eventDeferred.promise.then(cleanup, cleanup);
}
/**
@ -425,7 +424,7 @@ function waitForCondition(aCondition, aTimeoutMs, aIntervalMs) {
}
/**
* same as waitForCondition but with better test output.
* same as waitForCondition but with better test output.
*
* @param aCondition the callback that must return a truthy value
* @param aTestMsg test condition message printed when the test succeeds or

View File

@ -382,11 +382,6 @@ private:
// Returns null if a principal cannot be found; generally callers
// should error out at that point.
static nsIPrincipal* doGetObjectPrincipal(JS::Handle<JSObject*> obj);
#ifdef DEBUG
static nsIPrincipal*
old_doGetObjectPrincipal(JS::Handle<JSObject*> obj,
bool aAllowShortCircuit = true);
#endif
// Returns null if a principal cannot be found. Note that rv can be NS_OK
// when this happens -- this means that there was no JS running.
@ -409,7 +404,8 @@ private:
nsresult
LookupPolicy(nsIPrincipal* principal,
ClassInfoData& aClassData, jsid aProperty,
ClassInfoData& aClassData,
JS::Handle<jsid> aProperty,
uint32_t aAction,
ClassPolicy** aCachedClassPolicy,
SecurityLevel* result);

View File

@ -79,14 +79,14 @@ bool nsScriptSecurityManager::sStrictFileOriginPolicy = true;
// Lazily initialized. Use the getter below.
static jsid sEnabledID = JSID_VOID;
static jsid
static JS::HandleId
EnabledID()
{
if (sEnabledID != JSID_VOID)
return sEnabledID;
return JS::HandleId::fromMarkedLocation(&sEnabledID);
AutoSafeJSContext cx;
sEnabledID = INTERNED_STRING_TO_JSID(cx, JS_InternString(cx, "enabled"));
return sEnabledID;
return JS::HandleId::fromMarkedLocation(&sEnabledID);
}
bool
@ -984,7 +984,7 @@ nsScriptSecurityManager::CheckSameOriginDOMProp(nsIPrincipal* aSubject,
nsresult
nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal,
ClassInfoData& aClassData,
jsid aProperty,
JS::Handle<jsid> aProperty,
uint32_t aAction,
ClassPolicy** aCachedClassPolicy,
SecurityLevel* result)
@ -1957,118 +1957,9 @@ nsScriptSecurityManager::doGetObjectPrincipal(JS::Handle<JSObject*> aObj)
{
JSCompartment *compartment = js::GetObjectCompartment(aObj);
JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
nsIPrincipal *principal = nsJSPrincipals::get(principals);
// We leave the old code in for a little while to make sure that pulling
// object principals directly off the compartment always gives an equivalent
// result (from a security perspective).
#ifdef DEBUG
nsIPrincipal *old = old_doGetObjectPrincipal(aObj);
MOZ_ASSERT(NS_SUCCEEDED(CheckSameOriginPrincipal(principal, old)));
#endif
return principal;
return nsJSPrincipals::get(principals);
}
#ifdef DEBUG
// static
nsIPrincipal*
nsScriptSecurityManager::old_doGetObjectPrincipal(JS::Handle<JSObject*> aObj,
bool aAllowShortCircuit)
{
NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
nsIPrincipal* result = nullptr;
JSContext* cx = nsXPConnect::XPConnect()->GetCurrentJSContext();
JS::RootedObject obj(cx, aObj);
JS::RootedObject origObj(cx, obj);
// A common case seen in this code is that we enter this function
// with obj being a Function object, whose parent is a Call
// object. Neither of those have object principals, so we can skip
// those objects here before we enter the below loop. That way we
// avoid wasting time checking properties of their classes etc in
// the loop.
if (js::IsFunctionObject(obj)) {
obj = js::GetObjectParent(obj);
if (!obj)
return nullptr;
if (js::IsCallObject(obj)) {
obj = js::GetObjectParentMaybeScope(obj);
if (!obj)
return nullptr;
}
}
const js::Class *jsClass = js::GetObjectClass(obj);
do {
// Note: jsClass is set before this loop, and also at the
// *end* of this loop.
if (IS_WN_CLASS(jsClass)) {
result = nsXPConnect::XPConnect()->GetPrincipal(obj,
aAllowShortCircuit);
if (result) {
break;
}
} else {
nsISupports *priv;
if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
priv = (nsISupports *) js::GetObjectPrivate(obj);
} else {
priv = UnwrapDOMObjectToISupports(obj);
}
if (aAllowShortCircuit) {
nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
do_QueryInterface(priv);
NS_ASSERTION(!xpcWrapper ||
!strcmp(jsClass->name, "XPCNativeWrapper"),
"Uh, an nsIXPConnectWrappedNative with the "
"wrong JSClass or getObjectOps hooks!");
}
nsCOMPtr<nsIScriptObjectPrincipal> objPrin =
do_QueryInterface(priv);
if (objPrin) {
result = objPrin->GetPrincipal();
if (result) {
break;
}
}
}
obj = js::GetObjectParentMaybeScope(obj);
if (!obj)
break;
jsClass = js::GetObjectClass(obj);
} while (1);
if (aAllowShortCircuit) {
nsIPrincipal *principal = old_doGetObjectPrincipal(origObj, false);
// Because of inner window reuse, we can have objects with one principal
// living in a scope with a different (but same-origin) principal. So
// just check same-origin here.
NS_ASSERTION(NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)),
"Principal mismatch. Not good");
}
return result;
}
#endif /* DEBUG */
////////////////////////////////////////////////
// Methods implementing nsIXPCSecurityManager //
////////////////////////////////////////////////

View File

@ -11,8 +11,7 @@ import os
def get_build_entries(root_path):
""" Iterates through the root_path, creating a list for each file and
directory. Excludes any path starting with extensions or distribution
and paths ending with channel-prefs.js.
directory. Excludes any file paths ending with channel-prefs.js.
"""
rel_file_path_set = set()
rel_dir_path_set = set()
@ -21,18 +20,14 @@ def get_build_entries(root_path):
parent_dir_rel_path = root[len(root_path)+1:]
rel_path_file = os.path.join(parent_dir_rel_path, file_name)
rel_path_file = rel_path_file.replace("\\", "/")
if not (rel_path_file.startswith("distribution/") or
rel_path_file.startswith("extensions/") or
rel_path_file.endswith("channel-prefs.js")):
if not (rel_path_file.endswith("channel-prefs.js")):
rel_file_path_set.add(rel_path_file)
for dir_name in dirs:
parent_dir_rel_path = root[len(root_path)+1:]
rel_path_dir = os.path.join(parent_dir_rel_path, dir_name)
rel_path_dir = rel_path_dir.replace("\\", "/")+"/"
if not (rel_path_dir.startswith("distribution/") or
rel_path_dir.startswith("extensions/")):
rel_dir_path_set.add(rel_path_dir)
rel_dir_path_set.add(rel_path_dir)
rel_file_path_list = list(rel_file_path_set)
rel_file_path_list.sort(reverse=True)

View File

@ -2592,77 +2592,6 @@ fi
MOZ_CXX11
AC_LANG_CPLUSPLUS
dnl Check for usable char16_t (2 bytes, unsigned)
dnl (we might not need the unsignedness check anymore)
AC_CACHE_CHECK(for usable char16_t (2 bytes, unsigned),
ac_cv_have_usable_char16_t,
[AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(sizeof(char16_t) == 2);
CONFIGURE_STATIC_ASSERT(char16_t(-1) > char16_t(0));
CONFIGURE_STATIC_ASSERT(sizeof((u"hello")[0]) == 2);
CONFIGURE_STATIC_ASSERT(sizeof(u'a') == 2);
CONFIGURE_STATIC_ASSERT(u'\xFFFF' > u'\x0')],
ac_cv_have_usable_char16_t="yes",
ac_cv_have_usable_char16_t="no")])
if test "$ac_cv_have_usable_char16_t" = "yes"; then
AC_DEFINE(HAVE_CPP_CHAR16_T)
HAVE_CPP_CHAR16_T=1
elif test "$GNU_CXX"; then
CXXFLAGS="$_SAVE_CXXFLAGS"
fi
dnl Check for usable wchar_t (2 bytes, unsigned)
dnl (we really don't need the unsignedness check anymore)
dnl ========================================================
AC_CACHE_CHECK(for usable wchar_t (2 bytes, unsigned),
ac_cv_have_usable_wchar_v2,
[AC_TRY_COMPILE([#include <stddef.h>
$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(sizeof(wchar_t) == 2);
CONFIGURE_STATIC_ASSERT((wchar_t)-1 > (wchar_t) 0)],
ac_cv_have_usable_wchar_v2="yes",
ac_cv_have_usable_wchar_v2="no")])
if test "$ac_cv_have_usable_wchar_v2" = "yes"; then
AC_DEFINE(HAVE_CPP_2BYTE_WCHAR_T)
HAVE_CPP_2BYTE_WCHAR_T=1
elif test "$ac_cv_have_usable_char16_t" != "yes"; then
dnl This is really gcc-only
dnl Do this test using CXX only since some versions of gcc
dnl 2.95-2.97 have a signed wchar_t in c++ only and some versions
dnl only have short-wchar support for c++.
dnl Note that we assume that mac & win32 have short wchar (see nscore.h)
_SAVE_CXXFLAGS=$CXXFLAGS
CXXFLAGS="$CXXFLAGS -fshort-wchar"
AC_CACHE_CHECK(for compiler -fshort-wchar option,
ac_cv_have_usable_wchar_option_v2,
[AC_TRY_LINK([#include <stddef.h>
$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(sizeof(wchar_t) == 2);
CONFIGURE_STATIC_ASSERT((wchar_t)-1 > (wchar_t) 0)],
ac_cv_have_usable_wchar_option_v2="yes",
ac_cv_have_usable_wchar_option_v2="no")])
if test "$ac_cv_have_usable_wchar_option_v2" = "yes"; then
AC_DEFINE(HAVE_CPP_2BYTE_WCHAR_T)
HAVE_CPP_2BYTE_WCHAR_T=1
if test "$OS_TARGET" = Android; then
WCHAR_CFLAGS="-fshort-wchar -Wl,--no-wchar-size-warning"
CXXFLAGS="$CXXFLAGS -Wl,--no-wchar-size-warning"
CFLAGS="$CFLAGS -Wl,--no-wchar-size-warning"
DSO_LDOPTS="$DSO_LDOPTS -Wl,--no-wchar-size-warning"
else
WCHAR_CFLAGS="-fshort-wchar"
fi
else
CXXFLAGS=$_SAVE_CXXFLAGS
fi
fi
AC_LANG_C
dnl Check for .hidden assembler directive and visibility attribute.
@ -3155,7 +3084,7 @@ dnl Checks for library functions.
dnl ========================================================
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_CHECK_FUNCS(random strerror lchown fchmod snprintf memmove rint stat64 lstat64 truncate64 setbuf isatty)
AC_CHECK_FUNCS(random strerror lchown fchmod snprintf memmove stat64 lstat64 truncate64 setbuf isatty)
AC_CHECK_FUNCS(statvfs64 statvfs statfs64 statfs)
AC_CHECK_FUNCS(flockfile getpagesize)
AC_CHECK_FUNCS(localtime_r strtok_r)
@ -8895,9 +8824,7 @@ dnl ========================================================
dnl The following defines are used by xpcom
_NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES
CPP_THROW_NEW
HAVE_CPP_2BYTE_WCHAR_T
HAVE_CPP_AMBIGUITY_RESOLVING_USING
HAVE_CPP_CHAR16_T
HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR
HAVE_CPP_PARTIAL_SPECIALIZATION
HAVE_CPP_TROUBLE_COMPARING_TO_ZERO

View File

@ -6886,7 +6886,8 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
}
// Now convert the scale into device pixels per CSS pixel.
nsIWidget *widget = nsContentUtils::WidgetForDocument(this);
CSSToLayoutDeviceScale pixelRatio(widget ? widget->GetDefaultScale() : 1.0f);
CSSToLayoutDeviceScale pixelRatio = widget ? widget->GetDefaultScale()
: CSSToLayoutDeviceScale(1.0f);
CSSToScreenScale scaleFloat = mScaleFloat * pixelRatio;
CSSToScreenScale scaleMinFloat = mScaleMinFloat * pixelRatio;
CSSToScreenScale scaleMaxFloat = mScaleMaxFloat * pixelRatio;

View File

@ -55,7 +55,7 @@ public:
// Called by the decode thread to keep track of the number of bytes read
// from the resource.
virtual void NotifyBytesConsumed(int64_t aBytes) = 0;
virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) = 0;
// Increments the parsed and decoded frame counters by the passed in counts.
// Can be called on any thread.

View File

@ -77,7 +77,7 @@ BufferDecoder::GetResource() const
}
void
BufferDecoder::NotifyBytesConsumed(int64_t aBytes)
BufferDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
{
// ignore
}

View File

@ -40,7 +40,7 @@ public:
MediaResource* GetResource() const MOZ_FINAL MOZ_OVERRIDE;
void NotifyBytesConsumed(int64_t aBytes) MOZ_FINAL MOZ_OVERRIDE;
void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_FINAL MOZ_OVERRIDE;

View File

@ -1046,15 +1046,17 @@ void MediaDecoder::NotifyPrincipalChanged()
}
}
void MediaDecoder::NotifyBytesConsumed(int64_t aBytes)
void MediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
{
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
NS_ENSURE_TRUE_VOID(mDecoderStateMachine);
MOZ_ASSERT(OnStateMachineThread() || OnDecodeThread());
if (!mIgnoreProgressData) {
mDecoderPosition += aBytes;
if (mIgnoreProgressData) {
return;
}
if (aOffset >= mDecoderPosition) {
mPlaybackStatistics.AddBytes(aBytes);
}
mDecoderPosition = aOffset + aBytes;
}
void MediaDecoder::UpdateReadyStateForData()

View File

@ -478,9 +478,10 @@ public:
// changed. Called on main thread only.
virtual void NotifyPrincipalChanged();
// Called by the decode thread to keep track of the number of bytes read
// from the resource.
void NotifyBytesConsumed(int64_t aBytes) MOZ_FINAL MOZ_OVERRIDE;
// Called by the MediaResource to keep track of the number of bytes read
// from the resource. Called on the main by an event runner dispatched
// by the MediaResource read functions.
void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
int64_t GetEndMediaTime() const MOZ_FINAL MOZ_OVERRIDE;

View File

@ -803,7 +803,12 @@ nsresult ChannelMediaResource::Read(char* aBuffer,
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
return mCacheStream.Read(aBuffer, aCount, aBytes);
int64_t offset = mCacheStream.Tell();
nsresult rv = mCacheStream.Read(aBuffer, aCount, aBytes);
if (NS_SUCCEEDED(rv)) {
DispatchBytesConsumed(*aBytes, offset);
}
return rv;
}
nsresult ChannelMediaResource::ReadAt(int64_t aOffset,
@ -813,7 +818,11 @@ nsresult ChannelMediaResource::ReadAt(int64_t aOffset,
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
return mCacheStream.ReadAt(aOffset, aBuffer, aCount, aBytes);
nsresult rv = mCacheStream.ReadAt(aOffset, aBuffer, aCount, aBytes);
if (NS_SUCCEEDED(rv)) {
DispatchBytesConsumed(*aBytes, aOffset);
}
return rv;
}
nsresult ChannelMediaResource::Seek(int32_t aWhence, int64_t aOffset)
@ -1597,8 +1606,17 @@ nsresult FileMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32
nsresult FileMediaResource::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
{
MutexAutoLock lock(mLock);
return UnsafeRead(aBuffer, aCount, aBytes);
nsresult rv;
int64_t offset = 0;
{
MutexAutoLock lock(mLock);
mSeekable->Tell(&offset);
rv = UnsafeRead(aBuffer, aCount, aBytes);
}
if (NS_SUCCEEDED(rv)) {
DispatchBytesConsumed(*aBytes, offset);
}
return rv;
}
nsresult FileMediaResource::UnsafeRead(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
@ -1612,10 +1630,17 @@ nsresult FileMediaResource::ReadAt(int64_t aOffset, char* aBuffer,
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MutexAutoLock lock(mLock);
nsresult rv = UnsafeSeek(nsISeekableStream::NS_SEEK_SET, aOffset);
if (NS_FAILED(rv)) return rv;
return UnsafeRead(aBuffer, aCount, aBytes);
nsresult rv;
{
MutexAutoLock lock(mLock);
rv = UnsafeSeek(nsISeekableStream::NS_SEEK_SET, aOffset);
if (NS_FAILED(rv)) return rv;
rv = UnsafeRead(aBuffer, aCount, aBytes);
}
if (NS_SUCCEEDED(rv)) {
DispatchBytesConsumed(*aBytes, aOffset);
}
return rv;
}
nsresult FileMediaResource::Seek(int32_t aWhence, int64_t aOffset)
@ -1733,5 +1758,41 @@ void BaseMediaResource::ModifyLoadFlags(nsLoadFlags aFlags)
}
}
class DispatchBytesConsumedEvent : public nsRunnable {
public:
DispatchBytesConsumedEvent(MediaDecoder* aDecoder,
int64_t aNumBytes,
int64_t aOffset)
: mDecoder(aDecoder),
mNumBytes(aNumBytes),
mOffset(aOffset)
{
MOZ_COUNT_CTOR(DispatchBytesConsumedEvent);
}
~DispatchBytesConsumedEvent()
{
MOZ_COUNT_DTOR(DispatchBytesConsumedEvent);
}
NS_IMETHOD Run() {
mDecoder->NotifyBytesConsumed(mNumBytes, mOffset);
// Drop ref to decoder on main thread, just in case this reference
// ends up being the last owning reference somehow.
mDecoder = nullptr;
return NS_OK;
}
RefPtr<MediaDecoder> mDecoder;
int64_t mNumBytes;
int64_t mOffset;
};
void BaseMediaResource::DispatchBytesConsumed(int64_t aNumBytes, int64_t aOffset)
{
RefPtr<nsIRunnable> event(new DispatchBytesConsumedEvent(mDecoder, aNumBytes, aOffset));
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
}
} // namespace mozilla

View File

@ -429,6 +429,10 @@ protected:
// then the request is added back to the load group.
void ModifyLoadFlags(nsLoadFlags aFlags);
// Dispatches an event to call MediaDecoder::NotifyBytesConsumed(aNumBytes, aOffset)
// on the main thread. This is called automatically after every read.
void DispatchBytesConsumed(int64_t aNumBytes, int64_t aOffset);
// This is not an nsCOMPointer to prevent a circular reference
// between the decoder to the media stream object. The stream never
// outlives the lifetime of the decoder.

View File

@ -87,9 +87,8 @@ static void _AudioSampleCallback(void *aThis,
* Otherwise, put as much data as is left into |aData|, set |aNumBytes| to the
* amount of data we have left, and return false.
*
* This function also calls NotifyBytesConsumed() on the media resource and
* passes the read data on to the MP3 frame parser for stream duration
* estimation.
* This function also passes the read data on to the MP3 frame parser for
* stream duration estimation.
*/
nsresult
AppleMP3Reader::ReadAndNotify(uint32_t *aNumBytes, char *aData)
@ -112,8 +111,6 @@ AppleMP3Reader::ReadAndNotify(uint32_t *aNumBytes, char *aData)
}
} while(totalBytes < *aNumBytes && numBytes);
mDecoder->NotifyBytesConsumed(totalBytes);
// Pass the buffer to the MP3 frame parser to improve our duration estimate.
if (mMP3FrameParser.IsMP3()) {
mMP3FrameParser.Parse(aData, totalBytes, offset);

View File

@ -277,12 +277,6 @@ DirectShowReader::DecodeAudioData()
numFrames,
buffer.forget(),
mNumChannels));
uint32_t bytesConsumed = mSourceFilter->GetAndResetBytesConsumedCount();
if (bytesConsumed > 0) {
mDecoder->NotifyBytesConsumed(bytesConsumed);
}
return true;
}

View File

@ -69,8 +69,6 @@ GStreamerReader::GStreamerReader(AbstractMediaDecoder* aDecoder)
mAudioSinkBufferCount(0),
mGstThreadsMonitor("media.gst.threads"),
mReachedEos(false),
mByteOffset(0),
mLastReportedByteOffset(0),
fpsNum(0),
fpsDen(0)
{
@ -439,20 +437,10 @@ nsresult GStreamerReader::ResetDecode()
mVideoSinkBufferCount = 0;
mAudioSinkBufferCount = 0;
mReachedEos = false;
mLastReportedByteOffset = 0;
mByteOffset = 0;
return res;
}
void GStreamerReader::NotifyBytesConsumed()
{
NS_ASSERTION(mByteOffset >= mLastReportedByteOffset,
"current byte offset less than prev offset");
mDecoder->NotifyBytesConsumed(mByteOffset - mLastReportedByteOffset);
mLastReportedByteOffset = mByteOffset;
}
bool GStreamerReader::DecodeAudioData()
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
@ -488,7 +476,6 @@ bool GStreamerReader::DecodeAudioData()
}
}
NotifyBytesConsumed();
buffer = gst_app_sink_pull_buffer(mAudioAppSink);
mAudioSinkBufferCount--;
}
@ -552,7 +539,6 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
}
}
NotifyBytesConsumed();
mDecoder->NotifyDecodedFrames(0, 1);
buffer = gst_app_sink_pull_buffer(mVideoAppSink);
@ -679,12 +665,6 @@ nsresult GStreamerReader::GetBuffered(TimeRanges* aBuffered,
nsTArray<MediaByteRange> ranges;
resource->GetCachedRanges(ranges);
if (mDecoder->OnStateMachineThread())
/* Report the position from here while buffering as we can't report it from
* the gstreamer threads that are actually reading from the resource
*/
NotifyBytesConsumed();
if (resource->IsDataCachedToEndOfResource(0)) {
/* fast path for local or completely cached files */
gint64 duration = 0;
@ -738,7 +718,6 @@ void GStreamerReader::ReadAndPushData(guint aLength)
}
GST_BUFFER_SIZE(buffer) = bytesRead;
mByteOffset += bytesRead;
GstFlowReturn ret = gst_app_src_push_buffer(mSource, gst_buffer_ref(buffer));
if (ret != GST_FLOW_OK) {
@ -831,9 +810,7 @@ gboolean GStreamerReader::SeekData(GstAppSrc* aSrc, guint64 aOffset)
rv = resource->Seek(SEEK_SET, aOffset);
}
if (NS_SUCCEEDED(rv)) {
mByteOffset = mLastReportedByteOffset = aOffset;
} else {
if (NS_FAILED(rv)) {
LOG(PR_LOG_ERROR, ("seek at %lu failed", aOffset));
}

View File

@ -63,7 +63,6 @@ public:
private:
void ReadAndPushData(guint aLength);
void NotifyBytesConsumed();
int64_t QueryDuration();
/* Called once the pipeline is setup to check that the stream only contains
@ -160,10 +159,6 @@ private:
* DecodeAudioData and DecodeVideoFrame should not expect any more data
*/
bool mReachedEos;
/* offset we've reached reading from the source */
gint64 mByteOffset;
/* the last offset we reported with NotifyBytesConsumed */
gint64 mLastReportedByteOffset;
int fpsNum;
int fpsDen;
};

View File

@ -892,7 +892,6 @@ bool OggReader::ReadOggPage(ogg_page* aPage)
return false;
}
mDecoder->NotifyBytesConsumed(bytesRead);
// Update the synchronisation layer with the number
// of bytes written to the buffer
ret = ogg_sync_wrote(&mOggState, bytesRead);

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html class="reftest-wait">
<script>
var context = new window.OfflineAudioContext(1, 4096, 48000);
context.oncomplete = function(e) {
document.documentElement.removeAttribute("class");
};
var delay = context.createDelay();
delay.connect(context.destination);
delay.delayTime.value = 1.0;
var buffer = context.createBuffer(1, 2048, context.sampleRate);
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(delay);
source.start();
context.startRendering();
</script>

View File

@ -55,3 +55,4 @@ load 907986-1.html
load 907986-2.html
load 907986-3.html
load 907986-4.html
load 910171-1.html

View File

@ -309,7 +309,6 @@ WaveReader::ReadAll(char* aBuf, int64_t aSize, int64_t* aBytesRead)
if (read == 0) {
return false;
}
mDecoder->NotifyBytesConsumed(read);
got += read;
if (aBytesRead) {
*aBytesRead = got;

View File

@ -59,6 +59,8 @@ AudioContext::AudioContext(nsPIDOMWindow* aWindow,
aLength, aSampleRate))
, mNumberOfChannels(aNumberOfChannels)
, mIsOffline(aIsOffline)
, mIsStarted(!aIsOffline)
, mIsShutDown(false)
{
// Actually play audio
mDestination->Stream()->AddAudioOutput(&gWebAudioOutputKey);
@ -439,6 +441,20 @@ AudioContext::RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob)
mDecodeJobs.RemoveElement(aDecodeJob);
}
void
AudioContext::RegisterActiveNode(AudioNode* aNode)
{
if (!mIsShutDown) {
mActiveNodes.PutEntry(aNode);
}
}
void
AudioContext::UnregisterActiveNode(AudioNode* aNode)
{
mActiveNodes.RemoveEntry(aNode);
}
void
AudioContext::UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode)
{
@ -523,8 +539,15 @@ GetHashtableElements(nsTHashtable<nsPtrHashKey<T> >& aHashtable, nsTArray<T*>& a
void
AudioContext::Shutdown()
{
mIsShutDown = true;
Suspend();
// Release references to active nodes.
// Active AudioNodes don't unregister in destructors, at which point the
// Node is already unregistered.
mActiveNodes.Clear();
// Stop all audio buffer source nodes, to make sure that they release
// their self-references.
// We first gather an array of the nodes and then call Stop on each one,
@ -595,10 +618,15 @@ AudioContext::GetJSContext() const
}
void
AudioContext::StartRendering()
AudioContext::StartRendering(ErrorResult& aRv)
{
MOZ_ASSERT(mIsOffline, "This should only be called on OfflineAudioContext");
if (mIsStarted) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mIsStarted = true;
mDestination->StartRendering();
}

View File

@ -41,6 +41,7 @@ class AudioBuffer;
class AudioBufferSourceNode;
class AudioDestinationNode;
class AudioListener;
class AudioNode;
class BiquadFilterNode;
class ChannelMergerNode;
class ChannelSplitterNode;
@ -205,13 +206,27 @@ public:
const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback);
// OfflineAudioContext methods
void StartRendering();
void StartRendering(ErrorResult& aRv);
IMPL_EVENT_HANDLER(complete)
bool IsOffline() const { return mIsOffline; }
MediaStreamGraph* Graph() const;
MediaStream* DestinationStream() const;
// Nodes register here if they will produce sound even if they have silent
// or no input connections. The AudioContext will keep registered nodes
// alive until the context is collected. This takes care of "playing"
// references and "tail-time" references.
void RegisterActiveNode(AudioNode* aNode);
// Nodes unregister when they have finished producing sound for the
// foreseeable future.
// Do NOT call UnregisterActiveNode from an AudioNode destructor.
// If the destructor is called, then the Node has already been unregistered.
// The destructor may be called during hashtable enumeration, during which
// unregistering would not be safe.
void UnregisterActiveNode(AudioNode* aNode);
void UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode);
void UnregisterPannerNode(PannerNode* aNode);
void UnregisterOscillatorNode(OscillatorNode* aNode);
@ -239,6 +254,9 @@ private:
nsRefPtr<AudioListener> mListener;
MediaBufferDecoder mDecoder;
nsTArray<nsRefPtr<WebAudioDecodeJob> > mDecodeJobs;
// See RegisterActiveNode. These will keep the AudioContext alive while it
// is rendering and the window remains alive.
nsTHashtable<nsRefPtrHashKey<AudioNode> > mActiveNodes;
// Two hashsets containing all the PannerNodes and AudioBufferSourceNodes,
// to compute the doppler shift, and also to stop AudioBufferSourceNodes.
// These are all weak pointers.
@ -251,6 +269,8 @@ private:
// Number of channels passed in the OfflineAudioContext ctor.
uint32_t mNumberOfChannels;
bool mIsOffline;
bool mIsStarted;
bool mIsShutDown;
};
}

View File

@ -102,9 +102,9 @@ private:
* real-time processing and output of this AudioNode.
*
* We track the incoming and outgoing connections to other AudioNodes.
* Outgoing connections have strong ownership. Also, AudioNodes add self
* references if they produce sound on their output even when they have silent
* or no input.
* Outgoing connections have strong ownership. Also, AudioNodes that will
* produce sound on their output even when they have silent or no input ask
* the AudioContext to keep them alive until the context is finished.
*/
class AudioNode : public nsDOMEventTargetHelper,
public EnableWebAudioCheck
@ -213,6 +213,17 @@ public:
virtual void NotifyInputConnected() {}
// MarkActive() asks the context to keep the AudioNode alive until the
// context is finished. This takes care of "playing" references and
// "tail-time" references.
void MarkActive() { Context()->RegisterActiveNode(this); }
// Active nodes call MarkInactive() when they have finished producing sound
// for the foreseeable future.
// Do not call MarkInactive from a node destructor. If the destructor is
// called, then the node is already inactive.
// MarkInactive() may delete |this|.
void MarkInactive() { Context()->UnregisterActiveNode(this); }
private:
friend class AudioBufferSourceNode;
// This could possibly delete 'this'.

View File

@ -63,18 +63,15 @@ public:
}
bool AcceptPlayingRefRelease(int64_t aLastGraphUpdateIndexProcessed) const
{
// Reject any requests to release mPlayingRef if the request was issued
// Reject any requests to release the playing ref if the request was issued
// before the MediaStreamGraph was aware of the most-recently-added input
// connection.
return aLastGraphUpdateIndexProcessed >= mMediaStreamGraphUpdateIndexAtLastInputConnection;
}
private:
friend class PlayingRefChangeHandler<ConvolverNode>;
int64_t mMediaStreamGraphUpdateIndexAtLastInputConnection;
nsRefPtr<AudioBuffer> mBuffer;
SelfReference<ConvolverNode> mPlayingRef;
bool mNormalize;
};

View File

@ -39,7 +39,7 @@ public:
}
bool AcceptPlayingRefRelease(int64_t aLastGraphUpdateIndexProcessed) const
{
// Reject any requests to release mPlayingRef if the request was issued
// Reject any requests to release the playing ref if the request was issued
// before the MediaStreamGraph was aware of the most-recently-added input
// connection.
return aLastGraphUpdateIndexProcessed >= mMediaStreamGraphUpdateIndexAtLastInputConnection;
@ -48,12 +48,10 @@ public:
private:
static void SendDelayToStream(AudioNode* aNode);
friend class DelayNodeEngine;
friend class PlayingRefChangeHandler<DelayNode>;
private:
int64_t mMediaStreamGraphUpdateIndexAtLastInputConnection;
nsRefPtr<AudioParam> mDelay;
SelfReference<DelayNode> mPlayingRef;
};
}

View File

@ -38,10 +38,10 @@ public:
}
if (node) {
if (mChange == ADDREF) {
node->mPlayingRef.Take(node);
node->MarkActive();
} else if (mChange == RELEASE &&
node->AcceptPlayingRefRelease(mLastProcessedGraphUpdateIndex)) {
node->mPlayingRef.Drop(node);
node->MarkInactive();
}
}
return NS_OK;

View File

@ -98,6 +98,7 @@ public:
: mOutputQueue("SharedBuffers::outputQueue")
, mDelaySoFar(TRACK_TICKS_MAX)
, mSampleRate(aSampleRate)
, mLatency(0.0)
, mDroppingBuffers(false)
{
}

View File

@ -54,6 +54,10 @@ addLoadEvent(function() {
compareBuffers(e.renderedBuffer.getChannelData(0), buf.getChannelData(0));
compareBuffers(e.renderedBuffer.getChannelData(1), buf.getChannelData(1));
expectException(function() {
ctx.startRendering();
}, DOMException.INVALID_STATE_ERR);
SimpleTest.finish();
}, false);
});

View File

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test PannerNode directly above</title>
<title>Test ConvolverNode channel count</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
@ -12,7 +12,7 @@
const signalLength = 2048;
const responseLength = 1000;
const outputLength = 4096; // > signalLength + responseLength to work around bug 910171
const outputLength = 2048; // < signalLength + responseLength to test bug 910171
var gTest = {
length: outputLength,

View File

@ -74,7 +74,6 @@ static int webm_read(void *aBuffer, size_t aLength, void *aUserData)
eof = true;
break;
}
decoder->NotifyBytesConsumed(bytes);
aLength -= bytes;
p += bytes;
}

View File

@ -106,7 +106,6 @@ WMFByteStream::WMFByteStream(MediaResource* aResource,
mResource(aResource),
mReentrantMonitor("WMFByteStream.Data"),
mOffset(0),
mBytesConsumed(0),
mIsShutdown(false)
{
NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
@ -396,15 +395,6 @@ WMFByteStream::Close()
return S_OK;
}
uint32_t
WMFByteStream::GetAndResetBytesConsumedCount()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
uint32_t bytesConsumed = mBytesConsumed;
mBytesConsumed = 0;
return bytesConsumed;
}
STDMETHODIMP
WMFByteStream::EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead)
{
@ -428,10 +418,6 @@ WMFByteStream::EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead)
LOG("[%p] WMFByteStream::EndRead() offset=%lld *aBytesRead=%u mOffset=%lld status=0x%x hr=0x%x eof=%d",
this, requestState->mOffset, *aBytesRead, mOffset, aResult->GetStatus(), hr, IsEOS());
if (SUCCEEDED(aResult->GetStatus())) {
mBytesConsumed += requestState->mBytesRead;
}
return aResult->GetStatus();
}

View File

@ -112,10 +112,6 @@ public:
void ProcessReadRequest(IMFAsyncResult* aResult,
ReadRequest* aRequestState);
// Returns the number of bytes that have been consumed by the users of this
// class since the last time we called this, and resets the internal counter.
uint32_t GetAndResetBytesConsumedCount();
private:
// Locks the MediaResource and performs the read. The other read methods
@ -152,11 +148,6 @@ private:
// standard IMFAttributes class, which we store a reference to here.
RefPtr<IMFAttributes> mAttributes;
// Number of bytes that have been consumed by callers of the read functions
// on this object since the last time GetAndResetBytesConsumedCount() was
// called.
uint32_t mBytesConsumed;
// True if the resource has been shutdown, either because the WMFReader is
// shutting down, or because the underlying MediaResource has closed.
bool mIsShutdown;

View File

@ -763,8 +763,6 @@ WMFReader::DecodeAudioData()
timestamp, duration, currentLength);
#endif
NotifyBytesConsumed();
return true;
}
@ -993,20 +991,9 @@ WMFReader::DecodeVideoFrame(bool &aKeyframeSkip,
return false;
}
NotifyBytesConsumed();
return true;
}
void
WMFReader::NotifyBytesConsumed()
{
uint32_t bytesConsumed = mByteStream->GetAndResetBytesConsumedCount();
if (bytesConsumed > 0) {
mDecoder->NotifyBytesConsumed(bytesConsumed);
}
}
nsresult
WMFReader::Seek(int64_t aTargetUs,
int64_t aStartTime,

View File

@ -76,11 +76,6 @@ private:
// Attempt to initialize DXVA. Returns true on success.
bool InitializeDXVA();
// Notifies the MediaDecoder of the number of bytes we have consumed
// since last time we called this. We call this once per call to
// DecodeVideoFrame() and/or DecodeAudioData().
void NotifyBytesConsumed();
RefPtr<IMFSourceReader> mSourceReader;
RefPtr<WMFByteStream> mByteStream;
RefPtr<WMFSourceReaderCallback> mSourceReaderCallback;

View File

@ -5068,7 +5068,7 @@ NS_IMETHODIMP
nsDocShell::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
{
if (mParentWidget) {
*aScale = mParentWidget->GetDefaultScale();
*aScale = mParentWidget->GetDefaultScale().scale;
return NS_OK;
}

View File

@ -352,8 +352,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CSSRuleList, nsCSSRuleListSH,
ARRAY_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CSSGroupRuleRuleList, nsCSSRuleListSH,
ARRAY_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MediaList, nsMediaListSH,
ARRAY_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(StyleSheetList, nsStyleSheetListSH,
@ -1082,10 +1080,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSRuleList)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSGroupRuleRuleList, nsIDOMCSSRuleList)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSRuleList)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MediaList, nsIDOMMediaList)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMediaList)
DOM_CLASSINFO_MAP_END

View File

@ -19,7 +19,6 @@ DOMCI_CLASS(CSSImportRule)
DOMCI_CLASS(CSSMediaRule)
DOMCI_CLASS(CSSNameSpaceRule)
DOMCI_CLASS(CSSRuleList)
DOMCI_CLASS(CSSGroupRuleRuleList)
DOMCI_CLASS(MediaList)
DOMCI_CLASS(StyleSheetList)
DOMCI_CLASS(CSSStyleSheet)

View File

@ -7268,22 +7268,14 @@ nsGlobalWindow::FinalClose()
// broken addons. The chrome tests in toolkit/mozapps/downloads are a good
// testing ground.
//
// Here are some quirks that the test suite depends on:
//
// * When chrome code executes |win|.close(), that close happens immediately,
// along with the accompanying "domwindowclosed" notification. But _only_ if
// |win|'s JSContext is not at the top of the stack. If it is, the close
// _must not_ happen immediately.
//
// * If |win|'s JSContext is at the top of the stack, we must complete _two_
// round-trips to the event loop before the call to ReallyCloseWindow. This
// allows setTimeout handlers that are set after FinalClose() is called to
// run before the window is torn down.
// In particular, if |win|'s JSContext is at the top of the stack, we must
// complete _two_ round-trips to the event loop before the call to
// ReallyCloseWindow. This allows setTimeout handlers that are set after
// FinalClose() is called to run before the window is torn down.
bool indirect = GetContextInternal() && // Occasionally null. See bug 877390.
(nsContentUtils::GetCurrentJSContext() ==
GetContextInternal()->GetNativeContext());
if ((!indirect && nsContentUtils::IsCallerChrome()) ||
NS_FAILED(nsCloseEvent::PostCloseEvent(this, indirect))) {
if (NS_FAILED(nsCloseEvent::PostCloseEvent(this, indirect))) {
ReallyCloseWindow();
} else {
mHavePendingClose = true;

View File

@ -2121,8 +2121,8 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
}
NS_NAMED_MULTILINE_LITERAL_STRING(kFmt,
NS_LL("CC(T+%.1f) duration: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s\n")
NS_LL("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, sync: %lu ms, removed: %lu"));
MOZ_UTF16("CC(T+%.1f) duration: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s\n")
MOZ_UTF16("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, sync: %lu ms, removed: %lu"));
nsString msg;
msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC,
ccNowDuration, suspected,
@ -2146,28 +2146,28 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
if (sPostGCEventsToObserver) {
NS_NAMED_MULTILINE_LITERAL_STRING(kJSONFmt,
NS_LL("{ \"timestamp\": %llu, ")
NS_LL("\"duration\": %llu, ")
NS_LL("\"finish_gc_duration\": %llu, ")
NS_LL("\"sync_skippable_duration\": %llu, ")
NS_LL("\"suspected\": %lu, ")
NS_LL("\"visited\": { ")
NS_LL("\"RCed\": %lu, ")
NS_LL("\"GCed\": %lu }, ")
NS_LL("\"collected\": { ")
NS_LL("\"RCed\": %lu, ")
NS_LL("\"GCed\": %lu }, ")
NS_LL("\"waiting_for_gc\": %lu, ")
NS_LL("\"short_living_objects_waiting_for_gc\": %lu, ")
NS_LL("\"forced_gc\": %d, ")
NS_LL("\"forget_skippable\": { ")
NS_LL("\"times_before_cc\": %lu, ")
NS_LL("\"min\": %lu, ")
NS_LL("\"max\": %lu, ")
NS_LL("\"avg\": %lu, ")
NS_LL("\"total\": %lu, ")
NS_LL("\"removed\": %lu } ")
NS_LL("}"));
MOZ_UTF16("{ \"timestamp\": %llu, ")
MOZ_UTF16("\"duration\": %llu, ")
MOZ_UTF16("\"finish_gc_duration\": %llu, ")
MOZ_UTF16("\"sync_skippable_duration\": %llu, ")
MOZ_UTF16("\"suspected\": %lu, ")
MOZ_UTF16("\"visited\": { ")
MOZ_UTF16("\"RCed\": %lu, ")
MOZ_UTF16("\"GCed\": %lu }, ")
MOZ_UTF16("\"collected\": { ")
MOZ_UTF16("\"RCed\": %lu, ")
MOZ_UTF16("\"GCed\": %lu }, ")
MOZ_UTF16("\"waiting_for_gc\": %lu, ")
MOZ_UTF16("\"short_living_objects_waiting_for_gc\": %lu, ")
MOZ_UTF16("\"forced_gc\": %d, ")
MOZ_UTF16("\"forget_skippable\": { ")
MOZ_UTF16("\"times_before_cc\": %lu, ")
MOZ_UTF16("\"min\": %lu, ")
MOZ_UTF16("\"max\": %lu, ")
MOZ_UTF16("\"avg\": %lu, ")
MOZ_UTF16("\"total\": %lu, ")
MOZ_UTF16("\"removed\": %lu } ")
MOZ_UTF16("}"));
nsString json;
json.Adopt(nsTextFormatter::smprintf(kJSONFmt.get(), endCCTime,
ccNowDuration, gcDuration, skippableDuration,

View File

@ -67,7 +67,7 @@ interface nsIContentPref;
* See nsIContentPrefCallback2 below for more information about callbacks.
*/
[scriptable, uuid(133608c7-f812-41ca-bc1c-62a4eb95e52a)]
[scriptable, uuid(86279644-6b86-4875-a228-2d2ff2f3e33b)]
interface nsIContentPrefService2 : nsISupports
{
/**
@ -153,7 +153,7 @@ interface nsIContentPrefService2 : nsISupports
void getCachedBySubdomainAndName(in AString domain,
in AString name,
in nsILoadContext context,
out unsigned long len,
[optional] out unsigned long len,
[retval,array,size_is(len)] out nsIContentPref prefs);
/**

View File

@ -425,7 +425,7 @@ TabChild::Observe(nsISupports *aSubject,
mLastMetrics.mViewport = CSSRect(CSSPoint(), kDefaultViewportSize);
mLastMetrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
mLastMetrics.mZoom = mLastMetrics.CalculateIntrinsicScale();
mLastMetrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(mWidget->GetDefaultScale());
mLastMetrics.mDevPixelsPerCSSPixel = mWidget->GetDefaultScale();
// We use ScreenToLayerScale(1) below in order to turn the
// async zoom amount into the gecko zoom amount.
mLastMetrics.mCumulativeResolution =

View File

@ -1146,9 +1146,9 @@ TabParent::RecvGetDefaultScale(double* aValue)
{
TryCacheDPIAndScale();
NS_ABORT_IF_FALSE(mDefaultScale > 0,
NS_ABORT_IF_FALSE(mDefaultScale.scale > 0,
"Must not ask for scale before OwnerElement is received!");
*aValue = mDefaultScale;
*aValue = mDefaultScale.scale;
return true;
}

View File

@ -309,7 +309,7 @@ protected:
nsIntSize mDimensions;
ScreenOrientation mOrientation;
float mDPI;
double mDefaultScale;
CSSToLayoutDeviceScale mDefaultScale;
bool mShown;
bool mUpdatedDimensions;

View File

@ -290,6 +290,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
mNumCachedParams = 0;
mCachedAttrParamNames = nullptr;
mCachedAttrParamValues = nullptr;
mLastMouseDownButtonType = -1;
#ifdef XP_MACOSX
#ifndef NP_NO_CARBON
@ -1860,8 +1861,9 @@ nsPluginInstanceOwner::ProcessMouseDown(nsIDOMEvent* aMouseEvent)
}
nsEvent* event = aMouseEvent->GetInternalNSEvent();
if (event && event->eventStructType == NS_MOUSE_EVENT) {
nsEventStatus rv = ProcessEvent(*static_cast<nsGUIEvent*>(event));
if (event && event->eventStructType == NS_MOUSE_EVENT) {
mLastMouseDownButtonType = static_cast<nsMouseEvent*>(event)->button;
nsEventStatus rv = ProcessEvent(*static_cast<nsGUIEvent*>(event));
if (nsEventStatus_eConsumeNoDefault == rv) {
return aMouseEvent->PreventDefault(); // consume event
}
@ -1888,6 +1890,9 @@ nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent)
aMouseEvent->PreventDefault();
aMouseEvent->StopPropagation();
}
if (event->message == NS_MOUSE_BUTTON_UP) {
mLastMouseDownButtonType = -1;
}
}
return NS_OK;
}
@ -1911,11 +1916,15 @@ nsPluginInstanceOwner::HandleEvent(nsIDOMEvent* aEvent)
return ProcessMouseDown(aEvent);
}
if (eventType.EqualsLiteral("mouseup")) {
// Don't send a mouse-up event to the plugin if it isn't focused. This can
// happen if the previous mouse-down was sent to a DOM element above the
// plugin, the mouse is still above the plugin, and the mouse-down event
// caused the element to disappear. See bug 627649.
if (!mContentFocused) {
// Don't send a mouse-up event to the plugin if its button type doesn't
// match that of the preceding mouse-down event (if any). This kind of
// mismatch can happen if the previous mouse-down event was sent to a DOM
// element above the plugin, the mouse is still above the plugin, and the
// mouse-down event caused the element to disappear. See bug 627649 and
// bug 909678.
nsMouseEvent *event =
static_cast<nsMouseEvent*>(aEvent->GetInternalNSEvent());
if (event && ((int) event->button != mLastMouseDownButtonType)) {
aEvent->PreventDefault();
return NS_OK;
}

View File

@ -320,6 +320,8 @@ private:
nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent);
nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent);
nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent);
int mLastMouseDownButtonType;
nsresult EnsureCachedAttrParamArrays();

View File

@ -134,7 +134,6 @@ var interfaceNamesInGlobalScope =
"CSSFontFaceRule",
{name: "CSSFontFeatureValuesRule", release: false},
"CSSGroupingRule",
"CSSGroupRuleRuleList",
"CSSImportRule",
"CSSMediaRule",
"CSSMozDocumentRule",

View File

@ -233,7 +233,9 @@ function doTest() {
privateWin.close();
testOnWindow(true, function(newPrivateWin) {
// The .close() call above will operate asynchronously, so execute the
// code below asynchronously as well.
function callback(newPrivateWin) {
is(newPrivateWin.content.localStorage.getItem("must disappear"), null, "private browsing values threw away");
is(newPrivateWin.content.localStorage.length, 0, "No items");
@ -245,7 +247,8 @@ function doTest() {
prefBranch.clearUserPref("browser.startup.page")
prefBranch.clearUserPref("browser.startup.homepage_override.mstone");
SimpleTest.finish();
});
};
SimpleTest.executeSoon(function() testOnWindow(true, callback));
});
});
}

View File

@ -1,4 +1,4 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
@ -16,6 +16,7 @@ callback OfflineRenderSuccessCallback = void (AudioBuffer renderedData);
PrefControlled]
interface OfflineAudioContext : AudioContext {
[Throws]
void startRendering();
attribute EventHandler oncomplete;

View File

@ -1244,7 +1244,7 @@ NS_IMETHODIMP nsWebBrowser::Destroy()
NS_IMETHODIMP nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
{
*aScale = mParentWidget ? mParentWidget->GetDefaultScale() : 1.0;
*aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
return NS_OK;
}

View File

@ -835,7 +835,8 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
"BeginUpdate should always modify the draw region in the same way!");
FillSurface(onBlack, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0));
FillSurface(onWhite, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0));
if (RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize())) {
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize());
RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize());
RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
result.mContext = new gfxContext(dt);
@ -861,7 +862,8 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
}
} else {
nsRefPtr<gfxASurface> surf = GetUpdateSurface(BUFFER_BLACK, result.mRegionToDraw);
if (RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize())) {
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
result.mContext = new gfxContext(dt);
} else {
result.mContext = new gfxContext(surf);

View File

@ -709,7 +709,7 @@ public:
// see bug 865908 about fixing this.
virtual void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator)
{
MOZ_ASSERT(!mBuffer, "Will leak the old mBuffer");
MOZ_ASSERT(!mBuffer || mBuffer == aBuffer, "Will leak the old mBuffer");
mBuffer = aBuffer;
mDeAllocator = aAllocator;
}

View File

@ -25,9 +25,9 @@
#include "../d3d9/Nv3DVUtils.h"
#include "gfxCrashReporterUtils.h"
#include "nsWindowsHelpers.h"
#ifdef MOZ_METRO
#include "DXGI1_2.h"
#include "nsWindowsHelpers.h"
#endif
using namespace std;
@ -640,17 +640,15 @@ LayerManagerD3D10::VerifyBufferSize()
}
mRTView = nullptr;
if (gfxWindowsPlatform::IsOptimus()) {
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
DXGI_FORMAT_B8G8R8A8_UNORM,
0);
#ifdef MOZ_METRO
} else if (IsRunningInWindowsMetro()) {
if (IsRunningInWindowsMetro()) {
mSwapChain->ResizeBuffers(2, rect.width, rect.height,
DXGI_FORMAT_B8G8R8A8_UNORM,
0);
mDisableSequenceForNextFrame = true;
#endif
} else if (gfxWindowsPlatform::IsOptimus()) {
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
DXGI_FORMAT_B8G8R8A8_UNORM,
0);
} else {
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
DXGI_FORMAT_B8G8R8A8_UNORM,

View File

@ -750,17 +750,15 @@ CompositorD3D11::VerifyBufferSize()
mDefaultRT = nullptr;
if (gfxWindowsPlatform::IsOptimus()) {
mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
DXGI_FORMAT_B8G8R8A8_UNORM,
0);
#ifdef MOZ_METRO
} else if (IsRunningInWindowsMetro()) {
if (IsRunningInWindowsMetro()) {
mSwapChain->ResizeBuffers(2, mSize.width, mSize.height,
DXGI_FORMAT_B8G8R8A8_UNORM,
0);
mDisableSequenceForNextFrame = true;
#endif
} else if (gfxWindowsPlatform::IsOptimus()) {
mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
DXGI_FORMAT_B8G8R8A8_UNORM,
0);
} else {
mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
DXGI_FORMAT_B8G8R8A8_UNORM,

View File

@ -353,7 +353,9 @@ nsDeviceContext::SetDPI()
dpi = 96.0f;
}
double devPixelsPerCSSPixel = mWidget ? mWidget->GetDefaultScale() : 1.0;
CSSToLayoutDeviceScale scale = mWidget ? mWidget->GetDefaultScale()
: CSSToLayoutDeviceScale(1.0);
double devPixelsPerCSSPixel = scale.scale;
mAppUnitsPerDevNotScaledPixel =
std::max(1, NS_lround(AppUnitsPerCSSPixel() / devPixelsPerCSSPixel));

View File

@ -8,9 +8,7 @@
#include "nsDeviceContext.h" // for nsDeviceContext
#include "nsStringGlue.h" // for nsAutoString, etc
#include "prtypes.h" // for PR_STATIC_ASSERT
#include "nsDebug.h" // for NS_WARNING
#include "nsMargin.h" // for nsMargin
#include <algorithm> // for min, max
// the mozilla::css::Side sequence must match the nsMargin nscoord sequence
PR_STATIC_ASSERT((NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3));
@ -41,89 +39,3 @@ FILE* operator<<(FILE* out, const nsRect& rect)
}
#endif // DEBUG
nsRect
nsRect::SaturatingUnionEdges(const nsRect& aRect) const
{
#ifdef NS_COORD_IS_FLOAT
return UnionEdges(aRect);
#else
nsRect result;
result.x = std::min(aRect.x, x);
int64_t w = std::max(int64_t(aRect.x) + aRect.width, int64_t(x) + width) - result.x;
if (MOZ_UNLIKELY(w > nscoord_MAX)) {
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord width");
// Clamp huge negative x to nscoord_MIN / 2 and try again.
result.x = std::max(result.x, nscoord_MIN / 2);
w = std::max(int64_t(aRect.x) + aRect.width, int64_t(x) + width) - result.x;
if (MOZ_UNLIKELY(w > nscoord_MAX)) {
w = nscoord_MAX;
}
}
result.width = nscoord(w);
result.y = std::min(aRect.y, y);
int64_t h = std::max(int64_t(aRect.y) + aRect.height, int64_t(y) + height) - result.y;
if (MOZ_UNLIKELY(h > nscoord_MAX)) {
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord height");
// Clamp huge negative y to nscoord_MIN / 2 and try again.
result.y = std::max(result.y, nscoord_MIN / 2);
h = std::max(int64_t(aRect.y) + aRect.height, int64_t(y) + height) - result.y;
if (MOZ_UNLIKELY(h > nscoord_MAX)) {
h = nscoord_MAX;
}
}
result.height = nscoord(h);
return result;
#endif
}
void
nsRect::SaturatingInflate(const nsMargin& aMargin)
{
#ifdef NS_COORD_IS_FLOAT
Inflate(aMargin);
#else
int64_t nx = int64_t(x) - aMargin.left;
int64_t w = int64_t(width) + int64_t(aMargin.left) + aMargin.right;
if (MOZ_UNLIKELY(w > nscoord_MAX)) {
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord width");
int64_t xdiff = nx - nscoord_MIN / 2;
if (xdiff < 0) {
// Clamp huge negative x to nscoord_MIN / 2 and try again.
nx = nscoord_MIN / 2;
w += xdiff;
}
if (MOZ_UNLIKELY(w > nscoord_MAX)) {
w = nscoord_MAX;
}
}
width = nscoord(w);
if (MOZ_UNLIKELY(nx < nscoord_MIN)) {
NS_WARNING("Underflowed nscoord_MIN in conversion to nscoord x");
nx = nscoord_MIN;
}
x = nscoord(nx);
int64_t ny = int64_t(y) - aMargin.top;
int64_t h = int64_t(height) + int64_t(aMargin.top) + aMargin.bottom;
if (MOZ_UNLIKELY(h > nscoord_MAX)) {
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord height");
int64_t ydiff = ny - nscoord_MIN / 2;
if (ydiff < 0) {
// Clamp huge negative y to nscoord_MIN / 2 and try again.
ny = nscoord_MIN / 2;
h += ydiff;
}
if (MOZ_UNLIKELY(h > nscoord_MAX)) {
h = nscoord_MAX;
}
}
height = nscoord(h);
if (MOZ_UNLIKELY(ny < nscoord_MIN)) {
NS_WARNING("Underflowed nscoord_MIN in conversion to nscoord y");
ny = nscoord_MIN;
}
y = nscoord(ny);
#endif
}

View File

@ -9,6 +9,8 @@
#include <stdio.h> // for FILE
#include <stdint.h> // for int32_t, int64_t
#include <algorithm> // for min/max
#include "nsDebug.h" // for NS_WARNING
#include "gfxCore.h" // for NS_GFX
#include "mozilla/Likely.h" // for MOZ_UNLIKELY
#include "mozilla/gfx/BaseRect.h" // for BaseRect
@ -53,11 +55,6 @@ struct NS_GFX nsRect :
}
#endif
// A version of Inflate that caps the values to the nscoord range.
// x & y is capped at the minimum value nscoord_MIN and
// width & height is capped at the maximum value nscoord_MAX.
void SaturatingInflate(const nsMargin& aMargin);
// We have saturating versions of all the Union methods. These avoid
// overflowing nscoord values in the 'width' and 'height' fields by
// clamping the width and height values to nscoord_MAX if necessary.
@ -73,7 +70,40 @@ struct NS_GFX nsRect :
}
}
nsRect SaturatingUnionEdges(const nsRect& aRect) const;
nsRect SaturatingUnionEdges(const nsRect& aRect) const
{
#ifdef NS_COORD_IS_FLOAT
return UnionEdges(aRect);
#else
nsRect result;
result.x = std::min(aRect.x, x);
int64_t w = std::max(int64_t(aRect.x) + aRect.width, int64_t(x) + width) - result.x;
if (MOZ_UNLIKELY(w > nscoord_MAX)) {
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord width");
// Clamp huge negative x to nscoord_MIN / 2 and try again.
result.x = std::max(result.x, nscoord_MIN / 2);
w = std::max(int64_t(aRect.x) + aRect.width, int64_t(x) + width) - result.x;
if (MOZ_UNLIKELY(w > nscoord_MAX)) {
w = nscoord_MAX;
}
}
result.width = nscoord(w);
result.y = std::min(aRect.y, y);
int64_t h = std::max(int64_t(aRect.y) + aRect.height, int64_t(y) + height) - result.y;
if (MOZ_UNLIKELY(h > nscoord_MAX)) {
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord height");
// Clamp huge negative y to nscoord_MIN / 2 and try again.
result.y = std::max(result.y, nscoord_MIN / 2);
h = std::max(int64_t(aRect.y) + aRect.height, int64_t(y) + height) - result.y;
if (MOZ_UNLIKELY(h > nscoord_MAX)) {
h = nscoord_MAX;
}
}
result.height = nscoord(h);
return result;
#endif
}
#ifndef NS_COORD_IS_FLOAT
// Make all nsRect Union methods be saturating.

View File

@ -208,6 +208,19 @@ PokeGC(JSRuntime *rt);
extern JS_FRIEND_API(bool)
WasIncrementalGC(JSRuntime *rt);
extern JS_FRIEND_API(size_t)
GetGCNumber();
class AutoAssertNoGC {
#ifdef DEBUG
size_t gcNumber;
public:
AutoAssertNoGC();
~AutoAssertNoGC();
#endif
};
class JS_PUBLIC_API(ObjectPtr)
{
Heap<JSObject *> value;

View File

@ -23,6 +23,8 @@
#include "jsatominlines.h"
#include "jsobjinlines.h"
#include "vm/Shape-inl.h"
using mozilla::DebugOnly;
using namespace js;

View File

@ -2560,13 +2560,14 @@ dnl ========================================================
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_CHECK_FUNCS([fchmod flockfile getc_unlocked _getc_nolock getpagesize \
lchown localtime_r lstat64 memmove random rint sbrk snprintf \
lchown localtime_r lstat64 memmove random sbrk snprintf \
stat64 statvfs statvfs64 strerror strtok_r truncate64])
dnl Checks for math functions.
dnl ========================================================
AC_CHECK_FUNCS(log2 log1p expm1 sqrt1pm1 acosh asinh atanh hypot trunc cbrt)
AC_CHECK_LIB(m, sin)
AC_CHECK_FUNCS([log2 log1p expm1 sqrt1pm1 acosh asinh atanh hypot trunc cbrt])
dnl check for wcrtomb/mbrtowc

View File

@ -10,6 +10,7 @@
#include "jit/IonCode.h"
#include "vm/ArgumentsObject.h"
#include "vm/ScopeObject.h"
#include "vm/Shape.h"
#include "vm/TypedArrayObject.h"
@ -17,7 +18,6 @@
#include "jsinferinlines.h"
#include "gc/Nursery-inl.h"
#include "vm/Shape-inl.h"
#include "vm/String-inl.h"
using namespace js;

View File

@ -53,7 +53,7 @@ The general format in EBNF is:
item ::= flag | attribute
flag ::= "slow" | "allow-oom" | "valgrind" | "tz-pacific" |
"mjit" | "mjitalways" | "ion-eager" | "debug" |
"ion-eager" | "debug" |
"dump-bytecode" |
@ -70,8 +70,6 @@ The meaning of the items:
allow-oom If the test runs out of memory, it counts as passing.
valgrind Run test under valgrind.
tz-pacific Always run test with the Pacific time zone (TZ=PST8PDT).
mjit Run js with -m, whether --jitflags says to or not
mjitalways Run js with -a, whether --jitflags says to or not
ion-eager Run js with --ion-eager, whether --jitflags says to or not
debug Run js with -d, whether --jitflags says to or not
dump-bytecode Run js with -D, whether --jitflags says to or not

View File

@ -63,13 +63,13 @@ def main(argv):
help='Run all tests with valgrind, if valgrind is in $PATH.')
op.add_option('--jitflags', dest='jitflags', default='',
help='Example: --jitflags=m,mn to run each test with "-m" and "-m -n" [default="%default"]. ' +
'Long flags, such as "--no-jm", should be set using --args.')
'Long flags, such as "--ion-eager", should be set using --args.')
op.add_option('--avoid-stdio', dest='avoid_stdio', action='store_true',
help='Use js-shell file indirection instead of piping stdio.')
op.add_option('--write-failure-output', dest='write_failure_output', action='store_true',
help='With --write-failures=FILE, additionally write the output of failed tests to [FILE]')
op.add_option('--ion', dest='ion', action='store_true',
help='Run tests once with --ion-eager and once with --no-jm (ignores --jitflags)')
help='Run tests once with --ion-eager and once with --baseline-eager (ignores --jitflags)')
op.add_option('--tbpl', dest='tbpl', action='store_true',
help='Run tests with all IonMonkey option combinations (ignores --jitflags)')
op.add_option('-j', '--worker-count', dest='max_jobs', type=int, default=max_jobs_default,

View File

@ -1,5 +1,5 @@
if (!this.hasOwnProperty("Type"))
exit(0);
quit();
function eval() {
yield(undefined)

View File

@ -1,4 +1,4 @@
if (!this.hasOwnProperty("Type"))
exit(0);
quit();
new StructType([])

View File

@ -1,5 +1,5 @@
if (!this.hasOwnProperty("Type"))
exit(0);
quit();
var Color = new StructType({r: uint8, g: uint8, b: uint8});
var white2 = new Color({r: 255, toString: null, b: 253});

View File

@ -1,4 +1,4 @@
if (!this.hasOwnProperty("Type"))
exit(0);
quit();
new StructType(RegExp());

View File

@ -1,3 +1,6 @@
if (!this.hasOwnProperty("Type"))
quit();
var PointType2 = new StructType({x: float64,
y: float64});

View File

@ -1,3 +1,6 @@
if (!this.hasOwnProperty("Type"))
quit();
var PointType = new StructType({x: float64,
y: float64,
z: float64});

View File

@ -1,3 +1,6 @@
if (!this.hasOwnProperty("Type"))
quit();
var PointType = new StructType({x: uint32,
y: uint32,
z: uint32});

View File

@ -1,8 +0,0 @@
if (!this.hasOwnProperty("Type"))
exit(0);
function eval() {
yield(undefined)
}
new(StructType)
(eval())

View File

@ -1,8 +0,0 @@
// |jit-test| error:Error
if (!this.hasOwnProperty("Type"))
throw new Error("type too large");
var AA = new ArrayType(new ArrayType(uint8, (2147483647)), 5);
var aa = new AA();
var aa0 = aa[0];

View File

@ -1,13 +0,0 @@
// |jit-test| error:Error
if (!this.hasOwnProperty("Type"))
throw new Error("type too large");
var A = new ArrayType(uint8, (2147483647));
var S = new StructType({a: A,
b: A,
c: A,
d: A,
e: A});
var aa = new S();
var aa0 = aa.a;

View File

@ -1,4 +0,0 @@
if (!this.hasOwnProperty("Type"))
exit(0);
new StructType([])

View File

@ -1,7 +0,0 @@
// |jit-test| error:RangeError;
if (!this.hasOwnProperty("Type"))
throw new RangeError();
this.__proto__ = Proxy.create({});
new StructType;

View File

@ -1,10 +0,0 @@
// |jit-test| error:Error;
if (!this.hasOwnProperty("Type"))
throw new Error();
var A = new ArrayType(uint8, 10);
var a = new A();
a.forEach(function(val, i) {
assertEq(arguments[5], a);
});

View File

@ -1,6 +0,0 @@
if (!this.hasOwnProperty("Type"))
exit(0);
var Color = new StructType({r: uint8, g: uint8, b: uint8});
var white2 = new Color({r: 255, toString: null, b: 253});

View File

@ -1,6 +0,0 @@
// |jit-test| error:TypeError
if (!this.hasOwnProperty("Type"))
throw new TypeError();
new StructType(RegExp);

View File

@ -1,4 +0,0 @@
if (!this.hasOwnProperty("Type"))
exit(0);
new StructType(RegExp());

View File

@ -1,6 +0,0 @@
// |jit-test| error:Error
if (!this.hasOwnProperty("Type"))
throw new Error();
new ArrayType(uint8, .0000000009);

View File

@ -1,10 +0,0 @@
// |jit-test| error: TypeError
if (!this.hasOwnProperty("Type"))
throw new TypeError();
var Vec3 = new ArrayType(float32, 3);
var Sprite = new ArrayType(Vec3, 3);
var mario = new Sprite();
mario[/\u00ee[]/] = new Vec3([1, 0, 0]);

View File

@ -1,25 +0,0 @@
var PointType2 = new StructType({x: float64,
y: float64});
var PointType3 = new StructType({x: float64,
y: float64,
z: float64});
function xPlusY(p) {
return p.x + p.y;
}
function foo() {
var N = 30000;
var points = [];
for (var i = 0; i < N; i++) {
var s;
if ((i % 2) == 0 || true)
s = xPlusY(new PointType2({x: i, y: i+1}));
else
s = xPlusY(new PointType3({x: i, y: i+1, z: i+2}));
assertEq(s, i + i + 1);
}
}
foo();

View File

@ -1,14 +0,0 @@
var PointType = new StructType({x: float64,
y: float64,
z: float64});
function foo() {
for (var i = 0; i < 30000; i += 3) {
var pt = new PointType({x: i, y: i+1, z: i+2});
var sum = pt.x + pt.y + pt.z;
print(pt.x, pt.y, pt.z);
assertEq(sum, 3*i + 3);
}
}
foo();

View File

@ -1,13 +0,0 @@
var PointType = new StructType({x: uint32,
y: uint32,
z: uint32});
function foo() {
for (var i = 0; i < 30000; i += 3) {
var pt = new PointType({x: i, y: i+1, z: i+2});
var sum = pt.x + pt.y + pt.z;
assertEq(sum, 3*i + 3);
}
}
foo();

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