Merge mozilla-central to mozilla-inbound. CLOSED TREE

This commit is contained in:
Csoregi Natalia 2019-03-21 12:52:50 +02:00
Родитель 1b143bbf1f 486b64e4bf
Коммит 6151e79a07
223 изменённых файлов: 2469 добавлений и 1165 удалений

Просмотреть файл

@ -4,269 +4,12 @@ dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
AC_DEFUN([MOZ_ARCH_OPTS],
[
dnl ========================================================
dnl = ARM toolchain tweaks
dnl ========================================================
MOZ_THUMB=toolchain-default
MOZ_THUMB_INTERWORK=toolchain-default
MOZ_FPU=toolchain-default
MOZ_FLOAT_ABI=toolchain-default
MOZ_SOFT_FLOAT=toolchain-default
MOZ_ALIGN=toolchain-default
MOZ_ARG_WITH_STRING(arch,
[ --with-arch=[[type|toolchain-default]]
Use specific CPU features (-march=type). Resets
thumb, fpu, float-abi, etc. defaults when set],
if test -z "$GNU_CC"; then
AC_MSG_ERROR([--with-arch is not supported on non-GNU toolchains])
fi
MOZ_ARCH=$withval)
if test -z "$MOZ_ARCH"; then
dnl Defaults
case "${CPU_ARCH}-${OS_TARGET}" in
arm-Android)
MOZ_THUMB=yes
MOZ_ARCH=armv7-a
MOZ_FPU=neon
MOZ_FLOAT_ABI=softfp
MOZ_ALIGN=no
;;
arm-Darwin)
MOZ_ARCH=toolchain-default
;;
esac
fi
if test "$MOZ_ARCH" = "armv6" -a "$OS_TARGET" = "Android"; then
AC_MSG_ERROR([Android/armv6 is not supported])
fi
MOZ_ARG_WITH_STRING(thumb,
[ --with-thumb[[=yes|no|toolchain-default]]]
[ Use Thumb instruction set (-mthumb)],
if test -z "$GNU_CC"; then
AC_MSG_ERROR([--with-thumb is not supported on non-GNU toolchains])
fi
MOZ_THUMB=$withval)
MOZ_ARG_WITH_STRING(thumb-interwork,
[ --with-thumb-interwork[[=yes|no|toolchain-default]]
Use Thumb/ARM instuctions interwork (-mthumb-interwork)],
if test -z "$GNU_CC"; then
AC_MSG_ERROR([--with-thumb-interwork is not supported on non-GNU toolchains])
fi
MOZ_THUMB_INTERWORK=$withval)
MOZ_ARG_WITH_STRING(fpu,
[ --with-fpu=[[type|toolchain-default]]
Use specific FPU type (-mfpu=type)],
if test -z "$GNU_CC"; then
AC_MSG_ERROR([--with-fpu is not supported on non-GNU toolchains])
fi
MOZ_FPU=$withval)
MOZ_ARG_WITH_STRING(float-abi,
[ --with-float-abi=[[type|toolchain-default]]
Use specific arm float ABI (-mfloat-abi=type)],
if test -z "$GNU_CC"; then
AC_MSG_ERROR([--with-float-abi is not supported on non-GNU toolchains])
fi
MOZ_FLOAT_ABI=$withval)
MOZ_ARG_WITH_STRING(soft-float,
[ --with-soft-float[[=yes|no|toolchain-default]]
Use soft float library (-msoft-float)],
if test -z "$GNU_CC"; then
AC_MSG_ERROR([--with-soft-float is not supported on non-GNU toolchains])
fi
MOZ_SOFT_FLOAT=$withval)
case "$MOZ_ARCH" in
toolchain-default|"")
arch_flag=""
;;
*)
arch_flag="-march=$MOZ_ARCH"
;;
esac
case "$MOZ_THUMB" in
yes)
MOZ_THUMB2=1
thumb_flag="-mthumb"
;;
no)
MOZ_THUMB2=
thumb_flag="-marm"
;;
*)
_SAVE_CFLAGS="$CFLAGS"
CFLAGS="$arch_flag"
AC_TRY_COMPILE([],[return sizeof(__thumb2__);],
MOZ_THUMB2=1,
MOZ_THUMB2=)
CFLAGS="$_SAVE_CFLAGS"
thumb_flag=""
;;
esac
if test "$MOZ_THUMB2" = 1; then
AC_DEFINE(MOZ_THUMB2)
fi
case "$MOZ_THUMB_INTERWORK" in
yes)
thumb_interwork_flag="-mthumb-interwork"
;;
no)
thumb_interwork_flag="-mno-thumb-interwork"
;;
*) # toolchain-default
thumb_interwork_flag=""
;;
esac
case "$MOZ_FPU" in
toolchain-default|"")
fpu_flag=""
;;
*)
fpu_flag="-mfpu=$MOZ_FPU"
;;
esac
case "$MOZ_FLOAT_ABI" in
toolchain-default|"")
float_abi_flag=""
;;
*)
float_abi_flag="-mfloat-abi=$MOZ_FLOAT_ABI"
;;
esac
case "$MOZ_SOFT_FLOAT" in
yes)
soft_float_flag="-msoft-float"
;;
no)
soft_float_flag="-mno-soft-float"
;;
*) # toolchain-default
soft_float_flag=""
;;
esac
case "$MOZ_ALIGN" in
no)
align_flag="-mno-unaligned-access"
;;
yes)
align_flag="-munaligned-access"
;;
*)
align_flag=""
;;
esac
if test -n "$align_flag"; then
_SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $align_flag"
AC_MSG_CHECKING(whether alignment flag ($align_flag) is supported)
AC_TRY_COMPILE([],[],,align_flag="")
CFLAGS="$_SAVE_CFLAGS"
fi
dnl Use echo to avoid accumulating space characters
all_flags=`echo $arch_flag $thumb_flag $thumb_interwork_flag $fpu_flag $float_abi_flag $soft_float_flag $align_flag`
if test -n "$all_flags"; then
_SAVE_CFLAGS="$CFLAGS"
CFLAGS="$all_flags"
AC_MSG_CHECKING(whether the chosen combination of compiler flags ($all_flags) works)
AC_TRY_COMPILE([],[return 0;],
AC_MSG_RESULT([yes]),
AC_MSG_ERROR([no]))
CFLAGS="$_SAVE_CFLAGS $all_flags"
CXXFLAGS="$CXXFLAGS $all_flags"
ASFLAGS="$ASFLAGS $all_flags"
if test -n "$thumb_flag"; then
LDFLAGS="$LDFLAGS $thumb_flag"
if test -n "$_ARM_FLAGS"; then
CFLAGS="$CFLAGS $_ARM_FLAGS"
CXXFLAGS="$CXXFLAGS $_ARM_FLAGS"
ASFLAGS="$ASFLAGS $_ARM_FLAGS"
if test -n "$_THUMB_FLAGS"; then
LDFLAGS="$LDFLAGS $_THUMB_FLAGS"
fi
fi
AC_SUBST(MOZ_THUMB2)
if test "$CPU_ARCH" = "arm"; then
NEON_FLAGS="-mfpu=neon"
AC_MSG_CHECKING(for ARM SIMD support in compiler)
# We try to link so that this also fails when
# building with LTO.
AC_TRY_LINK([],
[asm("uqadd8 r1, r1, r2");],
result="yes", result="no")
AC_MSG_RESULT("$result")
if test "$result" = "yes"; then
AC_DEFINE(HAVE_ARM_SIMD)
HAVE_ARM_SIMD=1
fi
AC_MSG_CHECKING(ARM version support in compiler)
dnl Determine the target ARM architecture (5 for ARMv5, v5T, v5E, etc.; 6 for ARMv6, v6K, etc.)
ARM_ARCH=`${CC-cc} ${CFLAGS} -dM -E - < /dev/null | sed -n 's/.*__ARM_ARCH_\([[0-9]][[0-9]]*\).*/\1/p' | head -n 1`
AC_MSG_RESULT("$ARM_ARCH")
AC_MSG_CHECKING(for ARM NEON support in compiler)
# We try to link so that this also fails when
# building with LTO.
AC_TRY_LINK([],
[asm(".fpu neon\n vadd.i8 d0, d0, d0");],
result="yes", result="no")
AC_MSG_RESULT("$result")
if test "$result" = "yes"; then
AC_DEFINE(HAVE_ARM_NEON)
HAVE_ARM_NEON=1
dnl We don't need to build NEON support if we're targetting a non-NEON device.
dnl This matches media/webrtc/trunk/webrtc/build/common.gypi.
if test -n "$ARM_ARCH"; then
if test "$ARM_ARCH" -lt 7; then
BUILD_ARM_NEON=
else
AC_DEFINE(BUILD_ARM_NEON)
BUILD_ARM_NEON=1
fi
fi
fi
dnl Building with -mfpu=neon requires either the "softfp" or the
dnl "hardfp" ABI. Depending on the compiler's default target, and the
dnl CFLAGS, the default ABI might be neither, in which case it is the
dnl "softfloat" ABI.
dnl The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
dnl we can safely mix code built with both ABIs. So, if we detect
dnl that compiling uses the "softfloat" ABI, force the use of the
dnl "softfp" ABI instead.
dnl Confusingly, the __SOFTFP__ preprocessor variable indicates the
dnl "softfloat" ABI, not the "softfp" ABI.
dnl Note: VPX_ASFLAGS is also used in CFLAGS.
AC_TRY_COMPILE([],
[#ifndef __SOFTFP__
#error "compiler target supports -mfpu=neon, so we don't have to add extra flags"
#endif],
NEON_FLAGS="$NEON_FLAGS -mfloat-abi=softfp"
)
fi # CPU_ARCH = arm
AC_SUBST(HAVE_ARM_SIMD)
AC_SUBST(HAVE_ARM_NEON)
AC_SUBST(BUILD_ARM_NEON)
AC_SUBST(ARM_ARCH)
AC_SUBST_LIST(NEON_FLAGS)
AC_SUBST(MOZ_FPU)
])

Просмотреть файл

@ -0,0 +1,257 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
@depends(target.os, '--help')
def arm_option_defaults(os, _):
if os == 'Android':
arch = 'armv7-a'
thumb = 'yes'
fpu = 'neon'
float_abi = 'softfp'
else:
arch = thumb = fpu = float_abi = 'toolchain-default'
return namespace(
arch=arch,
thumb=thumb,
fpu=fpu,
float_abi=float_abi,
)
# Note: '{...|}' in the help of all options with a non-constant default to
# make the lint happy. The first arm is always going to be used, because a
# default is always returned. The lint is fooled by this file being
# conditional. If it weren't conditional, the lint wouldn't ask for '{|}' to
# be there.
js_option('--with-arch', nargs=1,
default=arm_option_defaults.arch,
help='{Use specific CPU features (-march=type). Resets thumb, fpu, '
'float-abi, etc. defaults when set|}')
@depends('--with-arch')
def arch_option(value):
if value:
if value[0] != 'toolchain-default':
return ['-march={}'.format(value[0])]
return []
js_option('--with-thumb', choices=('yes', 'no', 'toolchain-default'),
default=arm_option_defaults.thumb,
nargs='?', help='{Use Thumb instruction set (-mthumb)|}')
def normalize_arm_option(value):
if value:
if len(value):
if value[0] == 'yes':
return True
elif value[0] == 'no':
return False
else:
return value[0]
return True
return False
@depends('--with-thumb')
def thumb_option(value):
value = normalize_arm_option(value)
if value is True:
return ['-mthumb']
if value is False:
return ['-marm']
return []
js_option('--with-thumb-interwork', choices=('yes', 'no', 'toolchain-default'),
default='toolchain-default',
nargs='?', help='Use Thumb/ARM instuctions interwork (-mthumb-interwork)')
@depends('--with-thumb-interwork')
def thumb_interwork_option(value):
value = normalize_arm_option(value)
if value is True:
return ['-mthumb-interwork']
if value is False:
return ['-mno-thumb-interwork']
return []
js_option('--with-fpu', nargs=1,
default=arm_option_defaults.fpu,
help='{Use specific FPU type (-mfpu=type)|}')
@depends('--with-fpu')
def fpu_option(value):
if value:
if value[0] != 'toolchain-default':
return ['-mfpu={}'.format(value[0])]
return []
js_option('--with-float-abi', nargs=1,
default=arm_option_defaults.float_abi,
help='{Use specific arm float ABI (-mfloat-abi=type)|}')
@depends('--with-float-abi')
def float_abi_option(value):
if value:
if value[0] != 'toolchain-default':
return ['-mfloat-abi={}'.format(value[0])]
return []
js_option('--with-soft-float', choices=('yes', 'no', 'toolchain-default'),
default='toolchain-default',
nargs='?', help='Use soft float library (-msoft-float)')
@depends('--with-soft-float')
def soft_float_option(value):
value = normalize_arm_option(value)
if value is True:
return ['-msoft-float']
if value is False:
return ['-mno-soft-float']
return []
check_and_add_gcc_flag('-mno-unaligned-access',
when=depends(target.os)(lambda os: os == 'Android'))
@depends(arch_option, thumb_option, thumb_interwork_option, fpu_option,
float_abi_option, soft_float_option)
def all_flags(arch, thumb, interwork, fpu, float_abi, soft_float):
return arch + thumb + interwork + fpu + float_abi + soft_float
add_old_configure_assignment('_ARM_FLAGS', all_flags)
add_old_configure_assignment('_THUMB_FLAGS', thumb_option)
@depends(c_compiler, all_flags)
@checking('ARM version support in compiler', lambda x: x.arm_arch)
@imports(_from='textwrap', _import='dedent')
def arm_target(compiler, all_flags):
# We're going to preprocess the following source to figure out some details
# about the arm target options we have enabled.
source = dedent('''\
%ARM_ARCH __ARM_ARCH
#if __thumb2__
%THUMB2 yes
#else
%THUMB2 no
#endif
// Confusingly, the __SOFTFP__ preprocessor variable indicates the
// "softfloat" ABI, not the "softfp" ABI.
#if __SOFTFP__
%FLOAT_ABI soft
#elif __ARM_PCS_VFP
%FLOAT_ABI hard
#else
%FLOAT_ABI softfp
#endif
// There is more subtlety to it than this preprocessor test, but MOZ_FPU doesn't
// need to be too fine-grained.
#if __ARM_NEON
%FPU neon
#elif __ARM_VFPV2__
%FPU vfpv2
#elif __ARM_VFPV3__
%FPU vfpv3
#elif __ARM_VFPV4__
%FPU vfpv4
#elif __ARM_FPV5__
%FPU fp-armv8
#endif
''')
result = try_invoke_compiler(
compiler.wrapper + [compiler.compiler] + compiler.flags,
compiler.language,
source,
['-E'] + all_flags,
)
# Metadata emitted by preprocessors such as GCC with LANG=ja_JP.utf-8 may
# have non-ASCII characters. Treat the output as bytearray.
data = {}
for line in result.splitlines():
if line.startswith(b'%'):
k, _, v = line.partition(' ')
k = k.lstrip('%').lower()
if k == 'arm_arch':
data[k] = int(v)
else:
data[k] = {
'yes': True,
'no': False,
}.get(v, v)
log.debug('%s = %s', k, data[k])
return namespace(**data)
@depends(arm_target.arm_arch, when=depends(target.os)(lambda os: os == 'Android'))
def armv7(arch):
if arch < 7:
die('Android/armv6 and earlier are not supported')
set_config('MOZ_THUMB2', True, when=arm_target.thumb2)
set_define('MOZ_THUMB2', True, when=arm_target.thumb2)
add_old_configure_assignment('MOZ_THUMB2', True, when=arm_target.thumb2)
have_arm_simd = c_compiler.try_compile(body='asm("uqadd8 r1, r1, r2");',
check_msg='for ARM SIMD support in compiler')
set_config('HAVE_ARM_SIMD', have_arm_simd)
set_define('HAVE_ARM_SIMD', have_arm_simd)
have_arm_neon = c_compiler.try_compile(body='asm(".fpu neon\\n vadd.i8 d0, d0, d0");',
check_msg='for ARM NEON support in compiler')
set_config('HAVE_ARM_NEON', have_arm_neon)
set_define('HAVE_ARM_NEON', have_arm_neon)
# We don't need to build NEON support if we're targetting a non-NEON device.
# This matches media/webrtc/trunk/webrtc/build/common.gypi.
@depends(arm_target.arm_arch, when=have_arm_neon)
def build_arm_neon(arm_arch):
return arm_arch >= 7
set_config('BUILD_ARM_NEON', build_arm_neon)
set_define('BUILD_ARM_NEON', build_arm_neon)
set_config('ARM_ARCH', depends(arm_target.arm_arch)(lambda x: str(x)))
add_old_configure_assignment('ARM_ARCH', depends(arm_target.arm_arch)(lambda x: str(x)))
set_config('MOZ_FPU', arm_target.fpu)
@depends(arm_target.float_abi)
def neon_flags(float_abi):
# Building with -mfpu=neon requires either the "softfp" or the
# "hardfp" ABI. Depending on the compiler's default target, and the
# CFLAGS, the default ABI might be neither, in which case it is the
# "softfloat" ABI.
# The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
# we can safely mix code built with both ABIs. So, if we detect
# that compiling uses the "softfloat" ABI, force the use of the
# "softfp" ABI instead.
flags = ['-mfpu=neon']
if float_abi == 'soft':
flags.append('-mfloat-abi=softfp')
return tuple(flags)
set_config('NEON_FLAGS', neon_flags)

Просмотреть файл

@ -231,7 +231,6 @@ def old_configure_options(*options):
'--with-android-min-sdk',
'--with-app-basename',
'--with-app-name',
'--with-arch',
'--with-branding',
'--with-cross-lib',
'--with-debug-label',
@ -239,8 +238,6 @@ def old_configure_options(*options):
'--with-doc-include-dirs',
'--with-doc-input-dirs',
'--with-doc-output-dir',
'--with-float-abi',
'--with-fpu',
'--with-intl-api',
'--with-ios-sdk',
'--with-jitreport-granularity',
@ -253,7 +250,6 @@ def old_configure_options(*options):
'--with-nss-prefix',
'--with-qemu-exe',
'--with-sixgill',
'--with-soft-float',
'--with-system-bz2',
'--with-system-icu',
'--with-system-libevent',
@ -261,8 +257,6 @@ def old_configure_options(*options):
'--with-system-nss',
'--with-system-png',
'--with-system-zlib',
'--with-thumb',
'--with-thumb-interwork',
'--with-unify-dist',
'--with-user-appdir',
'--x-includes',

Просмотреть файл

@ -1183,6 +1183,7 @@ def msvs_version(info):
set_config('MSVS_VERSION', msvs_version)
include('compile-checks.configure')
include('arm.configure', when=depends(target.cpu)(lambda cpu: cpu == 'arm'))
@depends(have_64_bit,

Просмотреть файл

@ -2810,7 +2810,7 @@ html[dir="rtl"] .editor-mount {
}
.debug-expression,
.new-debug-line .column-breakpoint {
.debug-expression ~ .CodeMirror-widget {
background-color: var(--debug-expression-background);
}

Просмотреть файл

@ -3,21 +3,20 @@
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
// @flow
import { setBreakpointPositions } from "./breakpointPositions";
import {
breakpointExists,
assertBreakpoint,
createBreakpoint,
getASTLocation,
makeBreakpointId,
makeBreakpointLocation,
findPosition
makeBreakpointLocation
} from "../../utils/breakpoint";
import { PROMISE } from "../utils/middleware/promise";
import {
getSymbols,
getFirstBreakpointPosition,
getBreakpointPositionsForSource,
getBreakpointPositionsForLocation,
getSourceFromId
} from "../../selectors";
@ -101,15 +100,14 @@ export function addBreakpoint(
) {
return async ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
recordEvent("add_breakpoint");
let position;
const { sourceId, column } = location;
if (column === undefined) {
position = getFirstBreakpointPosition(getState(), location);
} else {
const positions = getBreakpointPositionsForSource(getState(), sourceId);
position = findPosition(positions, location);
}
await dispatch(setBreakpointPositions(sourceId));
const position = column
? getBreakpointPositionsForLocation(getState(), location)
: getFirstBreakpointPosition(getState(), location);
if (!position) {
return;

Просмотреть файл

@ -123,6 +123,9 @@ export function setBreakpointPositions(sourceId: string) {
(async () => {
try {
await _setBreakpointPositions(sourceId, thunkArgs);
} catch (e) {
// TODO: Address exceptions originating from 1536618
// `Debugger.Source belongs to a different Debugger`
} finally {
requests.delete(sourceId);
}

Просмотреть файл

@ -90,7 +90,7 @@ async function loadSourceTextPromise(
if (!newSource.isWasm && isLoaded(newSource)) {
parser.setSource(newSource);
await dispatch(setBreakpointPositions(newSource.id));
dispatch(setBreakpointPositions(newSource.id));
}
return newSource;
@ -105,6 +105,7 @@ export function loadSourceText(inputSource: ?Source) {
if (!inputSource) {
return;
}
// This ensures that the falsy check above is preserved into the IIFE
// below in a way that Flow is happy with.
const source = inputSource;

Просмотреть файл

@ -114,7 +114,7 @@ html[dir="rtl"] .editor-mount {
}
.debug-expression,
.new-debug-line .column-breakpoint {
.debug-expression ~ .CodeMirror-widget {
background-color: var(--debug-expression-background);
}

Просмотреть файл

@ -9,10 +9,10 @@
* @module reducers/breakpoints
*/
import { isGeneratedId, isOriginalId } from "devtools-source-map";
import { isGeneratedId } from "devtools-source-map";
import { isEqual } from "lodash";
import { makeBreakpointId } from "../utils/breakpoint";
import { makeBreakpointId, findPosition } from "../utils/breakpoint";
import { findEmptyLines } from "../utils/empty-lines";
// eslint-disable-next-line max-len
@ -22,6 +22,7 @@ import type {
XHRBreakpoint,
Breakpoint,
BreakpointId,
MappedLocation,
SourceLocation,
BreakpointPositions
} from "../types";
@ -380,19 +381,13 @@ export function hasBreakpointPositions(
return !!getBreakpointPositionsForSource(state, sourceId);
}
export function getBreakpointPositionsForLine(
export function getBreakpointPositionsForLocation(
state: OuterState,
sourceId: string,
line: number
): ?BreakpointPositions {
location: SourceLocation
): ?MappedLocation {
const { sourceId } = location;
const positions = getBreakpointPositionsForSource(state, sourceId);
if (!positions) {
return null;
}
return positions.filter(({ location, generatedLocation }) => {
const loc = isOriginalId(sourceId) ? location : generatedLocation;
return loc.line == line;
});
return findPosition(positions, location);
}
export function isEmptyLineInSource(

Просмотреть файл

@ -32,6 +32,10 @@
"waitForClipboard": false,
"waitForExplicitFinish": false,
"waitForFocus": false,
"selectSource": false,
"prettyPrint": false,
"closeTab": false,
"assertEditorBreakpoint": false,
// Globals introduced in debugger-specific head.js
"promise": false,
@ -42,8 +46,12 @@
"waitForThreadEvents": false,
"waitForState": false,
"waitForElement": false,
"waitForElementWithSelector": false,
"waitForPaused": false,
"waitForSources": false,
"waitForSource": false,
"waitForLoadedSource": false,
"waitForSelectedSource": false,
"isPaused": false,
"assertPausedLocation": false,
"assertHighlightLocation": false,
@ -68,6 +76,7 @@
"toggleScopes": false,
"isVisibleWithin": false,
"clickElement": false,
"clickElementWithSelector": false,
"rightClickElement": false,
"selectMenuItem": false,
"togglePauseOnExceptions": false,

Просмотреть файл

@ -1,5 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* 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 pending breakpoints when reloading
requestLongerTimeout(3);
@ -20,16 +21,13 @@ function addBreakpoint(dbg, line) {
}
function assertEditorBreakpoint(dbg, line) {
const exists = !!getLineEl(dbg, line).querySelector(".new-breakpoint");
const lineEl = getLineEl(dbg, line);
const exists = lineEl.classList.contains("new-breakpoint");
ok(exists, `Breakpoint exists on line ${line}`);
}
add_task(async function() {
const dbg = await initDebugger("doc-scripts.html", "simple1.js");
const {
selectors: { getBreakpoints, getBreakpoint },
getState
} = dbg;
const source = findSource(dbg, "simple1.js");
await selectSource(dbg, source.url);

Просмотреть файл

@ -10,6 +10,10 @@ add_task(async function() {
clickElementWithSelector(dbg, ".watch-expressions-pane ._header");
info(">> Click + to add the new expression");
await waitForElementWithSelector(
dbg,
".watch-expressions-pane ._header .plus"
);
clickElementWithSelector(dbg, ".watch-expressions-pane ._header .plus");
info(">> Ensure element gets focused");

Просмотреть файл

@ -7,7 +7,7 @@
add_task(async function() {
const dbg = await initDebugger("doc-pretty.html", "pretty.js");
await selectSource(dbg, "pretty.js")
await selectSource(dbg, "pretty.js");
await prettyPrint(dbg);
await addBreakpoint(dbg, "pretty.js:formatted", 5);

Просмотреть файл

@ -58,6 +58,7 @@ add_task(async function() {
const selectedSource = dbg.selectors.getSelectedSource(dbg.getState());
ok(selectedSource.url.includes("switching-01"));
await waitForLoadedSource(dbg, "switching-01");
});
add_task(async function() {

Просмотреть файл

@ -1,5 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* 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/>. */
/*
* Test reloading:
@ -21,19 +22,23 @@ function getBreakpoints(dbg) {
return dbg.selectors.getBreakpointsList(dbg.getState());
}
function getBreakpointCount(dbg) {
return dbg.selectors.getBreakpointCount(dbg.getState());
}
add_task(async function() {
const dbg = await initDebugger("doc-minified.html");
await navigate(dbg, "sourcemaps-reload/doc-sourcemaps-reload.html", "v1.js");
info('Add initial breakpoint');
info("Add initial breakpoint");
await selectSource(dbg, "v1.js");
await addBreakpoint(dbg, "v1.js", 6);
let breakpoint = getBreakpoints(dbg)[0];
is(breakpoint.location.line, 6);
info('Reload with a new version of the file');
info("Reload with a new version of the file");
let syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT");
await navigate(dbg, "doc-sourcemaps-reload2.html", "v1.js");
@ -43,18 +48,17 @@ add_task(async function() {
is(breakpoint.location.line, 9);
is(breakpoint.generatedLocation.line, 79);
info('Add a second breakpoint');
info("Add a second breakpoint");
await addBreakpoint(dbg, "v1.js", 13);
is(dbg.selectors.getBreakpointCount(dbg.getState()), 2, "No breakpoints");
is(getBreakpointCount(dbg), 2, "No breakpoints");
// NOTE: When we reload, the `foo` function and the
// module is no longer 13 lines long
info('Reload and observe no breakpoints')
info("Reload and observe no breakpoints");
syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT", 2);
await navigate(dbg, "doc-sourcemaps-reload3.html", "v1.js");
await waitForSource(dbg, "v1");
await syncBp;
is(getBreakpoints(dbg).length, 0, "No breakpoints");
is(getBreakpointCount(dbg), 0, "No breakpoints");
});

Просмотреть файл

@ -1,3 +1,4 @@
/* eslint-disable no-unused-vars */
/* 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/>. */
@ -41,40 +42,17 @@ async function waitFor(condition) {
}
// Wait until an action of `type` is dispatched. This is different
// then `_afterDispatchDone` because it doesn't wait for async actions
// then `waitForDispatch` because it doesn't wait for async actions
// to be done/errored. Use this if you want to listen for the "start"
// action of an async operation (somewhat rare).
function waitForNextDispatch(store, type) {
function waitForNextDispatch(store, actionType) {
return new Promise(resolve => {
store.dispatch({
// Normally we would use `services.WAIT_UNTIL`, but use the
// internal name here so tests aren't forced to always pass it
// in
type: "@@service/waitUntil",
predicate: action => action.type === type,
run: (dispatch, getState, action) => {
resolve(action);
}
});
});
}
// Wait until an action of `type` is dispatched. If it's part of an
// async operation, wait until the `status` field is "done" or "error"
function _afterDispatchDone(store, type) {
return new Promise(resolve => {
store.dispatch({
// Normally we would use `services.WAIT_UNTIL`, but use the
// internal name here so tests aren't forced to always pass it
// in
type: "@@service/waitUntil",
predicate: action => {
if (action.type === type) {
return action.status
? action.status === "done" || action.status === "error"
: true;
}
},
predicate: action => action.type === actionType,
run: (dispatch, getState, action) => {
resolve(action);
}
@ -93,16 +71,28 @@ function _afterDispatchDone(store, type) {
* @return {Promise}
* @static
*/
function waitForDispatch(dbg, type, eventRepeat = 1) {
function waitForDispatch(dbg, actionType, eventRepeat = 1) {
let count = 0;
return new Promise(resolve => {
dbg.store.dispatch({
// Normally we would use `services.WAIT_UNTIL`, but use the
// internal name here so tests aren't forced to always pass it
// in
type: "@@service/waitUntil",
predicate: action => {
const isDone =
!action.status ||
action.status === "done" ||
action.status === "error";
return Task.spawn(function*() {
info(`Waiting for ${type} to dispatch ${eventRepeat} time(s)`);
while (count < eventRepeat) {
yield _afterDispatchDone(dbg.store, type);
count++;
info(`${type} dispatched ${count} time(s)`);
}
if (action.type === actionType && isDone && ++count == eventRepeat) {
return true;
}
},
run: (dispatch, getState, action) => {
resolve(action);
}
});
});
}
@ -737,10 +727,13 @@ async function navigate(dbg, url, ...sources) {
return waitForSources(dbg, ...sources);
}
function getFirstBreakpointColumn(dbg, {line, sourceId}) {
const {getSource, getFirstBreakpointPosition} = dbg.selectors;
const source = getSource(dbg.getState(), sourceId)
const position = getFirstBreakpointPosition(dbg.getState(), { line, sourceId });
function getFirstBreakpointColumn(dbg, { line, sourceId }) {
const { getSource, getFirstBreakpointPosition } = dbg.selectors;
const source = getSource(dbg.getState(), sourceId);
const position = getFirstBreakpointPosition(dbg.getState(), {
line,
sourceId
});
return getSelectedLocation(position, source).column;
}
@ -759,15 +752,19 @@ function getFirstBreakpointColumn(dbg, {line, sourceId}) {
async function addBreakpoint(dbg, source, line, column, options) {
source = findSource(dbg, source);
const sourceId = source.id;
column = column || getFirstBreakpointColumn(dbg, {line, sourceId: source.id});
const bpCount = dbg.selectors.getBreakpointCount(dbg.getState());
dbg.actions.addBreakpoint({ sourceId, line, column }, options);
await waitForDispatch(dbg, "ADD_BREAKPOINT");
is(dbg.selectors.getBreakpointCount(dbg.getState()), bpCount + 1, "a new breakpoint was created");
is(
dbg.selectors.getBreakpointCount(dbg.getState()),
bpCount + 1,
"a new breakpoint was created"
);
}
function disableBreakpoint(dbg, source, line, column) {
column = column || getFirstBreakpointColumn(dbg, {line, sourceId: source.id});
column =
column || getFirstBreakpointColumn(dbg, { line, sourceId: source.id });
const location = { sourceId: source.id, sourceUrl: source.url, line, column };
const bp = dbg.selectors.getBreakpointForLocation(dbg.getState(), location);
dbg.actions.disableBreakpoint(bp);
@ -1255,10 +1252,7 @@ async function clickElement(dbg, elementName, ...args) {
}
function clickElementWithSelector(dbg, selector) {
clickDOMElement(
dbg,
findElementWithSelector(dbg, selector)
);
clickDOMElement(dbg, findElementWithSelector(dbg, selector));
}
function clickDOMElement(dbg, element) {

Просмотреть файл

@ -103,6 +103,11 @@ class ViewportDimension extends PureComponent {
const { target } = event;
target.value = parseInt(target.value, 10) + increment;
this.onInputChange(event, this.onInputSubmit);
// Keep this event from having default processing. Since the field is a
// number field, default processing would trigger additional manipulations
// of the value, and we've already applied the desired amount.
event.preventDefault();
}
onInputKeyUp({ target, keyCode }) {
@ -162,6 +167,7 @@ class ViewportDimension extends PureComponent {
className: "text-input viewport-dimension-input" +
(this.state.isWidthValid ? "" : " invalid"),
size: 4,
type: "number",
value: this.state.width,
onBlur: this.onInputBlur,
onChange: this.onInputChange,
@ -179,6 +185,7 @@ class ViewportDimension extends PureComponent {
className: "text-input viewport-dimension-input" +
(this.state.isHeightValid ? "" : " invalid"),
size: 4,
type: "number",
value: this.state.height,
onBlur: this.onInputBlur,
onChange: this.onInputChange,

Просмотреть файл

@ -362,6 +362,7 @@ body,
.viewport-dimension-input {
text-align: center;
width: 3em;
-moz-appearance: textfield;
}
.viewport-dimension-separator {

Просмотреть файл

@ -319,7 +319,9 @@ class IdleDispatchRunnable final : public IdleRunnable,
mCallback(&aCallback),
mParent(aParent) {}
NS_IMETHOD Run() override {
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT.
// See bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
if (mCallback) {
CancelTimer();
@ -329,12 +331,10 @@ class IdleDispatchRunnable final : public IdleRunnable,
RefPtr<IdleDeadline> idleDeadline =
new IdleDeadline(mParent, mTimedOut, deadline.ToMilliseconds());
mCallback->Call(*idleDeadline, rv, "ChromeUtils::IdleDispatch handler");
mCallback = nullptr;
RefPtr<IdleRequestCallback> callback(mCallback.forget());
MOZ_ASSERT(!mCallback);
callback->Call(*idleDeadline, "ChromeUtils::IdleDispatch handler");
mParent = nullptr;
rv.SuppressException();
return rv.StealNSResult();
}
return NS_OK;
}

Просмотреть файл

@ -460,7 +460,8 @@ void DOMIntersectionObserver::Notify() {
}
}
mQueuedEntries.Clear();
mCallback->Call(this, entries, *this);
RefPtr<dom::IntersectionCallback> callback(mCallback);
callback->Call(this, entries, *this);
}
} // namespace dom

Просмотреть файл

@ -7,6 +7,7 @@
#ifndef DOMIntersectionObserver_h
#define DOMIntersectionObserver_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/IntersectionObserverBinding.h"
#include "nsStyleCoord.h"
#include "nsTArray.h"
@ -132,7 +133,7 @@ class DOMIntersectionObserver final : public nsISupports,
bool SetRootMargin(const nsAString& aString);
void Update(Document* aDocument, DOMHighResTimeStamp time);
void Notify();
MOZ_CAN_RUN_SCRIPT void Notify();
protected:
void Connect();

Просмотреть файл

@ -11830,7 +11830,7 @@ DocumentAutoplayPolicy Document::AutoplayPolicy() const {
}
void Document::MaybeAllowStorageForOpenerAfterUserInteraction() {
if (mCookieSettings->GetCookieBehavior() !=
if (CookieSettings()->GetCookieBehavior() !=
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
return;
}
@ -12352,7 +12352,7 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
}
// Only enforce third-party checks when there is a reason to enforce them.
if (mCookieSettings->GetCookieBehavior() !=
if (CookieSettings()->GetCookieBehavior() !=
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
// Step 3. If the document's frame is the main frame, resolve.
if (IsTopLevelContentDocument()) {
@ -12405,7 +12405,7 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
return promise.forget();
}
if (mCookieSettings->GetCookieBehavior() ==
if (CookieSettings()->GetCookieBehavior() ==
nsICookieService::BEHAVIOR_REJECT_TRACKER &&
inner) {
// Only do something special for third-party tracking content.

Просмотреть файл

@ -48,6 +48,7 @@
#include "nsContentListDeclarations.h"
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
#include "mozilla/Attributes.h"
#include "mozilla/CORSMode.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/ContentBlockingLog.h"
@ -3487,7 +3488,7 @@ class Document : public nsINode,
void UpdateIntersectionObservations();
void ScheduleIntersectionObserverNotification();
void NotifyIntersectionObservers();
MOZ_CAN_RUN_SCRIPT void NotifyIntersectionObservers();
// Dispatch a runnable related to the document.
nsresult Dispatch(TaskCategory aCategory,

Просмотреть файл

@ -51,19 +51,16 @@ uint32_t IdleRequest::GetTimeoutHandle() const {
return mTimeoutHandle.value();
}
nsresult IdleRequest::IdleRun(nsPIDOMWindowInner* aWindow,
DOMHighResTimeStamp aDeadline, bool aDidTimeout) {
void IdleRequest::IdleRun(nsPIDOMWindowInner* aWindow,
DOMHighResTimeStamp aDeadline, bool aDidTimeout) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(mCallback);
ErrorResult error;
RefPtr<IdleDeadline> deadline =
new IdleDeadline(aWindow, aDidTimeout, aDeadline);
mCallback->Call(*deadline, error, "requestIdleCallback handler");
mCallback = nullptr;
error.SuppressException();
return error.StealNSResult();
RefPtr<IdleRequestCallback> callback(mCallback.forget());
MOZ_ASSERT(!mCallback);
callback->Call(*deadline, "requestIdleCallback handler");
}
} // namespace dom

Просмотреть файл

@ -28,8 +28,9 @@ class IdleRequest final : public LinkedListElement<RefPtr<IdleRequest>> {
public:
IdleRequest(IdleRequestCallback* aCallback, uint32_t aHandle);
nsresult IdleRun(nsPIDOMWindowInner* aWindow, DOMHighResTimeStamp aDeadline,
bool aDidTimeout);
MOZ_CAN_RUN_SCRIPT
void IdleRun(nsPIDOMWindowInner* aWindow, DOMHighResTimeStamp aDeadline,
bool aDidTimeout);
void SetTimeoutHandle(int32_t aHandle);
bool HasTimeout() const { return mTimeoutHandle.isSome(); }

Просмотреть файл

@ -91,20 +91,23 @@ class EncodingCompleteEvent : public CancelableRunnable {
}
}
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
NS_IMETHOD Run() override {
nsresult rv = NS_OK;
// We want to null out mEncodeCompleteCallback no matter what.
RefPtr<EncodeCompleteCallback> callback(mEncodeCompleteCallback.forget());
if (!mFailed) {
// The correct parentObject has to be set by the mEncodeCompleteCallback.
RefPtr<Blob> blob =
Blob::CreateMemoryBlob(nullptr, mImgData, mImgSize, mType);
MOZ_ASSERT(blob);
rv = mEncodeCompleteCallback->ReceiveBlob(blob.forget());
rv = callback->ReceiveBlob(blob.forget());
}
mEncodeCompleteCallback = nullptr;
return rv;
}

Просмотреть файл

@ -115,6 +115,7 @@ class EncodeCompleteCallback {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(EncodeCompleteCallback)
MOZ_CAN_RUN_SCRIPT
virtual nsresult ReceiveBlob(already_AddRefed<Blob> aBlob) = 0;
protected:

Просмотреть файл

@ -1240,8 +1240,8 @@ void Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints,
return;
}
MediaManager::GetUserMediaSuccessCallback onsuccess(&aOnSuccess);
MediaManager::GetUserMediaErrorCallback onerror(&aOnError);
RefPtr<NavigatorUserMediaSuccessCallback> onsuccess(&aOnSuccess);
RefPtr<NavigatorUserMediaErrorCallback> onerror(&aOnError);
nsWeakPtr weakWindow = nsWeakPtr(do_GetWeakReference(mWindow));
@ -1250,23 +1250,23 @@ void Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints,
->Then(
GetMainThreadSerialEventTarget(), __func__,
[weakWindow, onsuccess = std::move(onsuccess)](
const RefPtr<DOMMediaStream>& aStream) {
const RefPtr<DOMMediaStream>& aStream) MOZ_CAN_RUN_SCRIPT {
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(weakWindow);
if (!window || !window->GetOuterWindow() ||
window->GetOuterWindow()->GetCurrentInnerWindow() != window) {
return; // Leave Promise pending after navigation by design.
}
MediaManager::CallOnSuccess(&onsuccess, *aStream);
MediaManager::CallOnSuccess(*onsuccess, *aStream);
},
[weakWindow,
onerror = std::move(onerror)](const RefPtr<MediaMgrError>& aError) {
[weakWindow, onerror = std::move(onerror)](
const RefPtr<MediaMgrError>& aError) MOZ_CAN_RUN_SCRIPT {
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(weakWindow);
if (!window || !window->GetOuterWindow() ||
window->GetOuterWindow()->GetCurrentInnerWindow() != window) {
return; // Leave Promise pending after navigation by design.
}
auto error = MakeRefPtr<MediaStreamError>(window, *aError);
MediaManager::CallOnError(&onerror, *error);
MediaManager::CallOnError(*onerror, *error);
});
}
@ -1281,9 +1281,10 @@ void Navigator::MozGetUserMediaDevices(
return;
}
MediaManager* manager = MediaManager::Get();
RefPtr<MediaManager> manager = MediaManager::Get();
// XXXbz aOnError seems to be unused?
aRv = manager->GetUserMediaDevices(mWindow, aConstraints, aOnSuccess,
nsCOMPtr<nsPIDOMWindowInner> window(mWindow);
aRv = manager->GetUserMediaDevices(window, aConstraints, aOnSuccess,
aInnerWindowID, aCallID);
}

Просмотреть файл

@ -186,6 +186,7 @@ class Navigator final : public nsISupports, public nsWrapperCache {
NavigatorUserMediaSuccessCallback& aOnSuccess,
NavigatorUserMediaErrorCallback& aOnError,
CallerType aCallerType, ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT
void MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints,
MozGetUserMediaDevicesSuccessCallback& aOnSuccess,
NavigatorUserMediaErrorCallback& aOnError,

Просмотреть файл

@ -90,7 +90,7 @@ uint32_t GetFlagsForEvents(
}
template <class TWrapped, class TUnwrapped>
void CallListeners(
MOZ_CAN_RUN_SCRIPT void CallListeners(
uint32_t aEventFlags, FlaggedArray<TWrapped>& aListeners,
const Sequence<OwningNonNull<PlacesEvent>>& aEvents,
const std::function<TUnwrapped(TWrapped&)>& aUnwrapListener,
@ -283,7 +283,12 @@ void PlacesObservers::NotifyListeners(
CallListeners<RefPtr<PlacesEventCallback>, RefPtr<PlacesEventCallback>>(
flags, *JSListeners::GetListeners(), aEvents, [](auto& cb) { return cb; },
[&](auto& cb, const auto& events) { cb->Call(aEvents); });
// MOZ_CAN_RUN_SCRIPT_BOUNDARY because on Windows this gets called from
// some internals of the std::function implementation that we can't
// annotate. We handle this by annotating CallListeners and making sure
// it holds a strong ref to the callback.
[&](auto& cb, const auto& events)
MOZ_CAN_RUN_SCRIPT_BOUNDARY { cb->Call(aEvents); });
CallListeners<WeakPtr<places::INativePlacesEventCallback>,
RefPtr<places::INativePlacesEventCallback>>(
@ -297,7 +302,14 @@ void PlacesObservers::NotifyListeners(
RefPtr<PlacesWeakCallbackWrapper>>(
flags, *WeakJSListeners::GetListeners(), aEvents,
[](auto& cb) { return cb.get(); },
[&](auto& cb, const auto& events) { cb->mCallback->Call(aEvents); });
// MOZ_CAN_RUN_SCRIPT_BOUNDARY because on Windows this gets called from
// some internals of the std::function implementation that we can't
// annotate. We handle this by annotating CallListeners and making sure
// it holds a strong ref to the callback.
[&](auto& cb, const auto& events) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
RefPtr<PlacesEventCallback> callback(cb->mCallback);
callback->Call(aEvents);
});
auto& listenersToRemove = *JSListeners::GetListenersToRemove();
if (listenersToRemove.Length() > 0) {

Просмотреть файл

@ -41,10 +41,12 @@ class PlacesObservers {
static void RemoveListener(const nsTArray<PlacesEventType>& aEventTypes,
places::INativePlacesEventCallback* aCallback);
MOZ_CAN_RUN_SCRIPT
static void NotifyListeners(
GlobalObject& aGlobal,
const Sequence<OwningNonNull<PlacesEvent>>& aEvents, ErrorResult& rv);
MOZ_CAN_RUN_SCRIPT
static void NotifyListeners(
const Sequence<OwningNonNull<PlacesEvent>>& aEvents);

Просмотреть файл

@ -221,8 +221,9 @@ void TimeoutExecutor::Cancel() {
mDeadline = TimeStamp();
}
NS_IMETHODIMP
TimeoutExecutor::Run() {
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP TimeoutExecutor::Run() {
// If the executor is canceled and then rescheduled its possible to get
// spurious executions here. Ignore these unless our current mode matches.
MOZ_LOG(gTimeoutLog, LogLevel::Debug,
@ -233,7 +234,9 @@ TimeoutExecutor::Run() {
return NS_OK;
}
NS_IMETHODIMP
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsITimerCallback::Notify is
// MOZ_CAN_RUN_SCRIPT.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
TimeoutExecutor::Notify(nsITimer* aTimer) {
// If the executor is canceled and then rescheduled its possible to get
// spurious executions here. Ignore these unless our current mode matches.

Просмотреть файл

@ -66,7 +66,7 @@ class TimeoutExecutor final : public nsIRunnable,
nsresult MaybeReschedule(const TimeStamp& aDeadline,
const TimeDuration& aMinDelay);
void MaybeExecute();
MOZ_CAN_RUN_SCRIPT void MaybeExecute();
public:
TimeoutExecutor(TimeoutManager* aOwner, bool aIsIdleQueue,

Просмотреть файл

@ -14,7 +14,7 @@ TimeoutHandler::TimeoutHandler(JSContext* aCx) : TimeoutHandler() {
nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo, &mColumn);
}
nsresult TimeoutHandler::Call() { return NS_OK; }
void TimeoutHandler::Call() {}
void TimeoutHandler::GetLocation(const char** aFileName, uint32_t* aLineNo,
uint32_t* aColumn) {

Просмотреть файл

@ -12,6 +12,7 @@
#include "nsITimeoutHandler.h"
#include "nsCycleCollectionParticipant.h"
#include "nsString.h"
#include "mozilla/Attributes.h"
namespace mozilla {
namespace dom {
@ -26,7 +27,7 @@ class TimeoutHandler : public nsITimeoutHandler {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(TimeoutHandler)
virtual nsresult Call() override;
MOZ_CAN_RUN_SCRIPT virtual void Call() override;
virtual void GetLocation(const char** aFileName, uint32_t* aLineNo,
uint32_t* aColumn) override;
virtual void MarkForCC() override {}

Просмотреть файл

@ -741,11 +741,10 @@ void TimeoutManager::RunTimeout(const TimeStamp& aNow,
// Make sure that the window and the script context don't go away as
// a result of running timeouts
nsCOMPtr<nsIScriptGlobalObject> windowKungFuDeathGrip(&mWindow);
// Silence the static analysis error about windowKungFuDeathGrip. Accessing
// members of mWindow here is safe, because the lifetime of TimeoutManager is
// the same as the lifetime of the containing nsGlobalWindow.
Unused << windowKungFuDeathGrip;
RefPtr<nsGlobalWindowInner> window(&mWindow);
// Accessing members of mWindow here is safe, because the lifetime of
// TimeoutManager is the same as the lifetime of the containing
// nsGlobalWindow.
// A native timer has gone off. See which of our timeouts need
// servicing
@ -976,8 +975,9 @@ void TimeoutManager::RunTimeout(const TimeStamp& aNow,
MOZ_ASSERT(timeout->mFiringIndex > mLastFiringIndex);
mLastFiringIndex = timeout->mFiringIndex;
#endif
// This timeout is good to run
bool timeout_was_cleared = mWindow.RunTimeoutHandler(timeout, scx);
// This timeout is good to run.
bool timeout_was_cleared =
window->RunTimeoutHandler(timeout, scx);
#if MOZ_GECKO_PROFILER
if (profiler_is_active()) {
TimeDuration elapsed = now - timeout->SubmitTime();

Просмотреть файл

@ -52,6 +52,7 @@ class TimeoutManager final {
bool aIsIdle);
// The timeout implementation functions.
MOZ_CAN_RUN_SCRIPT
void RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadline,
bool aProcessIdle);

Просмотреть файл

@ -536,6 +536,7 @@ void nsDOMMutationObserver::ScheduleForRun() {
class MutationObserverMicroTask final : public MicroTaskRunnable {
public:
MOZ_CAN_RUN_SCRIPT
virtual void Run(AutoSlowOperation& aAso) override {
nsDOMMutationObserver::HandleMutations(aAso);
}
@ -804,7 +805,8 @@ void nsDOMMutationObserver::HandleMutation() {
}
ClearPendingRecords();
mCallback->Call(this, mutations, *this);
RefPtr<dom::MutationCallback> callback(mCallback);
callback->Call(this, mutations, *this);
}
void nsDOMMutationObserver::HandleMutationsInternal(AutoSlowOperation& aAso) {

Просмотреть файл

@ -467,7 +467,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
void TakeRecords(nsTArray<RefPtr<nsDOMMutationRecord>>& aRetVal);
void HandleMutation();
MOZ_CAN_RUN_SCRIPT void HandleMutation();
void GetObservingInfo(
nsTArray<mozilla::dom::Nullable<MutationObservingInfo>>& aResult,
@ -514,6 +514,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
// static methods
static void QueueMutationObserverMicroTask();
MOZ_CAN_RUN_SCRIPT
static void HandleMutations(mozilla::AutoSlowOperation& aAso);
static bool AllScheduledMutationObserversAreSuppressed() {
@ -561,6 +562,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
return mOwner && nsGlobalWindowInner::Cast(mOwner)->IsInSyncOperation();
}
MOZ_CAN_RUN_SCRIPT
static void HandleMutationsInternal(mozilla::AutoSlowOperation& aAso);
static void AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver,

Просмотреть файл

@ -420,7 +420,7 @@ class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler {
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IdleRequestExecutorTimeoutHandler,
TimeoutHandler)
nsresult Call() override;
void Call() override;
private:
~IdleRequestExecutorTimeoutHandler() override {}
@ -530,13 +530,15 @@ IdleRequestExecutor::GetName(nsACString& aName) {
return NS_OK;
}
NS_IMETHODIMP
IdleRequestExecutor::Run() {
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsIRunnable::Run is MOZ_CAN_RUN_SCRIPT.
// See bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP IdleRequestExecutor::Run() {
MOZ_ASSERT(NS_IsMainThread());
mDispatched = false;
if (mWindow) {
return mWindow->ExecuteIdleRequest(mDeadline);
RefPtr<nsGlobalWindowInner> window(mWindow);
window->ExecuteIdleRequest(mDeadline);
}
return NS_OK;
@ -617,11 +619,10 @@ void IdleRequestExecutor::DelayedDispatch(uint32_t aDelay) {
mDelayedExecutorHandle = Some(handle);
}
nsresult IdleRequestExecutorTimeoutHandler::Call() {
void IdleRequestExecutorTimeoutHandler::Call() {
if (!mExecutor->IsCancelled()) {
mExecutor->ScheduleDispatch();
}
return NS_OK;
}
void nsGlobalWindowInner::ScheduleIdleRequestDispatch() {
@ -659,23 +660,25 @@ void nsGlobalWindowInner::RemoveIdleCallback(
aRequest->removeFrom(mIdleRequestCallbacks);
}
nsresult nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest,
DOMHighResTimeStamp aDeadline,
bool aDidTimeout) {
void nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest,
DOMHighResTimeStamp aDeadline,
bool aDidTimeout) {
AssertIsOnMainThread();
// XXXbz Do we still need this RefPtr? MOZ_CAN_RUN_SCRIPT should
// guarantee that caller is holding a strong ref on the stack.
RefPtr<IdleRequest> request(aRequest);
RemoveIdleCallback(request);
return request->IdleRun(this, aDeadline, aDidTimeout);
request->IdleRun(this, aDeadline, aDidTimeout);
}
nsresult nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
void nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
AssertIsOnMainThread();
RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
if (!request) {
// There are no more idle requests, so stop scheduling idle
// request callbacks.
return NS_OK;
return;
}
// If the request that we're trying to execute has been queued
@ -683,7 +686,7 @@ nsresult nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
// of the idle period.
if (mIdleRequestExecutor->IneligibleForCurrentIdlePeriod(request)) {
mIdleRequestExecutor->MaybeDispatch(aDeadline);
return NS_OK;
return;
}
DOMHighResTimeStamp deadline = 0.0;
@ -693,14 +696,13 @@ nsresult nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
}
mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit();
nsresult result = RunIdleRequest(request, deadline, false);
RunIdleRequest(request, deadline, false);
// Running the idle callback could've suspended the window, in which
// case mIdleRequestExecutor will be null.
if (mIdleRequestExecutor) {
mIdleRequestExecutor->MaybeDispatch();
}
return result;
}
class IdleRequestTimeoutHandler final : public TimeoutHandler {
@ -713,9 +715,10 @@ class IdleRequestTimeoutHandler final : public TimeoutHandler {
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IdleRequestTimeoutHandler,
TimeoutHandler)
nsresult Call() override {
return nsGlobalWindowInner::Cast(mWindow)->RunIdleRequest(mIdleRequest, 0.0,
true);
MOZ_CAN_RUN_SCRIPT void Call() override {
RefPtr<nsGlobalWindowInner> window(nsGlobalWindowInner::Cast(mWindow));
RefPtr<IdleRequest> request(mIdleRequest);
window->RunIdleRequest(request, 0.0, true);
}
private:
@ -5559,6 +5562,8 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout,
nsIScriptContext* aScx) {
// Hold on to the timeout in case mExpr or mFunObj releases its
// doc.
// XXXbz Our caller guarantees it'll hold on to the timeout (because
// we're MOZ_CAN_RUN_SCRIPT), so we can probably stop doing that...
RefPtr<Timeout> timeout = aTimeout;
Timeout* last_running_timeout = mTimeoutManager->BeginRunningTimeout(timeout);
timeout->mRunning = true;
@ -7012,7 +7017,7 @@ void nsPIDOMWindowInner::BroadcastReport(Report* aReport) {
void nsPIDOMWindowInner::NotifyReportingObservers() {
nsTArray<RefPtr<ReportingObserver>> reportingObservers(mReportingObservers);
for (ReportingObserver* observer : reportingObservers) {
for (RefPtr<ReportingObserver>& observer : reportingObservers) {
observer->MaybeNotify();
}
}

Просмотреть файл

@ -1053,6 +1053,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
mozilla::ErrorResult& aError);
// Return true if |aTimeout| was cleared while its handler ran.
MOZ_CAN_RUN_SCRIPT
bool RunTimeoutHandler(mozilla::dom::Timeout* aTimeout,
nsIScriptContext* aScx);
@ -1196,9 +1197,11 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
uint32_t LastIdleRequestHandle() const {
return mIdleRequestCallbackCounter - 1;
}
nsresult RunIdleRequest(mozilla::dom::IdleRequest* aRequest,
DOMHighResTimeStamp aDeadline, bool aDidTimeout);
nsresult ExecuteIdleRequest(TimeStamp aDeadline);
MOZ_CAN_RUN_SCRIPT
void RunIdleRequest(mozilla::dom::IdleRequest* aRequest,
DOMHighResTimeStamp aDeadline, bool aDidTimeout);
MOZ_CAN_RUN_SCRIPT
void ExecuteIdleRequest(TimeStamp aDeadline);
void ScheduleIdleRequestDispatch();
void SuspendIdleRequests();
void ResumeIdleRequests();

Просмотреть файл

@ -1638,6 +1638,7 @@ class nsINode : public mozilla::dom::EventTarget {
void GenerateXPath(nsAString& aResult);
MOZ_CAN_RUN_SCRIPT
already_AddRefed<mozilla::dom::Promise> Localize(
JSContext* aCx, mozilla::dom::L10nCallback& aCallback,
mozilla::ErrorResult& aRv);

Просмотреть файл

@ -7,6 +7,7 @@
#define nsITimeoutHandler_h___
#include "nsISupports.h"
#include "mozilla/Attributes.h"
#define NS_ITIMEOUTHANDLER_IID \
{ \
@ -19,7 +20,7 @@ class nsITimeoutHandler : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITIMEOUTHANDLER_IID)
virtual nsresult Call() = 0;
MOZ_CAN_RUN_SCRIPT virtual void Call() = 0;
virtual void GetLocation(const char** aFileName, uint32_t* aLineNo,
uint32_t* aColumn) = 0;

Просмотреть файл

@ -57,7 +57,7 @@ class nsJSScriptTimeoutHandler final : public nsIScriptTimeoutHandler {
virtual const nsTArray<JS::Value>& GetArgs() override { return mArgs; }
virtual nsresult Call() override { return NS_OK; }
virtual void Call() override {}
virtual void GetLocation(const char** aFileName, uint32_t* aLineNo,
uint32_t* aColumn) override {

Просмотреть файл

@ -555,7 +555,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
void BroadcastReport(mozilla::dom::Report* aReport);
void NotifyReportingObservers();
MOZ_CAN_RUN_SCRIPT void NotifyReportingObservers();
void SaveStorageAccessGranted(const nsACString& aPermissionKey);

Просмотреть файл

@ -312,7 +312,7 @@ class CallbackObject : public nsISupports {
const char* aExecutionReason,
ExceptionHandling aExceptionHandling, JS::Realm* aRealm = nullptr,
bool aIsJSImplementedWebIDL = false);
~CallSetup();
MOZ_CAN_RUN_SCRIPT ~CallSetup();
JSContext* GetContext() const { return mCx; }

Просмотреть файл

@ -31,16 +31,18 @@ void CanvasRenderingContextHelper::ToBlob(
: mGlobal(aGlobal), mBlobCallback(aCallback) {}
// This is called on main thread.
MOZ_CAN_RUN_SCRIPT
nsresult ReceiveBlob(already_AddRefed<Blob> aBlob) override {
RefPtr<Blob> blob = aBlob;
RefPtr<Blob> newBlob = Blob::Create(mGlobal, blob->Impl());
RefPtr<BlobCallback> callback(mBlobCallback.forget());
ErrorResult rv;
mBlobCallback->Call(newBlob, rv);
callback->Call(newBlob, rv);
mGlobal = nullptr;
mBlobCallback = nullptr;
MOZ_ASSERT(!mBlobCallback);
return rv.StealNSResult();
}

Просмотреть файл

@ -4,7 +4,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback PlacesEventCallback = void (sequence<PlacesEvent> events);
[ChromeOnly, Exposed=Window,

Просмотреть файл

@ -8,7 +8,6 @@ interface nsISupports;
/**
* A callback passed to SessionStoreUtils.forEachNonDynamicChildFrame().
*/
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback SessionStoreUtilsFrameCallback = void (WindowProxy frame, unsigned long index);
/**

Просмотреть файл

@ -5,7 +5,6 @@
interface URI;
interface WindowProxy;
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback WebExtensionLocalizeCallback = DOMString (DOMString unlocalizedText);
/**

Просмотреть файл

@ -445,8 +445,7 @@ class ConsoleRunnable : public StructuredCloneHolderBase {
return true;
}
void ProcessProfileData(JSContext* aCx, Console* aConsole,
Console::MethodName aMethodName,
void ProcessProfileData(JSContext* aCx, Console::MethodName aMethodName,
const nsAString& aAction) {
AssertIsOnMainThread();
@ -485,7 +484,7 @@ class ConsoleRunnable : public StructuredCloneHolderBase {
}
}
aConsole->ProfileMethodInternal(aCx, aMethodName, aAction, arguments);
Console::ProfileMethodMainthread(aCx, aAction, arguments);
}
ConsoleStructuredCloneData mClonedData;
@ -634,7 +633,7 @@ class ConsoleWorkerRunnable : public WorkerProxyToMainThreadRunnable,
wp = wp->GetParent();
}
nsPIDOMWindowInner* window = wp->GetWindow();
nsCOMPtr<nsPIDOMWindowInner> window = wp->GetWindow();
if (!window) {
RunWindowless(aWorkerPrivate);
} else {
@ -655,7 +654,7 @@ class ConsoleWorkerRunnable : public WorkerProxyToMainThreadRunnable,
return;
}
nsPIDOMWindowOuter* outerWindow = aWindow->GetOuterWindow();
nsCOMPtr<nsPIDOMWindowOuter> outerWindow = aWindow->GetOuterWindow();
if (NS_WARN_IF(!outerWindow)) {
return;
}
@ -834,8 +833,7 @@ class ConsoleProfileWorkletRunnable final : public ConsoleWorkletRunnable {
// We don't need to set a parent object in mCallData bacause there are not
// DOM objects exposed to worklet.
ProcessProfileData(cx, mConsole, mName, mAction);
ProcessProfileData(cx, mName, mAction);
}
virtual void ReleaseData() override {}
@ -870,7 +868,7 @@ class ConsoleProfileWorkerRunnable final : public ConsoleWorkerRunnable {
// Now we could have the correct window (if we are not window-less).
mClonedData.mParent = aInnerWindow;
ProcessProfileData(aCx, mConsole, mName, mAction);
ProcessProfileData(aCx, mName, mAction);
mClonedData.mParent = nullptr;
}
@ -1267,6 +1265,13 @@ void Console::ProfileMethodInternal(JSContext* aCx, MethodName aMethodName,
return;
}
ProfileMethodMainthread(aCx, aAction, aData);
}
// static
void Console::ProfileMethodMainthread(JSContext* aCx, const nsAString& aAction,
const Sequence<JS::Value>& aData) {
MOZ_ASSERT(NS_IsMainThread());
ConsoleCommon::ClearException ce(aCx);
RootedDictionary<ConsoleProfileEvent> event(aCx);
@ -2517,7 +2522,8 @@ void Console::NotifyHandler(JSContext* aCx,
}
JS::Rooted<JS::Value> ignored(aCx);
mConsoleEventNotifier->Call(value, &ignored);
RefPtr<AnyCallback> notifier(mConsoleEventNotifier);
notifier->Call(value, &ignored);
}
void Console::RetrieveConsoleEvents(JSContext* aCx,
@ -2850,7 +2856,8 @@ void Console::MaybeExecuteDumpFunctionForTime(JSContext* aCx,
void Console::ExecuteDumpFunction(const nsAString& aMessage) {
if (mDumpFunction) {
mDumpFunction->Call(aMessage);
RefPtr<ConsoleInstanceDumpCallback> dumpFunction(mDumpFunction);
dumpFunction->Call(aMessage);
return;
}

Просмотреть файл

@ -49,67 +49,90 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
uint64_t aInnerWindowID,
ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT
static void Log(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Info(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Warn(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Error(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Exception(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Debug(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Table(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Trace(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Dir(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Dirxml(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Group(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void GroupCollapsed(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void GroupEnd(const GlobalObject& aGlobal);
MOZ_CAN_RUN_SCRIPT
static void Time(const GlobalObject& aGlobal, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
static void TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
static void TimeStamp(const GlobalObject& aGlobal,
const JS::Handle<JS::Value> aData);
MOZ_CAN_RUN_SCRIPT
static void Profile(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void ProfileEnd(const GlobalObject& aGlobal,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Assert(const GlobalObject& aGlobal, bool aCondition,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Count(const GlobalObject& aGlobal, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
static void CountReset(const GlobalObject& aGlobal, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
static void Clear(const GlobalObject& aGlobal);
static already_AddRefed<ConsoleInstance> CreateInstance(
@ -162,27 +185,38 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
static already_AddRefed<Console> GetConsoleInternal(
const GlobalObject& aGlobal, ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT
static void ProfileMethod(const GlobalObject& aGlobal, MethodName aName,
const nsAString& aAction,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void ProfileMethodInternal(JSContext* aCx, MethodName aName,
const nsAString& aAction,
const Sequence<JS::Value>& aData);
// Implementation of the mainthread-only parts of ProfileMethod.
// This is indepedent of console instance state.
static void ProfileMethodMainthread(JSContext* aCx, const nsAString& aAction,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void Method(const GlobalObject& aGlobal, MethodName aName,
const nsAString& aString,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void MethodInternal(JSContext* aCx, MethodName aName,
const nsAString& aString,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
static void StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
const Sequence<JS::Value>& aData,
MethodName aMethodName,
const nsAString& aMethodString);
MOZ_CAN_RUN_SCRIPT
void StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
const Sequence<JS::Value>& aData,
MethodName aMethodName,
@ -200,6 +234,7 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
void ReleaseCallData(ConsoleCallData* aCallData);
// aCx and aArguments must be in the same JS compartment.
MOZ_CAN_RUN_SCRIPT
void NotifyHandler(JSContext* aCx, const Sequence<JS::Value>& aArguments,
ConsoleCallData* aData);
@ -370,15 +405,18 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
const Sequence<JS::Value>& aData,
DOMHighResTimeStamp* aTimeStamp);
MOZ_CAN_RUN_SCRIPT
void MaybeExecuteDumpFunction(JSContext* aCx, const nsAString& aMethodName,
const Sequence<JS::Value>& aData,
nsIStackFrame* aStack);
MOZ_CAN_RUN_SCRIPT
void MaybeExecuteDumpFunctionForTime(JSContext* aCx, MethodName aMethodName,
const nsAString& aMethodString,
uint64_t aMonotonicTimer,
const JS::Value& aData);
MOZ_CAN_RUN_SCRIPT
void ExecuteDumpFunction(const nsAString& aMessage);
bool IsEnabled(JSContext* aCx) const;

Просмотреть файл

@ -109,8 +109,9 @@ JSObject* ConsoleInstance::WrapObject(JSContext* aCx,
#define METHOD(name, string) \
void ConsoleInstance::name(JSContext* aCx, \
const Sequence<JS::Value>& aData) { \
mConsole->MethodInternal(aCx, Console::Method##name, \
NS_LITERAL_STRING(string), aData); \
RefPtr<Console> console(mConsole); \
console->MethodInternal(aCx, Console::Method##name, \
NS_LITERAL_STRING(string), aData); \
}
METHOD(Log, "log")
@ -130,26 +131,29 @@ METHOD(GroupCollapsed, "groupCollapsed")
void ConsoleInstance::GroupEnd(JSContext* aCx) {
const Sequence<JS::Value> data;
mConsole->MethodInternal(aCx, Console::MethodGroupEnd,
NS_LITERAL_STRING("groupEnd"), data);
RefPtr<Console> console(mConsole);
console->MethodInternal(aCx, Console::MethodGroupEnd,
NS_LITERAL_STRING("groupEnd"), data);
}
void ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel) {
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodTime,
NS_LITERAL_STRING("time"));
RefPtr<Console> console(mConsole);
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodTime, NS_LITERAL_STRING("time"));
}
void ConsoleInstance::TimeLog(JSContext* aCx, const nsAString& aLabel,
const Sequence<JS::Value>& aData) {
mConsole->StringMethodInternal(aCx, aLabel, aData, Console::MethodTimeLog,
NS_LITERAL_STRING("timeLog"));
RefPtr<Console> console(mConsole);
console->StringMethodInternal(aCx, aLabel, aData, Console::MethodTimeLog,
NS_LITERAL_STRING("timeLog"));
}
void ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel) {
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodTimeEnd,
NS_LITERAL_STRING("timeEnd"));
RefPtr<Console> console(mConsole);
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodTimeEnd,
NS_LITERAL_STRING("timeEnd"));
}
void ConsoleInstance::TimeStamp(JSContext* aCx,
@ -163,46 +167,53 @@ void ConsoleInstance::TimeStamp(JSContext* aCx,
return;
}
mConsole->MethodInternal(aCx, Console::MethodTimeStamp,
NS_LITERAL_STRING("timeStamp"), data);
RefPtr<Console> console(mConsole);
console->MethodInternal(aCx, Console::MethodTimeStamp,
NS_LITERAL_STRING("timeStamp"), data);
}
void ConsoleInstance::Profile(JSContext* aCx,
const Sequence<JS::Value>& aData) {
mConsole->ProfileMethodInternal(aCx, Console::MethodProfile,
NS_LITERAL_STRING("profile"), aData);
RefPtr<Console> console(mConsole);
console->ProfileMethodInternal(aCx, Console::MethodProfile,
NS_LITERAL_STRING("profile"), aData);
}
void ConsoleInstance::ProfileEnd(JSContext* aCx,
const Sequence<JS::Value>& aData) {
mConsole->ProfileMethodInternal(aCx, Console::MethodProfileEnd,
NS_LITERAL_STRING("profileEnd"), aData);
RefPtr<Console> console(mConsole);
console->ProfileMethodInternal(aCx, Console::MethodProfileEnd,
NS_LITERAL_STRING("profileEnd"), aData);
}
void ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
const Sequence<JS::Value>& aData) {
if (!aCondition) {
mConsole->MethodInternal(aCx, Console::MethodAssert,
NS_LITERAL_STRING("assert"), aData);
RefPtr<Console> console(mConsole);
console->MethodInternal(aCx, Console::MethodAssert,
NS_LITERAL_STRING("assert"), aData);
}
}
void ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel) {
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodCount,
NS_LITERAL_STRING("count"));
RefPtr<Console> console(mConsole);
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodCount,
NS_LITERAL_STRING("count"));
}
void ConsoleInstance::CountReset(JSContext* aCx, const nsAString& aLabel) {
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodCountReset,
NS_LITERAL_STRING("countReset"));
RefPtr<Console> console(mConsole);
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
Console::MethodCountReset,
NS_LITERAL_STRING("countReset"));
}
void ConsoleInstance::Clear(JSContext* aCx) {
const Sequence<JS::Value> data;
mConsole->MethodInternal(aCx, Console::MethodClear,
NS_LITERAL_STRING("clear"), data);
RefPtr<Console> console(mConsole);
console->MethodInternal(aCx, Console::MethodClear, NS_LITERAL_STRING("clear"),
data);
}
void ConsoleInstance::ReportForServiceWorkerScope(const nsAString& aScope,

Просмотреть файл

@ -26,52 +26,75 @@ class ConsoleInstance final : public nsISupports, public nsWrapperCache {
nsPIDOMWindowInner* GetParentObject() const { return nullptr; }
MOZ_CAN_RUN_SCRIPT
void Log(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Info(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Warn(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Error(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Exception(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Debug(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Table(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Trace(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Dir(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Dirxml(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Group(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void GroupCollapsed(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void GroupEnd(JSContext* aCx);
MOZ_CAN_RUN_SCRIPT
void Time(JSContext* aCx, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
void TimeLog(JSContext* aCx, const nsAString& aLabel,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void TimeEnd(JSContext* aCx, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
void TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData);
MOZ_CAN_RUN_SCRIPT
void Profile(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Assert(JSContext* aCx, bool aCondition,
const Sequence<JS::Value>& aData);
MOZ_CAN_RUN_SCRIPT
void Count(JSContext* aCx, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
void CountReset(JSContext* aCx, const nsAString& aLabel);
MOZ_CAN_RUN_SCRIPT
void Clear(JSContext* aCx);
// For testing only.

Просмотреть файл

@ -7,6 +7,7 @@
#include "DataTransferItem.h"
#include "DataTransferItemList.h"
#include "mozilla/Attributes.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/EventForwards.h"
#include "mozilla/dom/DataTransferItemBinding.h"
@ -430,15 +431,19 @@ void DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
mCallback(aCallback),
mStringData(aStringData) {}
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until runnables are opted into
// MOZ_CAN_RUN_SCRIPT. See bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
NS_IMETHOD Run() override {
ErrorResult rv;
mCallback->Call(mStringData, rv);
// mCallback is const, so we never null it out until our destructor.
MOZ_KnownLive(mCallback)->Call(mStringData, rv);
NS_WARNING_ASSERTION(!rv.Failed(), "callback failed");
return rv.StealNSResult();
}
private:
RefPtr<FunctionStringCallback> mCallback;
const RefPtr<FunctionStringCallback> mCallback;
nsString mStringData;
};

Просмотреть файл

@ -154,8 +154,8 @@ nsresult JSEventHandler::HandleEvent(Event* aEvent) {
mTypedHandler.OnErrorEventHandler();
ErrorResult rv;
JS::Rooted<JS::Value> retval(RootingCx());
handler->Call(mTarget, msgOrEvent, fileName, lineNumber, columnNumber,
error, &retval, rv);
handler->Call(target, msgOrEvent, fileName, lineNumber, columnNumber, error,
&retval, rv);
if (rv.Failed()) {
return rv.StealNSResult();
}
@ -173,7 +173,7 @@ nsresult JSEventHandler::HandleEvent(Event* aEvent) {
mTypedHandler.OnBeforeUnloadEventHandler();
ErrorResult rv;
nsString retval;
handler->Call(mTarget, *aEvent, retval, rv);
handler->Call(target, *aEvent, retval, rv);
if (rv.Failed()) {
return rv.StealNSResult();
}
@ -202,7 +202,7 @@ nsresult JSEventHandler::HandleEvent(Event* aEvent) {
ErrorResult rv;
RefPtr<EventHandlerNonNull> handler = mTypedHandler.NormalEventHandler();
JS::Rooted<JS::Value> retval(RootingCx());
handler->Call(mTarget, *aEvent, &retval, rv);
handler->Call(target, *aEvent, &retval, rv);
if (rv.Failed()) {
return rv.StealNSResult();
}

Просмотреть файл

@ -33,7 +33,9 @@ EntryCallbackRunnable::EntryCallbackRunnable(FileSystemEntryCallback* aCallback,
NS_IMETHODIMP
EntryCallbackRunnable::Run() {
mCallback->Call(*mEntry);
// Both of our strongly held members never change (they're const), so we can
// use MOZ_KnownLive on them.
MOZ_KnownLive(mCallback)->Call(MOZ_KnownLive(*mEntry));
return NS_OK;
}
@ -52,7 +54,8 @@ ErrorCallbackRunnable::ErrorCallbackRunnable(nsIGlobalObject* aGlobalObject,
NS_IMETHODIMP
ErrorCallbackRunnable::Run() {
RefPtr<DOMException> exception = DOMException::Create(mError);
mCallback->Call(*exception);
// mCallback never changes (it's const) so MOZ_KnownLive is ok.
MOZ_KnownLive(mCallback)->Call(*exception);
return NS_OK;
}
@ -65,7 +68,8 @@ EmptyEntriesCallbackRunnable::EmptyEntriesCallbackRunnable(
NS_IMETHODIMP
EmptyEntriesCallbackRunnable::Run() {
Sequence<OwningNonNull<FileSystemEntry>> sequence;
mCallback->Call(sequence);
// mCallback never changes (it's const), so MOZ_KnownLive is ok.
MOZ_KnownLive(mCallback)->Call(sequence);
return NS_OK;
}
@ -188,7 +192,8 @@ void GetEntryHelper::CompleteOperation(JSObject* aObj) {
RefPtr<FileSystemFileEntry> entry = new FileSystemFileEntry(
mParentEntry->GetParentObject(), file, mParentEntry, mFileSystem);
mSuccessCallback->Call(*entry);
// mSuccessCallback never changes (it's const), so MOZ_KnownLive is ok.
MOZ_KnownLive(mSuccessCallback)->Call(*entry);
return;
}
@ -202,7 +207,8 @@ void GetEntryHelper::CompleteOperation(JSObject* aObj) {
RefPtr<FileSystemDirectoryEntry> entry = new FileSystemDirectoryEntry(
mParentEntry->GetParentObject(), directory, mParentEntry, mFileSystem);
mSuccessCallback->Call(*entry);
// mSuccessCallback never changes (it's const), so MOZ_KnownLive is ok.
MOZ_KnownLive(mSuccessCallback)->Call(*entry);
}
void GetEntryHelper::ContinueRunning(JSObject* aObj) {

Просмотреть файл

@ -23,12 +23,13 @@ class EntryCallbackRunnable final : public Runnable {
EntryCallbackRunnable(FileSystemEntryCallback* aCallback,
FileSystemEntry* aEntry);
NS_IMETHOD
Run() override;
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override;
private:
RefPtr<FileSystemEntryCallback> mCallback;
RefPtr<FileSystemEntry> mEntry;
const RefPtr<FileSystemEntryCallback> mCallback;
const RefPtr<FileSystemEntry> mEntry;
};
class ErrorCallbackRunnable final : public Runnable {
@ -36,12 +37,13 @@ class ErrorCallbackRunnable final : public Runnable {
ErrorCallbackRunnable(nsIGlobalObject* aGlobalObject,
ErrorCallback* aCallback, nsresult aError);
NS_IMETHOD
Run() override;
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override;
private:
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ErrorCallback> mCallback;
const RefPtr<ErrorCallback> mCallback;
nsresult mError;
};
@ -49,11 +51,12 @@ class EmptyEntriesCallbackRunnable final : public Runnable {
public:
explicit EmptyEntriesCallbackRunnable(FileSystemEntriesCallback* aCallback);
NS_IMETHOD
Run() override;
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override;
private:
RefPtr<FileSystemEntriesCallback> mCallback;
const RefPtr<FileSystemEntriesCallback> mCallback;
};
class GetEntryHelper final : public PromiseNativeHandler {
@ -68,6 +71,7 @@ class GetEntryHelper final : public PromiseNativeHandler {
void Run();
MOZ_CAN_RUN_SCRIPT
virtual void ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) override;
@ -81,14 +85,14 @@ class GetEntryHelper final : public PromiseNativeHandler {
void ContinueRunning(JSObject* aObj);
void CompleteOperation(JSObject* aObj);
MOZ_CAN_RUN_SCRIPT void CompleteOperation(JSObject* aObj);
RefPtr<FileSystemDirectoryEntry> mParentEntry;
RefPtr<Directory> mDirectory;
nsTArray<nsString> mParts;
RefPtr<FileSystem> mFileSystem;
RefPtr<FileSystemEntryCallback> mSuccessCallback;
const RefPtr<FileSystemEntryCallback> mSuccessCallback;
RefPtr<ErrorCallback> mErrorCallback;
FileSystemDirectoryEntry::GetInternalType mType;

Просмотреть файл

@ -36,6 +36,7 @@ class PromiseHandler final : public PromiseNativeHandler {
MOZ_ASSERT(aSuccessCallback);
}
MOZ_CAN_RUN_SCRIPT
virtual void ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) override {
if (NS_WARN_IF(!aValue.isObject())) {
@ -86,7 +87,8 @@ class PromiseHandler final : public PromiseNativeHandler {
sequence[i] = entry;
}
mSuccessCallback->Call(sequence);
// mSuccessCallback never changes (it's const), so MOZ_KnownLive is ok.
MOZ_KnownLive(mSuccessCallback)->Call(sequence);
}
virtual void RejectedCallback(JSContext* aCx,
@ -106,7 +108,7 @@ class PromiseHandler final : public PromiseNativeHandler {
RefPtr<FileSystemDirectoryEntry> mParentEntry;
RefPtr<FileSystem> mFileSystem;
RefPtr<FileSystemEntriesCallback> mSuccessCallback;
const RefPtr<FileSystemEntriesCallback> mSuccessCallback;
RefPtr<ErrorCallback> mErrorCallback;
};

Просмотреть файл

@ -24,19 +24,21 @@ class FileCallbackRunnable final : public Runnable {
MOZ_ASSERT(aFile);
}
NS_IMETHOD
Run() override {
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
// Here we clone the File object.
RefPtr<File> file = File::Create(mFile->GetParentObject(), mFile->Impl());
MOZ_ASSERT(file);
mCallback->Call(*file);
// mCallback never changes (it's const) so MOZ_KnownLive is ok.
MOZ_KnownLive(mCallback)->Call(*file);
return NS_OK;
}
private:
RefPtr<FileCallback> mCallback;
const RefPtr<FileCallback> mCallback;
RefPtr<File> mFile;
};

Просмотреть файл

@ -24,8 +24,9 @@ class EntriesCallbackRunnable final : public Runnable {
MOZ_ASSERT(aCallback);
}
NS_IMETHOD
Run() override {
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
Sequence<OwningNonNull<FileSystemEntry>> entries;
for (uint32_t i = 0; i < mEntries.Length(); ++i) {
if (!entries.AppendElement(mEntries[i].forget(), fallible)) {
@ -33,12 +34,13 @@ class EntriesCallbackRunnable final : public Runnable {
}
}
mCallback->Call(entries);
// mCallback never changes (it's const), so MOZ_KnownLive is ok.
MOZ_KnownLive(mCallback)->Call(entries);
return NS_OK;
}
private:
RefPtr<FileSystemEntriesCallback> mCallback;
const RefPtr<FileSystemEntriesCallback> mCallback;
Sequence<RefPtr<FileSystemEntry>> mEntries;
};

Просмотреть файл

@ -492,9 +492,11 @@ nsresult HTMLCanvasElement::DispatchPrintCallback(nsITimerCallback* aCallback) {
return OwnerDoc()->Dispatch(TaskCategory::Other, renderEvent.forget());
}
MOZ_CAN_RUN_SCRIPT
void HTMLCanvasElement::CallPrintCallback() {
ErrorResult rv;
GetMozPrintCallback()->Call(*mPrintState, rv);
RefPtr<PrintCallback> callback = GetMozPrintCallback();
RefPtr<HTMLCanvasPrintState> state = mPrintState;
callback->Call(*state);
}
void HTMLCanvasElement::ResetPrintCallback() {

Просмотреть файл

@ -3009,7 +3009,7 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
// We know prefs are ASCII here.
NS_LossyConvertUTF16toASCII strData(aData);
Pref pref(strData, /* isLocked */ false, null_t(), null_t());
Pref pref(strData, /* isLocked */ false, Nothing(), Nothing());
Preferences::GetPreference(&pref);
if (IsAlive()) {
MOZ_ASSERT(mQueuedPrefs.IsEmpty());

Просмотреть файл

@ -112,12 +112,6 @@ struct WebProgressData
uint64_t DOMWindowID;
};
union OptionalWebProgressData
{
void_t;
WebProgressData;
};
struct RequestData
{
nsIURI requestURI;
@ -125,12 +119,6 @@ struct RequestData
nsCString matchedList;
};
union OptionalShmem
{
void_t;
Shmem;
};
nested(upto inside_cpow) sync protocol PBrowser
{
manager PContent;
@ -550,7 +538,7 @@ parent:
async RegisterProtocolHandler(nsString scheme, nsIURI handlerURI, nsString title,
nsIURI documentURI);
async OnContentBlockingEvent(OptionalWebProgressData aWebProgressData,
async OnContentBlockingEvent(WebProgressData? aWebProgressData,
RequestData aRequestData, uint32_t aEvent);
child:
@ -594,7 +582,7 @@ parent:
nested(inside_sync) sync DispatchKeyboardEvent(WidgetKeyboardEvent event);
async InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action,
OptionalShmem visualData,
Shmem? visualData,
uint32_t stride, SurfaceFormat format,
LayoutDeviceIntRect dragRect,
Principal principal);

Просмотреть файл

@ -14,11 +14,6 @@ union PrefValue {
bool;
};
union MaybePrefValue {
PrefValue;
null_t;
};
// This serialization form mirrors that used in mozilla::Pref in
// Preferences.cpp. The two should be kept in sync, e.g. if something is added
// to one it should also be added to the other.
@ -28,8 +23,8 @@ union MaybePrefValue {
struct Pref {
nsCString name;
bool isLocked;
MaybePrefValue defaultValue;
MaybePrefValue userValue;
PrefValue? defaultValue;
PrefValue? userValue;
};
} // namespace dom

Просмотреть файл

@ -3311,11 +3311,13 @@ NS_IMETHODIMP TabChild::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
nsresult rv = PrepareProgressListenerData(aWebProgress, aRequest,
webProgressData, requestData);
NS_ENSURE_SUCCESS(rv, rv);
Maybe<WebProgressData> maybeWebProgressData;
if (aWebProgress) {
Unused << SendOnContentBlockingEvent(webProgressData, requestData, aEvent);
} else {
Unused << SendOnContentBlockingEvent(void_t(), requestData, aEvent);
maybeWebProgressData.emplace(webProgressData);
}
Unused << SendOnContentBlockingEvent(maybeWebProgressData, requestData,
aEvent);
return NS_OK;
}

Просмотреть файл

@ -2210,26 +2210,24 @@ mozilla::ipc::IPCResult TabParent::RecvRegisterProtocolHandler(
}
mozilla::ipc::IPCResult TabParent::RecvOnContentBlockingEvent(
const OptionalWebProgressData& aWebProgressData,
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const uint32_t& aEvent) {
nsCOMPtr<nsIBrowser> browser =
mFrameElement ? mFrameElement->AsBrowser() : nullptr;
if (browser) {
MOZ_ASSERT(aWebProgressData.type() != OptionalWebProgressData::T__None);
if (aWebProgressData.type() == OptionalWebProgressData::Tvoid_t) {
if (aWebProgressData.isNothing()) {
Unused << browser->CallWebProgressContentBlockingEventListeners(
false, false, false, 0, 0, aRequestData.requestURI(),
aRequestData.originalRequestURI(), aRequestData.matchedList(),
aEvent);
} else {
Unused << browser->CallWebProgressContentBlockingEventListeners(
true, aWebProgressData.get_WebProgressData().isTopLevel(),
aWebProgressData.get_WebProgressData().isLoadingDocument(),
aWebProgressData.get_WebProgressData().loadType(),
aWebProgressData.get_WebProgressData().DOMWindowID(),
aRequestData.requestURI(), aRequestData.originalRequestURI(),
aRequestData.matchedList(), aEvent);
true, aWebProgressData.ref().isTopLevel(),
aWebProgressData.ref().isLoadingDocument(),
aWebProgressData.ref().loadType(),
aWebProgressData.ref().DOMWindowID(), aRequestData.requestURI(),
aRequestData.originalRequestURI(), aRequestData.matchedList(),
aEvent);
}
}
@ -3301,7 +3299,7 @@ mozilla::ipc::IPCResult TabParent::RecvAsyncAuthPrompt(
mozilla::ipc::IPCResult TabParent::RecvInvokeDragSession(
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction,
const OptionalShmem& aVisualDnDData, const uint32_t& aStride,
Maybe<Shmem>&& aVisualDnDData, const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
const IPC::Principal& aPrincipal) {
mInitialDataTransferItems.Clear();
@ -3326,14 +3324,13 @@ mozilla::ipc::IPCResult TabParent::RecvInvokeDragSession(
dragService->MaybeAddChildProcess(Manager());
}
if (aVisualDnDData.type() == OptionalShmem::Tvoid_t ||
!aVisualDnDData.get_Shmem().IsReadable() ||
aVisualDnDData.get_Shmem().Size<char>() < aDragRect.height * aStride) {
if (aVisualDnDData.isNothing() || !aVisualDnDData.ref().IsReadable() ||
aVisualDnDData.ref().Size<char>() < aDragRect.height * aStride) {
mDnDVisualization = nullptr;
} else {
mDnDVisualization = gfx::CreateDataSourceSurfaceFromData(
gfx::IntSize(aDragRect.width, aDragRect.height), aFormat,
aVisualDnDData.get_Shmem().get<uint8_t>(), aStride);
aVisualDnDData.ref().get<uint8_t>(), aStride);
}
mDragValid = true;
@ -3342,8 +3339,8 @@ mozilla::ipc::IPCResult TabParent::RecvInvokeDragSession(
esm->BeginTrackingRemoteDragGesture(mFrameElement);
if (aVisualDnDData.type() == OptionalShmem::TShmem) {
Unused << DeallocShmem(aVisualDnDData);
if (aVisualDnDData.isSome()) {
Unused << DeallocShmem(aVisualDnDData.ref());
}
return IPC_OK();

Просмотреть файл

@ -166,7 +166,7 @@ class TabParent final : public PBrowserParent,
nsIURI* aDocURI);
mozilla::ipc::IPCResult RecvOnContentBlockingEvent(
const OptionalWebProgressData& aWebProgressData,
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const uint32_t& aEvent);
mozilla::ipc::IPCResult RecvBrowserFrameOpenWindow(
@ -572,7 +572,7 @@ class TabParent final : public PBrowserParent,
mozilla::ipc::IPCResult RecvInvokeDragSession(
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction,
const OptionalShmem& aVisualDnDData, const uint32_t& aStride,
Maybe<Shmem>&& aVisualDnDData, const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
const IPC::Principal& aPrincipal);

Просмотреть файл

@ -121,115 +121,6 @@ std::map<MediaDecoderOwnerID, GPUProcessCrashTelemetryLogger::GPUCrashData>
GPUProcessCrashTelemetryLogger::sGPUCrashDataMap;
StaticMutex GPUProcessCrashTelemetryLogger::sGPUCrashMapMutex;
/**
* This class addresses the concern of bug 1339310 comment 4 where the Widevine
* CDM doesn't support running multiple instances of a video decoder at once per
* CDM instance by sequencing the order of decoder creation and shutdown. Note
* this class addresses a different concern from that of GlobalAllocPolicy which
* controls a system-wide number of decoders while this class control a per-MFR
* number (which is one per CDM requirement).
*/
class LocalAllocPolicy {
using TrackType = TrackInfo::TrackType;
using Promise = GlobalAllocPolicy::Promise;
using Token = GlobalAllocPolicy::Token;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LocalAllocPolicy)
public:
LocalAllocPolicy(TrackType aTrack, TaskQueue* aOwnerThread)
: mTrack(aTrack), mOwnerThread(aOwnerThread) {}
// Acquire a token for decoder creation. Note the resolved token will
// aggregate a GlobalAllocPolicy token to comply to its policy. Note
// this function shouldn't be called again until the returned promise
// is resolved or rejected.
RefPtr<Promise> Alloc();
// Cancel the request to GlobalAllocPolicy and reject the current token
// request. Note this must happen before mOwnerThread->BeginShutdown().
void Cancel();
private:
/*
* An RAII class to manage LocalAllocPolicy::mDecoderLimit.
*/
class AutoDeallocToken : public Token {
public:
explicit AutoDeallocToken(LocalAllocPolicy* aOwner) : mOwner(aOwner) {
MOZ_DIAGNOSTIC_ASSERT(mOwner->mDecoderLimit > 0);
--mOwner->mDecoderLimit;
}
// Aggregate a GlobalAllocPolicy token to present a single instance of
// Token to the client so the client doesn't have to deal with
// GlobalAllocPolicy and LocalAllocPolicy separately.
void Append(Token* aToken) { mToken = aToken; }
private:
// Release tokens allocated from GlobalAllocPolicy and LocalAllocPolicy
// and process next token request if any.
~AutoDeallocToken() {
mToken = nullptr; // Dealloc the global token.
++mOwner->mDecoderLimit; // Dealloc the local token.
mOwner->ProcessRequest(); // Process next pending request.
}
RefPtr<LocalAllocPolicy> mOwner;
RefPtr<Token> mToken;
};
~LocalAllocPolicy() {}
void ProcessRequest();
int mDecoderLimit = 1;
const TrackType mTrack;
RefPtr<TaskQueue> mOwnerThread;
MozPromiseHolder<Promise> mPendingPromise;
MozPromiseRequestHolder<Promise> mTokenRequest;
};
RefPtr<LocalAllocPolicy::Promise> LocalAllocPolicy::Alloc() {
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
MOZ_DIAGNOSTIC_ASSERT(mPendingPromise.IsEmpty());
RefPtr<Promise> p = mPendingPromise.Ensure(__func__);
if (mDecoderLimit > 0) {
ProcessRequest();
}
return p.forget();
}
void LocalAllocPolicy::ProcessRequest() {
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
MOZ_DIAGNOSTIC_ASSERT(mDecoderLimit > 0);
// No pending request.
if (mPendingPromise.IsEmpty()) {
return;
}
RefPtr<AutoDeallocToken> token = new AutoDeallocToken(this);
RefPtr<LocalAllocPolicy> self = this;
GlobalAllocPolicy::Instance(mTrack)
.Alloc()
->Then(mOwnerThread, __func__,
[self, token](RefPtr<Token> aToken) {
self->mTokenRequest.Complete();
token->Append(aToken);
self->mPendingPromise.Resolve(token, __func__);
},
[self, token]() {
self->mTokenRequest.Complete();
self->mPendingPromise.Reject(true, __func__);
})
->Track(mTokenRequest);
}
void LocalAllocPolicy::Cancel() {
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
mPendingPromise.RejectIfExists(true, __func__);
mTokenRequest.DisconnectIfExists();
}
/**
* This class tracks shutdown promises to ensure all decoders are shut down
* completely before MFR continues the rest of the shutdown procedure.
@ -371,8 +262,8 @@ void MediaFormatReader::DecoderData::Flush() {
class MediaFormatReader::DecoderFactory {
using InitPromise = MediaDataDecoder::InitPromise;
using TokenPromise = GlobalAllocPolicy::Promise;
using Token = GlobalAllocPolicy::Token;
using TokenPromise = AllocPolicy::Promise;
using Token = AllocPolicy::Token;
public:
explicit DecoderFactory(MediaFormatReader* aOwner)
@ -415,10 +306,10 @@ class MediaFormatReader::DecoderFactory {
Data(DecoderData& aOwnerData, TrackType aTrack, TaskQueue* aThread)
: mOwnerData(aOwnerData),
mTrack(aTrack),
mPolicy(new LocalAllocPolicy(aTrack, aThread)) {}
mPolicy(new SingleAllocPolicy(aTrack, aThread)) {}
DecoderData& mOwnerData;
const TrackType mTrack;
RefPtr<LocalAllocPolicy> mPolicy;
RefPtr<SingleAllocPolicy> mPolicy;
Stage mStage = Stage::None;
RefPtr<Token> mToken;
RefPtr<MediaDataDecoder> mDecoder;

Просмотреть файл

@ -301,26 +301,14 @@ static uint16_t FromCaptureState(CaptureState aState) {
return static_cast<uint16_t>(aState);
}
void MediaManager::CallOnError(
const MediaManager::GetUserMediaErrorCallback* aCallback,
MediaStreamError& aError) {
MOZ_ASSERT(aCallback);
if (aCallback->HasWebIDLCallback()) {
aCallback->GetWebIDLCallback()->Call(aError);
} else {
aCallback->GetXPCOMCallback()->OnError(&aError);
}
void MediaManager::CallOnError(GetUserMediaErrorCallback& aCallback,
MediaStreamError& aError) {
aCallback.Call(aError);
}
void MediaManager::CallOnSuccess(
const MediaManager::GetUserMediaSuccessCallback* aCallback,
DOMMediaStream& aStream) {
MOZ_ASSERT(aCallback);
if (aCallback->HasWebIDLCallback()) {
aCallback->GetWebIDLCallback()->Call(aStream);
} else {
aCallback->GetXPCOMCallback()->OnSuccess(&aStream);
}
void MediaManager::CallOnSuccess(GetUserMediaSuccessCallback& aCallback,
DOMMediaStream& aStream) {
aCallback.Call(aStream);
}
/**

Просмотреть файл

@ -199,16 +199,14 @@ class MediaManager final : public nsIMediaManagerService,
void RemoveFromWindowList(uint64_t aWindowID,
GetUserMediaWindowListener* aListener);
typedef dom::CallbackObjectHolder<dom::NavigatorUserMediaSuccessCallback,
nsIDOMGetUserMediaSuccessCallback>
GetUserMediaSuccessCallback;
typedef dom::CallbackObjectHolder<dom::NavigatorUserMediaErrorCallback,
nsIDOMGetUserMediaErrorCallback>
GetUserMediaErrorCallback;
typedef dom::NavigatorUserMediaSuccessCallback GetUserMediaSuccessCallback;
typedef dom::NavigatorUserMediaErrorCallback GetUserMediaErrorCallback;
static void CallOnError(const GetUserMediaErrorCallback* aCallback,
MOZ_CAN_RUN_SCRIPT
static void CallOnError(GetUserMediaErrorCallback& aCallback,
dom::MediaStreamError& aError);
static void CallOnSuccess(const GetUserMediaSuccessCallback* aCallback,
MOZ_CAN_RUN_SCRIPT
static void CallOnSuccess(GetUserMediaSuccessCallback& aCallback,
DOMMediaStream& aStream);
typedef nsTArray<RefPtr<MediaDevice>> MediaDeviceSet;
@ -227,6 +225,7 @@ class MediaManager final : public nsIMediaManagerService,
const dom::MediaStreamConstraints& aConstraints,
dom::CallerType aCallerType);
MOZ_CAN_RUN_SCRIPT
nsresult GetUserMediaDevices(
nsPIDOMWindowInner* aWindow,
const dom::MediaStreamConstraints& aConstraints,

Просмотреть файл

@ -13,6 +13,7 @@
#include "MediaRecorder.h"
#include "PDMFactory.h"
#include "VPXDecoder.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Move.h"
#include "mozilla/StaticPrefs.h"
#include "mozilla/TaskQueue.h"
@ -243,81 +244,98 @@ already_AddRefed<Promise> MediaCapabilities::DecodingInfo(
*config, taskQueue, compositor,
CreateDecoderParams::VideoFrameRate(frameRate),
TrackInfo::kVideoTrack};
return AllocationWrapper::CreateDecoder(params)->Then(
taskQueue, __func__,
[taskQueue, frameRate, config = std::move(config)](
AllocationWrapper::AllocateDecoderPromise::
ResolveOrRejectValue&& aValue) mutable {
if (aValue.IsReject()) {
return CapabilitiesPromise::CreateAndReject(
std::move(aValue.RejectValue()), __func__);
}
RefPtr<MediaDataDecoder> decoder =
std::move(aValue.ResolveValue());
// We now query the decoder to determine if it's power
// efficient.
RefPtr<CapabilitiesPromise> p = decoder->Init()->Then(
taskQueue, __func__,
[taskQueue, decoder, frameRate, config = std::move(config)](
MediaDataDecoder::InitPromise::ResolveOrRejectValue&&
aValue) mutable {
RefPtr<CapabilitiesPromise> p;
if (aValue.IsReject()) {
p = CapabilitiesPromise::CreateAndReject(
std::move(aValue.RejectValue()), __func__);
} else {
MOZ_ASSERT(config->IsVideo());
nsAutoCString reason;
bool powerEfficient = true;
bool smooth = true;
if (config->GetAsVideoInfo()->mImage.height > 480) {
// Assume that we can do stuff at 480p or less in a
// power efficient manner and smoothly. If greater
// than 480p we assume that if the video decoding is
// hardware accelerated it will be smooth and power
// efficient, otherwise we use the benchmark to
// estimate
powerEfficient =
decoder->IsHardwareAccelerated(reason);
if (!powerEfficient &&
VPXDecoder::IsVP9(config->mMimeType)) {
smooth = VP9Benchmark::IsVP9DecodeFast(
true /* default */);
uint32_t fps = VP9Benchmark::MediaBenchmarkVp9Fps();
if (!smooth && fps > 0) {
// The VP9 estimizer decode a 1280x720 video.
// Let's adjust the result for the resolution and
// frame rate of what we actually want. If the
// result is twice that we need we assume it will
// be smooth.
const auto& videoConfig =
*config->GetAsVideoInfo();
double needed = ((1280.0 * 720.0) /
(videoConfig.mImage.width *
videoConfig.mImage.height) *
fps) /
frameRate;
smooth = needed > 2;
// We want to ensure that all decoder's queries are occurring only
// once at a time as it can quickly exhaust the system resources
// otherwise.
static RefPtr<AllocPolicy> sVideoAllocPolicy = [&taskQueue]() {
SystemGroup::Dispatch(
TaskCategory::Other,
NS_NewRunnableFunction(
"MediaCapabilities::AllocPolicy:Video", []() {
ClearOnShutdown(&sVideoAllocPolicy,
ShutdownPhase::ShutdownThreads);
}));
return new SingleAllocPolicy(TrackInfo::TrackType::kVideoTrack,
taskQueue);
}();
return AllocationWrapper::CreateDecoder(params, sVideoAllocPolicy)
->Then(
taskQueue, __func__,
[taskQueue, frameRate, config = std::move(config)](
AllocationWrapper::AllocateDecoderPromise::
ResolveOrRejectValue&& aValue) mutable {
if (aValue.IsReject()) {
return CapabilitiesPromise::CreateAndReject(
std::move(aValue.RejectValue()), __func__);
}
RefPtr<MediaDataDecoder> decoder =
std::move(aValue.ResolveValue());
// We now query the decoder to determine if it's power
// efficient.
RefPtr<CapabilitiesPromise> p = decoder->Init()->Then(
taskQueue, __func__,
[taskQueue, decoder, frameRate,
config = std::move(config)](
MediaDataDecoder::InitPromise::
ResolveOrRejectValue&& aValue) mutable {
RefPtr<CapabilitiesPromise> p;
if (aValue.IsReject()) {
p = CapabilitiesPromise::CreateAndReject(
std::move(aValue.RejectValue()), __func__);
} else {
MOZ_ASSERT(config->IsVideo());
nsAutoCString reason;
bool powerEfficient = true;
bool smooth = true;
if (config->GetAsVideoInfo()->mImage.height > 480) {
// Assume that we can do stuff at 480p or less in
// a power efficient manner and smoothly. If
// greater than 480p we assume that if the video
// decoding is hardware accelerated it will be
// smooth and power efficient, otherwise we use
// the benchmark to estimate
powerEfficient =
decoder->IsHardwareAccelerated(reason);
if (!powerEfficient &&
VPXDecoder::IsVP9(config->mMimeType)) {
smooth = VP9Benchmark::IsVP9DecodeFast(
true /* default */);
uint32_t fps =
VP9Benchmark::MediaBenchmarkVp9Fps();
if (!smooth && fps > 0) {
// The VP9 estimizer decode a 1280x720 video.
// Let's adjust the result for the resolution
// and frame rate of what we actually want. If
// the result is twice that we need we assume
// it will be smooth.
const auto& videoConfig =
*config->GetAsVideoInfo();
double needed = ((1280.0 * 720.0) /
(videoConfig.mImage.width *
videoConfig.mImage.height) *
fps) /
frameRate;
smooth = needed > 2;
}
}
}
p = CapabilitiesPromise::CreateAndResolve(
MediaCapabilitiesInfo(true /* supported */,
smooth, powerEfficient),
__func__);
}
}
p = CapabilitiesPromise::CreateAndResolve(
MediaCapabilitiesInfo(true /* supported */, smooth,
powerEfficient),
__func__);
}
MOZ_ASSERT(p.get(), "the promise has been created");
// Let's keep alive the decoder and the config object
// until the decoder has shutdown.
decoder->Shutdown()->Then(
taskQueue, __func__,
[taskQueue, decoder, config = std::move(config)](
const ShutdownPromise::ResolveOrRejectValue&
aValue) {});
return p;
});
return p;
});
MOZ_ASSERT(p.get(), "the promise has been created");
// Let's keep alive the decoder and the config object
// until the decoder has shutdown.
decoder->Shutdown()->Then(
taskQueue, __func__,
[taskQueue, decoder, config = std::move(config)](
const ShutdownPromise::ResolveOrRejectValue&
aValue) {});
return p;
});
return p;
});
}));
}

Просмотреть файл

@ -12,7 +12,10 @@
#include "VideoSink.h"
#include "GeckoProfiler.h"
#ifdef MOZ_GECKO_PROFILER
# include "ProfileJSONWriter.h"
# include "ProfilerMarkerPayload.h"
#endif
#include "MediaQueue.h"
#include "VideoUtils.h"
@ -31,6 +34,42 @@ extern LazyLogModule gMediaDecoderLog;
#define VSINK_LOG_V(x, ...) \
MOZ_LOG(gMediaDecoderLog, LogLevel::Verbose, (FMT(x, ##__VA_ARGS__)))
#ifdef MOZ_GECKO_PROFILER
# define VSINK_ADD_PROFILER_MARKER(tag, markerTime, aTime, vTime) \
do { \
if (profiler_thread_is_being_profiled()) { \
profiler_add_marker( \
tag, JS::ProfilingCategoryPair::GRAPHICS, \
MakeUnique<VideoFrameMarkerPayload>(markerTime, aTime, vTime)); \
} \
} while (0)
class VideoFrameMarkerPayload : public ProfilerMarkerPayload {
public:
explicit VideoFrameMarkerPayload(mozilla::TimeStamp aMarkerTime,
int64_t aAudioPositionUs,
int64_t aVideoFrameTimeUs)
: ProfilerMarkerPayload(aMarkerTime, aMarkerTime),
mAudioPositionUs(aAudioPositionUs),
mVideoFrameTimeUs(aVideoFrameTimeUs) {}
void StreamPayload(SpliceableJSONWriter& aWriter,
const TimeStamp& aProcessStartTime,
UniqueStacks& aUniqueStacks) {
StreamCommonProps("UpdateRenderVideoFrames", aWriter, aProcessStartTime,
aUniqueStacks);
aWriter.IntProperty("audio", mAudioPositionUs);
aWriter.IntProperty("video", mVideoFrameTimeUs);
}
private:
int64_t mAudioPositionUs;
int64_t mVideoFrameTimeUs;
};
#else
# define VSINK_ADD_PROFILER_MARKER(tag, markerTime, aTime, vTime)
#endif
using namespace mozilla::layers;
// Minimum update frequency is 1/120th of a second, i.e. half the
@ -411,7 +450,7 @@ void VideoSink::RenderVideoFrames(int32_t aMaxFrames, int64_t aClockTime,
MediaSink::PlaybackParams params = mAudioSink->GetPlaybackParams();
for (uint32_t i = 0; i < frames.Length(); ++i) {
VideoData* frame = frames[i];
bool wasSent = frame->IsSentToCompositor();
frame->MarkSentToCompositor();
if (!frame->mImage || !frame->mImage->IsValid() ||
@ -452,6 +491,10 @@ void VideoSink::RenderVideoFrames(int32_t aMaxFrames, int64_t aClockTime,
VSINK_LOG_V("playing video frame %" PRId64 " (id=%x) (vq-queued=%zu)",
frame->mTime.ToMicroseconds(), frame->mFrameID,
VideoQueue().GetSize());
if (!wasSent) {
VSINK_ADD_PROFILER_MARKER("VideoSink: play", aClockTimeStamp, aClockTime,
frame->mTime.ToMicroseconds());
}
}
if (images.Length() > 0) {
@ -488,13 +531,12 @@ void VideoSink::UpdateRenderedVideoFrames() {
VSINK_LOG_V("discarding video frame mTime=%" PRId64
" clock_time=%" PRId64,
frame->mTime.ToMicroseconds(), clockTime.ToMicroseconds());
VSINK_ADD_PROFILER_MARKER("VideoSink: discard", nowTime,
clockTime.ToMicroseconds(),
frame->mTime.ToMicroseconds());
}
}
if (droppedCount > 0) {
PROFILER_ADD_MARKER("DroppedUncompositedVideoFrames", GRAPHICS);
}
if (droppedCount || sentToCompositorCount) {
uint32_t totalCompositorDroppedCount = mContainer->GetDroppedImageCount();
uint32_t compositorDroppedCount =

Просмотреть файл

@ -16,25 +16,3 @@ interface nsIMediaDevice : nsISupports
readonly attribute AString groupId;
readonly attribute boolean scary;
};
[scriptable, function, uuid(24544878-d35e-4962-8c5f-fb84e97bdfee)]
interface nsIGetUserMediaDevicesSuccessCallback : nsISupports
{
void onSuccess(in nsIVariant devices);
};
[scriptable, function, uuid(f2a144fc-3534-4761-8c5d-989ae720f89a)]
interface nsIDOMGetUserMediaSuccessCallback : nsISupports
{
/*
* value must be a Blob if picture is true and a
* DOMMediaStream if either audio or video are true.
*/
void onSuccess(in nsISupports value);
};
[scriptable, function, uuid(39e96c61-2636-4f0e-918e-9bb64276492a)]
interface nsIDOMGetUserMediaErrorCallback : nsISupports
{
void onError(in nsISupports error);
};

Просмотреть файл

@ -6,8 +6,8 @@
#include "AllocationPolicy.h"
#include "PDMFactory.h"
#include "MediaInfo.h"
#include "PDMFactory.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/SystemGroup.h"
#ifdef MOZ_WIDGET_ANDROID
@ -18,18 +18,62 @@ namespace mozilla {
using TrackType = TrackInfo::TrackType;
StaticMutex GlobalAllocPolicy::sMutex;
class GlobalAllocPolicy::AutoDeallocToken : public Token {
class AllocPolicyImpl::AutoDeallocToken : public Token {
public:
explicit AutoDeallocToken(GlobalAllocPolicy& aPolicy) : mPolicy(aPolicy) {}
explicit AutoDeallocToken(const RefPtr<AllocPolicyImpl>& aPolicy)
: mPolicy(aPolicy) {}
private:
~AutoDeallocToken() { mPolicy.Dealloc(); }
~AutoDeallocToken() { mPolicy->Dealloc(); }
GlobalAllocPolicy& mPolicy; // reference to a singleton object.
RefPtr<AllocPolicyImpl> mPolicy;
};
AllocPolicyImpl::AllocPolicyImpl(int aDecoderLimit)
: mMaxDecoderLimit(aDecoderLimit),
mMonitor("AllocPolicyImpl"),
mDecoderLimit(aDecoderLimit) {}
AllocPolicyImpl::~AllocPolicyImpl() { RejectAll(); }
auto AllocPolicyImpl::Alloc() -> RefPtr<Promise> {
ReentrantMonitorAutoEnter mon(mMonitor);
// No decoder limit set.
if (mDecoderLimit < 0) {
return Promise::CreateAndResolve(new Token(), __func__);
}
RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
mPromises.push(p);
ResolvePromise(mon);
return p.forget();
}
void AllocPolicyImpl::Dealloc() {
ReentrantMonitorAutoEnter mon(mMonitor);
++mDecoderLimit;
ResolvePromise(mon);
}
void AllocPolicyImpl::ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock) {
MOZ_ASSERT(mDecoderLimit >= 0);
if (mDecoderLimit > 0 && !mPromises.empty()) {
--mDecoderLimit;
RefPtr<PromisePrivate> p = mPromises.front().forget();
mPromises.pop();
p->Resolve(new AutoDeallocToken(this), __func__);
}
}
void AllocPolicyImpl::RejectAll() {
ReentrantMonitorAutoEnter mon(mMonitor);
while (!mPromises.empty()) {
RefPtr<PromisePrivate> p = mPromises.front().forget();
mPromises.pop();
p->Reject(true, __func__);
}
}
static int32_t MediaDecoderLimitDefault() {
#ifdef MOZ_WIDGET_ANDROID
if (jni::GetAPIVersion() < 18) {
@ -42,68 +86,90 @@ static int32_t MediaDecoderLimitDefault() {
return -1;
}
GlobalAllocPolicy::GlobalAllocPolicy()
: mMonitor("DecoderAllocPolicy::mMonitor"),
mDecoderLimit(MediaDecoderLimitDefault()) {
SystemGroup::Dispatch(
TaskCategory::Other,
NS_NewRunnableFunction("GlobalAllocPolicy::GlobalAllocPolicy", [this]() {
ClearOnShutdown(this, ShutdownPhase::ShutdownThreads);
}));
}
StaticMutex GlobalAllocPolicy::sMutex;
GlobalAllocPolicy::~GlobalAllocPolicy() {
while (!mPromises.empty()) {
RefPtr<PromisePrivate> p = mPromises.front().forget();
mPromises.pop();
p->Reject(true, __func__);
}
}
GlobalAllocPolicy& GlobalAllocPolicy::Instance(TrackType aTrack) {
NotNull<AllocPolicy*> GlobalAllocPolicy::Instance(TrackType aTrack) {
StaticMutexAutoLock lock(sMutex);
if (aTrack == TrackType::kAudioTrack) {
static auto sAudioPolicy = new GlobalAllocPolicy();
return *sAudioPolicy;
} else {
static auto sVideoPolicy = new GlobalAllocPolicy();
return *sVideoPolicy;
static RefPtr<AllocPolicyImpl> sAudioPolicy = []() {
SystemGroup::Dispatch(
TaskCategory::Other,
NS_NewRunnableFunction(
"GlobalAllocPolicy::GlobalAllocPolicy:Audio", []() {
ClearOnShutdown(&sAudioPolicy, ShutdownPhase::ShutdownThreads);
}));
return new AllocPolicyImpl(MediaDecoderLimitDefault());
}();
return WrapNotNull(sAudioPolicy.get());
}
static RefPtr<AllocPolicyImpl> sVideoPolicy = []() {
SystemGroup::Dispatch(
TaskCategory::Other,
NS_NewRunnableFunction(
"GlobalAllocPolicy::GlobalAllocPolicy:Audio", []() {
ClearOnShutdown(&sVideoPolicy, ShutdownPhase::ShutdownThreads);
}));
return new AllocPolicyImpl(MediaDecoderLimitDefault());
}();
return WrapNotNull(sVideoPolicy.get());
}
auto GlobalAllocPolicy::Alloc() -> RefPtr<Promise> {
// No decoder limit set.
if (mDecoderLimit < 0) {
return Promise::CreateAndResolve(new Token(), __func__);
}
class SingleAllocPolicy::AutoDeallocCombinedToken : public Token {
public:
AutoDeallocCombinedToken(already_AddRefed<Token> aSingleAllocPolicyToken,
already_AddRefed<Token> aGlobalAllocPolicyToken)
: mSingleToken(aSingleAllocPolicyToken),
mGlobalToken(aGlobalAllocPolicyToken) {}
ReentrantMonitorAutoEnter mon(mMonitor);
RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
mPromises.push(p);
ResolvePromise(mon);
return p.forget();
private:
// Release tokens allocated from GlobalAllocPolicy and LocalAllocPolicy
// and process next token request if any.
~AutoDeallocCombinedToken() = default;
const RefPtr<Token> mSingleToken;
const RefPtr<Token> mGlobalToken;
};
auto SingleAllocPolicy::Alloc() -> RefPtr<Promise> {
MOZ_DIAGNOSTIC_ASSERT(MaxDecoderLimit() == 1,
"We can only handle at most one token out at a time.");
RefPtr<SingleAllocPolicy> self = this;
return AllocPolicyImpl::Alloc()->Then(
mOwnerThread, __func__,
[self](RefPtr<Token> aToken) {
RefPtr<Token> localToken = aToken.forget();
RefPtr<Promise> p = self->mPendingPromise.Ensure(__func__);
GlobalAllocPolicy::Instance(self->mTrack)
->Alloc()
->Then(self->mOwnerThread, __func__,
[self, localToken = std::move(localToken)](
RefPtr<Token> aToken) mutable {
self->mTokenRequest.Complete();
RefPtr<Token> combinedToken = new AutoDeallocCombinedToken(
localToken.forget(), aToken.forget());
self->mPendingPromise.Resolve(combinedToken, __func__);
},
[self]() {
self->mTokenRequest.Complete();
self->mPendingPromise.Reject(true, __func__);
})
->Track(self->mTokenRequest);
return p;
},
[]() { return Promise::CreateAndReject(true, __func__); });
}
void GlobalAllocPolicy::Dealloc() {
ReentrantMonitorAutoEnter mon(mMonitor);
++mDecoderLimit;
ResolvePromise(mon);
SingleAllocPolicy::~SingleAllocPolicy() {
mPendingPromise.RejectIfExists(true, __func__);
mTokenRequest.DisconnectIfExists();
}
void GlobalAllocPolicy::ResolvePromise(
ReentrantMonitorAutoEnter& aProofOfLock) {
MOZ_ASSERT(mDecoderLimit >= 0);
if (mDecoderLimit > 0 && !mPromises.empty()) {
--mDecoderLimit;
RefPtr<PromisePrivate> p = mPromises.front().forget();
mPromises.pop();
p->Resolve(new AutoDeallocToken(*this), __func__);
}
void SingleAllocPolicy::Cancel() {
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
mPendingPromise.RejectIfExists(true, __func__);
mTokenRequest.DisconnectIfExists();
RejectAll();
}
void GlobalAllocPolicy::operator=(std::nullptr_t) { delete this; }
AllocationWrapper::AllocationWrapper(
already_AddRefed<MediaDataDecoder> aDecoder, already_AddRefed<Token> aToken)
: mDecoder(aDecoder), mToken(aToken) {
@ -125,7 +191,8 @@ RefPtr<ShutdownPromise> AllocationWrapper::Shutdown() {
[token]() { return ShutdownPromise::CreateAndResolve(true, __func__); });
}
/* static */ RefPtr<AllocationWrapper::AllocateDecoderPromise>
AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams) {
AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams,
AllocPolicy* aPolicy) {
// aParams.mConfig is guaranteed to stay alive during the lifetime of the
// MediaDataDecoder, so keeping a pointer to the object is safe.
const TrackInfo* config = &aParams.mConfig;
@ -143,8 +210,8 @@ AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams) {
CreateDecoderParams::VideoFrameRate rate = aParams.mRate;
RefPtr<AllocateDecoderPromise> p =
GlobalAllocPolicy::Instance(aParams.mType)
.Alloc()
(aPolicy ? aPolicy : GlobalAllocPolicy::Instance(aParams.mType))
->Alloc()
->Then(AbstractThread::GetCurrent(), __func__,
[=](RefPtr<Token> aToken) {
// result may not always be updated by

Просмотреть файл

@ -7,56 +7,84 @@
#ifndef AllocationPolicy_h_
#define AllocationPolicy_h_
#include <queue>
#include "MediaInfo.h"
#include "PlatformDecoderModule.h"
#include "TimeUnits.h"
#include "mozilla/MozPromise.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/NotNull.h"
#include "mozilla/ReentrantMonitor.h"
#include <queue>
#include "mozilla/StaticMutex.h"
namespace mozilla {
/**
* This is a singleton which controls the number of decoders that can be
* created concurrently. Before calling PDMFactory::CreateDecoder(), Alloc()
* must be called to get a token object as a permission to create a decoder.
* The token should stay alive until Shutdown() is called on the decoder.
* The destructor of the token will restore the decoder count so it is available
* Before calling PDMFactory::CreateDecoder(), Alloc() must be called on the
* policy to get a token object as a permission to create a decoder. The
* token should stay alive until Shutdown() is called on the decoder. The
* destructor of the token will restore the decoder count so it is available
* for next calls of Alloc().
*/
class GlobalAllocPolicy {
class AllocPolicy {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AllocPolicy)
public:
class Token {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Token)
protected:
virtual ~Token() {}
virtual ~Token() = default;
};
using Promise = MozPromise<RefPtr<Token>, bool, true>;
// Acquire a token for decoder creation. Thread-safe.
RefPtr<Promise> Alloc();
virtual RefPtr<Promise> Alloc() = 0;
// Called by ClearOnShutdown() to delete the singleton.
void operator=(decltype(nullptr));
protected:
virtual ~AllocPolicy() = default;
};
/**
* This is a singleton which controls the number of decoders that can be created
* concurrently.
* Instance() will return the TrackType global AllocPolicy.
* Instance() will always return a non-null value.
*/
class GlobalAllocPolicy {
public:
// Get the singleton for the given track type. Thread-safe.
static GlobalAllocPolicy& Instance(TrackInfo::TrackType aTrack);
static NotNull<AllocPolicy*> Instance(TrackInfo::TrackType aTrack);
private:
// Protect access to Instance().
static StaticMutex sMutex;
};
/** This the actual base implementation underneath all AllocPolicy objects and
* control how many decoders can be created concurrently.
* Alloc() must be called to get a token object as a permission to perform an
* action. The token should stay alive until Shutdown() is called on the
* decoder. The destructor of the token will restore the decoder count so it is
* available for next calls of Alloc().
**/
class AllocPolicyImpl : public AllocPolicy {
public:
explicit AllocPolicyImpl(int aDecoderLimit);
RefPtr<Promise> Alloc() override;
protected:
virtual ~AllocPolicyImpl();
void RejectAll();
int MaxDecoderLimit() const { return mMaxDecoderLimit; }
private:
class AutoDeallocToken;
using PromisePrivate = Promise::Private;
GlobalAllocPolicy();
~GlobalAllocPolicy();
// Called by the destructor of TokenImpl to restore the decoder limit.
void Dealloc();
// Decrement the decoder limit and resolve a promise if available.
void ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock);
// Protect access to Instance().
static StaticMutex sMutex;
const int mMaxDecoderLimit;
ReentrantMonitor mMonitor;
// The number of decoders available for creation.
int mDecoderLimit;
@ -64,8 +92,35 @@ class GlobalAllocPolicy {
std::queue<RefPtr<PromisePrivate>> mPromises;
};
/**
* This class allows to track and serialise a single decoder allocation at a
* time
*/
class SingleAllocPolicy : public AllocPolicyImpl {
using TrackType = TrackInfo::TrackType;
public:
SingleAllocPolicy(TrackType aTrack, TaskQueue* aOwnerThread)
: AllocPolicyImpl(1), mTrack(aTrack), mOwnerThread(aOwnerThread) {}
RefPtr<Promise> Alloc() override;
// Cancel the request to GlobalAllocPolicy and reject the current token
// request. Note this must happen before mOwnerThread->BeginShutdown().
void Cancel();
private:
class AutoDeallocCombinedToken;
virtual ~SingleAllocPolicy();
const TrackType mTrack;
RefPtr<TaskQueue> mOwnerThread;
MozPromiseHolder<Promise> mPendingPromise;
MozPromiseRequestHolder<Promise> mTokenRequest;
};
class AllocationWrapper : public MediaDataDecoder {
using Token = GlobalAllocPolicy::Token;
using Token = AllocPolicy::Token;
public:
AllocationWrapper(already_AddRefed<MediaDataDecoder> aDecoder,
@ -96,11 +151,11 @@ class AllocationWrapper : public MediaDataDecoder {
/* IsExclusive = */ true>
AllocateDecoderPromise;
// Will create a decoder has soon as one can be created according to the
// GlobalAllocPolicy.
// AllocPolicy (or GlobalAllocPolicy if aPolicy is null)
// Warning: all aParams members must be valid until the promise has been
// resolved, as some contains raw pointers to objects.
static RefPtr<AllocateDecoderPromise> CreateDecoder(
const CreateDecoderParams& aParams);
const CreateDecoderParams& aParams, AllocPolicy* aPolicy = nullptr);
private:
RefPtr<MediaDataDecoder> mDecoder;

Просмотреть файл

@ -85,6 +85,9 @@ class MediaDecodeTask final : public Runnable {
MOZ_ASSERT(NS_IsMainThread());
}
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
// bug 1535398.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
NS_IMETHOD Run() override;
bool CreateReader();
MediaFormatReader* Reader() {
@ -93,6 +96,7 @@ class MediaDecodeTask final : public Runnable {
}
private:
MOZ_CAN_RUN_SCRIPT
void ReportFailureOnMainThread(WebAudioDecodeJob::ErrorCode aErrorCode) {
if (NS_IsMainThread()) {
Cleanup();
@ -109,14 +113,14 @@ class MediaDecodeTask final : public Runnable {
}
void Decode();
void OnMetadataRead(MetadataHolder&& aMetadata);
void OnMetadataNotRead(const MediaResult& aError);
MOZ_CAN_RUN_SCRIPT void OnMetadataRead(MetadataHolder&& aMetadata);
MOZ_CAN_RUN_SCRIPT void OnMetadataNotRead(const MediaResult& aError);
void RequestSample();
void SampleDecoded(RefPtr<AudioData> aData);
void SampleNotDecoded(const MediaResult& aError);
void FinishDecode();
void AllocateBuffer();
void CallbackTheResult();
MOZ_CAN_RUN_SCRIPT void SampleNotDecoded(const MediaResult& aError);
MOZ_CAN_RUN_SCRIPT void FinishDecode();
MOZ_CAN_RUN_SCRIPT void AllocateBuffer();
MOZ_CAN_RUN_SCRIPT void CallbackTheResult();
void Cleanup() {
MOZ_ASSERT(NS_IsMainThread());
@ -486,14 +490,14 @@ void WebAudioDecodeJob::OnSuccess(ErrorCode aErrorCode) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aErrorCode == NoError);
RefPtr<AudioBuffer> output(mOutput);
if (mSuccessCallback) {
ErrorResult rv;
mSuccessCallback->Call(*mOutput, rv);
RefPtr<DecodeSuccessCallback> callback(mSuccessCallback);
// Ignore errors in calling the callback, since there is not much that we
// can do about it here.
rv.SuppressException();
callback->Call(*output);
}
mPromise->MaybeResolve(mOutput);
mPromise->MaybeResolve(output);
mContext->RemoveFromDecodeQueue(this);
}
@ -537,7 +541,8 @@ void WebAudioDecodeJob::OnFailure(ErrorCode aErrorCode) {
nsAutoCString errorString(errorMessage);
RefPtr<DOMException> exception = DOMException::Create(
NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR, errorString);
mFailureCallback->Call(*exception);
RefPtr<DecodeErrorCallback> callback(mFailureCallback);
callback->Call(*exception);
}
mPromise->MaybeReject(NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR);

Просмотреть файл

@ -12,6 +12,7 @@
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/MemoryReporting.h"
@ -45,8 +46,8 @@ struct WebAudioDecodeJob final {
typedef void (WebAudioDecodeJob::*ResultFn)(ErrorCode);
void OnSuccess(ErrorCode /* ignored */);
void OnFailure(ErrorCode aErrorCode);
MOZ_CAN_RUN_SCRIPT void OnSuccess(ErrorCode /* ignored */);
MOZ_CAN_RUN_SCRIPT void OnFailure(ErrorCode aErrorCode);
bool AllocateBuffer();

Просмотреть файл

@ -55,7 +55,8 @@ already_AddRefed<Promise> RTCIdentityProviderRegistrar::GenerateAssertion(
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
return nullptr;
}
return mGenerateAssertionCallback->Call(aContents, aOrigin, aOptions, aRv);
RefPtr<GenerateAssertionCallback> callback(mGenerateAssertionCallback);
return callback->Call(aContents, aOrigin, aOptions, aRv);
}
already_AddRefed<Promise> RTCIdentityProviderRegistrar::ValidateAssertion(
const nsAString& aAssertion, const nsAString& aOrigin, ErrorResult& aRv) {
@ -63,7 +64,8 @@ already_AddRefed<Promise> RTCIdentityProviderRegistrar::ValidateAssertion(
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
return nullptr;
}
return mValidateAssertionCallback->Call(aAssertion, aOrigin, aRv);
RefPtr<ValidateAssertionCallback> callback(mValidateAssertionCallback);
return callback->Call(aAssertion, aOrigin, aRv);
}
} // namespace dom

Просмотреть файл

@ -38,9 +38,11 @@ class RTCIdentityProviderRegistrar final : public nsISupports,
void Register(const RTCIdentityProvider& aIdp);
bool HasIdp() const;
MOZ_CAN_RUN_SCRIPT
already_AddRefed<Promise> GenerateAssertion(
const nsAString& aContents, const nsAString& aOrigin,
const RTCIdentityProviderOptions& aOptions, ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT
already_AddRefed<Promise> ValidateAssertion(const nsAString& assertion,
const nsAString& origin,
ErrorResult& aRv);

Просмотреть файл

@ -231,7 +231,7 @@ class NotificationPermissionRequest : public ContentPermissionRequestBase,
protected:
~NotificationPermissionRequest() = default;
nsresult ResolvePromise();
MOZ_CAN_RUN_SCRIPT nsresult ResolvePromise();
nsresult DispatchResolvePromise();
NotificationPermission mPermission;
RefPtr<Promise> mPromise;
@ -575,7 +575,8 @@ nsresult NotificationPermissionRequest::ResolvePromise() {
}
if (mCallback) {
ErrorResult error;
mCallback->Call(mPermission, error);
RefPtr<NotificationPermissionCallback> callback(mCallback);
callback->Call(mPermission, error);
rv = error.StealNSResult();
}
mPromise->MaybeResolve(mPermission);

Просмотреть файл

@ -424,9 +424,13 @@ class NotifyObserversTask final : public CancelableRunnable {
MOZ_ASSERT(mPerformance);
}
// MOZ_CAN_RUN_SCRIPT_BOUNDARY for now until Runnable::Run is
// MOZ_CAN_RUN_SCRIPT.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
NS_IMETHOD Run() override {
MOZ_ASSERT(mPerformance);
mPerformance->NotifyObservers();
RefPtr<Performance> performance(mPerformance);
performance->NotifyObservers();
return NS_OK;
}

Просмотреть файл

@ -79,7 +79,7 @@ class Performance : public DOMEventTargetHelper {
void AddObserver(PerformanceObserver* aObserver);
void RemoveObserver(PerformanceObserver* aObserver);
void NotifyObservers();
MOZ_CAN_RUN_SCRIPT void NotifyObservers();
void CancelNotificationObservers();
virtual PerformanceTiming* Timing() = 0;

Просмотреть файл

@ -106,7 +106,8 @@ void PerformanceObserver::Notify() {
mQueuedEntries.Clear();
ErrorResult rv;
mCallback->Call(this, *list, *this, rv);
RefPtr<PerformanceObserverCallback> callback(mCallback);
callback->Call(this, *list, *this, rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
}

Просмотреть файл

@ -55,7 +55,7 @@ class PerformanceObserver final : public nsISupports, public nsWrapperCache {
void TakeRecords(nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void Notify();
MOZ_CAN_RUN_SCRIPT void Notify();
void QueueEntry(PerformanceEntry* aEntry);
private:

Просмотреть файл

@ -55,11 +55,6 @@ union SurfaceDescriptor {
null_t;
};
union OptionalShmem {
Shmem;
null_t;
};
intr protocol PPluginInstance
{
manager PPluginModule;

Просмотреть файл

@ -316,6 +316,7 @@ void Promise::MaybeReject(JSContext* aCx, JS::Handle<JS::Value> aValue) {
enum class NativeHandlerTask : int32_t { Resolve, Reject };
MOZ_CAN_RUN_SCRIPT
static bool NativeHandlerCallback(JSContext* aCx, unsigned aArgc,
JS::Value* aVp) {
JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
@ -334,10 +335,12 @@ static bool NativeHandlerCallback(JSContext* aCx, unsigned aArgc,
NativeHandlerTask task = static_cast<NativeHandlerTask>(v.toInt32());
if (task == NativeHandlerTask::Resolve) {
handler->ResolvedCallback(aCx, args.get(0));
// handler is kept alive by "obj" on the stack.
MOZ_KnownLive(handler)->ResolvedCallback(aCx, args.get(0));
} else {
MOZ_ASSERT(task == NativeHandlerTask::Reject);
handler->RejectedCallback(aCx, args.get(0));
// handler is kept alive by "obj" on the stack.
MOZ_KnownLive(handler)->RejectedCallback(aCx, args.get(0));
}
return true;
@ -377,14 +380,18 @@ class PromiseNativeHandlerShim final : public PromiseNativeHandler {
MOZ_ASSERT(mInner);
}
MOZ_CAN_RUN_SCRIPT
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
mInner->ResolvedCallback(aCx, aValue);
mInner = nullptr;
RefPtr<PromiseNativeHandler> inner = mInner.forget();
inner->ResolvedCallback(aCx, aValue);
MOZ_ASSERT(!mInner);
}
MOZ_CAN_RUN_SCRIPT
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
mInner->RejectedCallback(aCx, aValue);
mInner = nullptr;
RefPtr<PromiseNativeHandler> inner = mInner.forget();
inner->RejectedCallback(aCx, aValue);
MOZ_ASSERT(!mInner);
}
bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,

Просмотреть файл

@ -23,9 +23,11 @@ class PromiseNativeHandler : public nsISupports {
virtual ~PromiseNativeHandler() {}
public:
MOZ_CAN_RUN_SCRIPT
virtual void ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) = 0;
MOZ_CAN_RUN_SCRIPT
virtual void RejectedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) = 0;
};

Просмотреть файл

@ -138,7 +138,11 @@ void ReportingObserver::MaybeReport(Report* aReport) {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
"ReportingObserver::MaybeReport",
[window]() { window->NotifyReportingObservers(); });
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until at least we're able to have
// Runnable::Run be MOZ_CAN_RUN_SCRIPT. But even then, having a boundary
// here might make the most sense.
[window]()
MOZ_CAN_RUN_SCRIPT_BOUNDARY { window->NotifyReportingObservers(); });
NS_DispatchToCurrentThread(r);
}
@ -160,7 +164,8 @@ void ReportingObserver::MaybeNotify() {
}
// We should report if this throws exception. But where?
mCallback->Call(reports, *this);
RefPtr<ReportingObserverCallback> callback(mCallback);
callback->Call(reports, *this);
}
NS_IMETHODIMP

Просмотреть файл

@ -54,7 +54,7 @@ class ReportingObserver final : public nsIObserver,
void MaybeReport(Report* aReport);
void MaybeNotify();
MOZ_CAN_RUN_SCRIPT void MaybeNotify();
private:
~ReportingObserver();

Просмотреть файл

@ -91,6 +91,7 @@ class U2F final : public WebAuthnManagerBase, public nsWrapperCache {
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
MOZ_CAN_RUN_SCRIPT
void Register(const nsAString& aAppId,
const Sequence<RegisterRequest>& aRegisterRequests,
const Sequence<RegisteredKey>& aRegisteredKeys,
@ -98,6 +99,7 @@ class U2F final : public WebAuthnManagerBase, public nsWrapperCache {
const Optional<Nullable<int32_t>>& opt_aTimeoutSeconds,
ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT
void Sign(const nsAString& aAppId, const nsAString& aChallenge,
const Sequence<RegisteredKey>& aRegisteredKeys,
U2FSignCallback& aCallback,
@ -106,31 +108,35 @@ class U2F final : public WebAuthnManagerBase, public nsWrapperCache {
// WebAuthnManagerBase
MOZ_CAN_RUN_SCRIPT
void FinishMakeCredential(
const uint64_t& aTransactionId,
const WebAuthnMakeCredentialResult& aResult) override;
MOZ_CAN_RUN_SCRIPT
void FinishGetAssertion(const uint64_t& aTransactionId,
const WebAuthnGetAssertionResult& aResult) override;
MOZ_CAN_RUN_SCRIPT
void RequestAborted(const uint64_t& aTransactionId,
const nsresult& aError) override;
protected:
// Cancels the current transaction (by sending a Cancel message to the
// parent) and rejects it by calling RejectTransaction().
void CancelTransaction(const nsresult& aError) override;
MOZ_CAN_RUN_SCRIPT void CancelTransaction(const nsresult& aError) override;
private:
~U2F();
MOZ_CAN_RUN_SCRIPT ~U2F();
template <typename T, typename C>
void ExecuteCallback(T& aResp, nsMainThreadPtrHandle<C>& aCb);
MOZ_CAN_RUN_SCRIPT void ExecuteCallback(T& aResp,
nsMainThreadPtrHandle<C>& aCb);
// Clears all information we have about the current transaction.
void ClearTransaction();
// Rejects the current transaction and clears it.
void RejectTransaction(const nsresult& aError);
MOZ_CAN_RUN_SCRIPT void RejectTransaction(const nsresult& aError);
nsString mOrigin;

Просмотреть файл

@ -30,24 +30,27 @@ class WebAuthnManagerBase : public nsIDOMEventListener {
explicit WebAuthnManagerBase(nsPIDOMWindowInner* aParent);
MOZ_CAN_RUN_SCRIPT
virtual void FinishMakeCredential(
const uint64_t& aTransactionId,
const WebAuthnMakeCredentialResult& aResult) = 0;
MOZ_CAN_RUN_SCRIPT
virtual void FinishGetAssertion(
const uint64_t& aTransactionId,
const WebAuthnGetAssertionResult& aResult) = 0;
MOZ_CAN_RUN_SCRIPT
virtual void RequestAborted(const uint64_t& aTransactionId,
const nsresult& aError) = 0;
void ActorDestroyed();
protected:
virtual ~WebAuthnManagerBase();
MOZ_CAN_RUN_SCRIPT virtual ~WebAuthnManagerBase();
// Needed by HandleEvent() to cancel transactions.
virtual void CancelTransaction(const nsresult& aError) = 0;
MOZ_CAN_RUN_SCRIPT virtual void CancelTransaction(const nsresult& aError) = 0;
// Visibility event handling.
void ListenForVisibilityEvents();

Просмотреть файл

@ -25,14 +25,23 @@ class WebAuthnTransactionChild final : public PWebAuthnTransactionChild {
NS_INLINE_DECL_REFCOUNTING(WebAuthnTransactionChild);
explicit WebAuthnTransactionChild(WebAuthnManagerBase* aManager);
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until we can do MOZ_CAN_RUN_SCRIPT in
// IPDL-generated things.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvConfirmRegister(
const uint64_t& aTransactionId,
const WebAuthnMakeCredentialResult& aResult);
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until we can do MOZ_CAN_RUN_SCRIPT in
// IPDL-generated things.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvConfirmSign(
const uint64_t& aTransactionId,
const WebAuthnGetAssertionResult& aResult);
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until we can do MOZ_CAN_RUN_SCRIPT in
// IPDL-generated things.
MOZ_CAN_RUN_SCRIPT_BOUNDARY
mozilla::ipc::IPCResult RecvAbort(const uint64_t& aTransactionId,
const nsresult& aError);

Просмотреть файл

@ -10,9 +10,7 @@
* liability, trademark and document use rules apply.
*/
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback DecodeSuccessCallback = void (AudioBuffer decodedData);
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback DecodeErrorCallback = void (DOMException error);
enum AudioContextState {

Просмотреть файл

@ -189,7 +189,6 @@ interface ConsoleInstance {
void profileEnd(any... data);
};
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback ConsoleInstanceDumpCallback = void (DOMString message);
enum ConsoleLogLevel {

Просмотреть файл

@ -17,7 +17,6 @@ interface DataTransferItem {
File? getAsFile();
};
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback FunctionStringCallback = void (DOMString data);
// https://wicg.github.io/entries-api/#idl-index

Просмотреть файл

@ -10,15 +10,15 @@
* Opera Software ASA. You are granted a license to use, reproduce
* and create derivative works of this document.
*/
[TreatNonObjectAsNull, MOZ_CAN_RUN_SCRIPT_BOUNDARY]
[TreatNonObjectAsNull]
callback EventHandlerNonNull = any (Event event);
typedef EventHandlerNonNull? EventHandler;
[TreatNonObjectAsNull, MOZ_CAN_RUN_SCRIPT_BOUNDARY]
[TreatNonObjectAsNull]
callback OnBeforeUnloadEventHandlerNonNull = DOMString? (Event event);
typedef OnBeforeUnloadEventHandlerNonNull? OnBeforeUnloadEventHandler;
[TreatNonObjectAsNull, MOZ_CAN_RUN_SCRIPT_BOUNDARY]
[TreatNonObjectAsNull]
callback OnErrorEventHandlerNonNull = any ((Event or DOMString) event, optional DOMString source, optional unsigned long lineno, optional unsigned long column, optional any error);
typedef OnErrorEventHandlerNonNull? OnErrorEventHandler;

Просмотреть файл

@ -11,10 +11,8 @@ dictionary FileSystemFlags {
boolean exclusive = false;
};
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback FileSystemEntryCallback = void (FileSystemEntry entry);
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback ErrorCallback = void (DOMException err);
interface FileSystem {

Просмотреть файл

@ -6,7 +6,6 @@
* https://wicg.github.io/entries-api/#idl-index
*/
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
callback FileSystemEntriesCallback = void (sequence<FileSystemEntry> entries);
interface FileSystemDirectoryReader {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше