Merge inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2016-05-19 12:46:54 -04:00
commit 4cffb5461e
222 changed files with 3974 additions and 3073 deletions

118
.taskcluster.yml Normal file
View File

@ -0,0 +1,118 @@
---
version: 0
metadata:
name: 'Taskcluster tasks for Gecko'
description: "The taskcluster task graph for Gecko trees"
owner: mozilla-taskcluster-maintenance@mozilla.com
source: {{{source}}}
scopes:
# Note the below scopes are insecure however these get overriden on the server
# side to whatever scopes are set by mozilla-taskcluster.
- queue:*
- docker-worker:*
- scheduler:*
# Available mustache parameters (see the mozilla-taskcluster source):
#
# - owner: push user (email address)
# - source: URL of this YAML file
# - url: repository URL
# - project: alias for the destination repository (basename of
# the repo url)
# - level: SCM level of the destination repository
# (1 = try, 3 = core)
# - revision: (short) hg revision of the head of the push
# - revision_hash: (long) hg revision of the head of the push
# - comment: comment of the push
# - pushlog_id: id in the pushlog table of the repository
#
# and functions:
# - as_slugid: convert a label into a slugId
# - from_now: generate a timestamp at a fixed offset from now
tasks:
- taskId: '{{#as_slugid}}decision task{{/as_slugid}}'
reruns: 3
task:
created: '{{now}}'
deadline: '{{#from_now}}1 day{{/from_now}}'
expires: '{{#from_now}}14 day{{/from_now}}'
metadata:
owner: mozilla-taskcluster-maintenance@mozilla.com
source: {{{source}}}
name: "Gecko Decision Task"
description: |
The task that creates all of the other tasks in the task graph
workerType: "gecko-decision"
provisionerId: "aws-provisioner-v1"
tags:
createdForUser: {{owner}}
scopes:
# Bug 1269443: cache scopes, etc. must be listed explicitly
- "docker-worker:cache:level-1-*"
- "docker-worker:cache:tooltool-cache"
- "secrets:get:project/taskcluster/gecko/hgfingerprint"
- "assume:repo:hg.mozilla.org/try:*"
routes:
- "index.gecko.v2.{{project}}.latest.firefox.decision"
- "tc-treeherder.{{project}}.{{revision_hash}}"
- "tc-treeherder-stage.{{project}}.{{revision_hash}}"
payload:
env:
# checkout-gecko uses these to check out the source; the inputs
# to `mach taskgraph decision` are all on the command line.
GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-central'
GECKO_HEAD_REPOSITORY: '{{{url}}}'
GECKO_HEAD_REF: '{{revision}}'
GECKO_HEAD_REV: '{{revision}}'
cache:
level-{{level}}-{{project}}-tc-vcs-public-sources: /home/worker/.tc-vcs/
level-{{level}}-{{project}}-gecko-decision: /home/worker/workspace
features:
taskclusterProxy: true
# Note: This task is built server side without the context or tooling that
# exist in tree so we must hard code the version
image: 'taskcluster/decision:0.1.0'
maxRunTime: 1800
command:
- /bin/bash
- -cx
- >
mkdir -p /home/worker/artifacts &&
checkout-gecko workspace &&
cd workspace/gecko &&
ln -s /home/worker/artifacts artifacts &&
./mach taskgraph decision
--pushlog-id='{{pushlog_id}}'
--project='{{project}}'
--message='{{comment}}'
--owner='{{owner}}'
--level='{{level}}'
--base-repository='https://hg.mozilla.org/mozilla-central'
--head-repository='{{{url}}}'
--head-ref='{{revision}}'
--head-rev='{{revision}}'
--revision-hash='{{revision_hash}}'
artifacts:
'public':
type: 'directory'
path: '/home/worker/artifacts'
expires: '{{#from_now}}7 days{{/from_now}}'
extra:
treeherder:
symbol: D
revision: '{{revision}}'
revision_hash: '{{revision_hash}}'

View File

@ -170,6 +170,17 @@ DocAccessible::CreateSubtree(Accessible* aChild)
Accessible* focusedAcc = nullptr;
CacheChildrenInSubtree(aChild, &focusedAcc);
// Fire events for ARIA elements.
if (aChild->HasARIARole()) {
roles::Role role = aChild->ARIARole();
if (role == roles::MENUPOPUP) {
FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aChild);
}
else if (role == roles::ALERT) {
FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aChild);
}
}
// XXX: do we really want to send focus to focused DOM node not taking into
// account active item?
if (focusedAcc) {

View File

@ -2181,19 +2181,9 @@ DocAccessible::CacheChildrenInSubtree(Accessible* aRoot,
return;
}
roles::Role role = aRoot->ARIARole();
if (role == roles::MENUPOPUP) {
FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aRoot);
return;
}
if (role == roles::ALERT) {
FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aRoot);
return;
}
// XXX: we should delay document load complete event if the ARIA document
// has aria-busy.
roles::Role role = aRoot->ARIARole();
if (!aRoot->IsDoc() && (role == roles::DIALOG || role == roles::DOCUMENT)) {
FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot);
}

View File

@ -4030,8 +4030,11 @@ function openNewUserContextTab(event)
*/
function updateUserContextUIVisibility()
{
let userContextEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
document.getElementById("menu_newUserContext").hidden = !userContextEnabled;
let menu = document.getElementById("menu_newUserContext");
menu.hidden = !Services.prefs.getBoolPref("privacy.userContext.enabled");
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
menu.setAttribute("disabled", "true");
}
}
/**

View File

@ -149,7 +149,7 @@ nsContextMenu.prototype = {
this.showItem("context-openlink", shouldShow && !isWindowPrivate);
this.showItem("context-openlinkprivate", shouldShow);
this.showItem("context-openlinkintab", shouldShow);
this.showItem("context-openlinkinusercontext-menu", shouldShow && showContainers);
this.showItem("context-openlinkinusercontext-menu", shouldShow && !isWindowPrivate && showContainers);
this.showItem("context-openlinkincurrent", this.onPlainTextLink);
this.showItem("context-sep-open", shouldShow);
},

View File

@ -6604,7 +6604,12 @@
let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled;
document.getElementById("alltabs_containersTab").hidden = !containersEnabled;
let containersTab = document.getElementById("alltabs_containersTab");
containersTab.hidden = !containersEnabled;
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
containersTab.setAttribute("disabled", "true");
}
document.getElementById("alltabs_undoCloseTab").disabled =
SessionStore.getClosedTabCount(window) == 0;

View File

@ -26,7 +26,7 @@ this.ContextualIdentityService = {
label: "userContextWork.label",
accessKey: "userContextWork.accesskey" },
{ userContextId: 3,
icon: "chome://browser/skin/usercontext/banking.svg",
icon: "chrome://browser/skin/usercontext/banking.svg",
color: "#7dc14c",
label: "userContextBanking.label",
accessKey: "userContextBanking.accesskey" },

View File

@ -1116,6 +1116,10 @@ if (Services.prefs.getBoolPref("privacy.userContext.enabled")) {
win.openUILinkIn(win.BROWSER_NEW_TAB_URL, "tab", {userContextId});
};
items.addEventListener("command", onItemCommand);
if (PrivateBrowsingUtils.isWindowPrivate(win)) {
aNode.setAttribute("disabled", "true");
}
},
onViewShowing: function(aEvent) {
let doc = aEvent.detail.ownerDocument;

View File

@ -622,7 +622,9 @@ this.UITour = {
case "resetFirefox": {
// Open a reset profile dialog window.
ResetProfile.openConfirmationDialog(window);
if (ResetProfile.resetSupported()) {
ResetProfile.openConfirmationDialog(window);
}
break;
}
@ -1939,6 +1941,9 @@ this.UITour = {
setup: Services.prefs.prefHasUserValue("services.sync.username"),
});
break;
case "canReset":
this.sendPageCallback(aMessageManager, aCallbackID, ResetProfile.resetSupported());
break;
default:
log.error("getConfiguration: Unknown configuration requested: " + aConfiguration);
break;

View File

@ -8,6 +8,8 @@ add_task(setup_UITourTest);
// Test that a reset profile dialog appears when "resetFirefox" event is triggered
add_UITour_task(function* test_resetFirefox() {
let canReset = yield getConfigurationPromise("canReset");
ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile.");
let dialogPromise = new Promise((resolve) => {
let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
@ -28,7 +30,19 @@ add_UITour_task(function* test_resetFirefox() {
}
});
});
// make reset possible.
let profileService = Cc["@mozilla.org/toolkit/profile-service;1"].
getService(Ci.nsIToolkitProfileService);
let currentProfileDir = Services.dirsvc.get("ProfD", Ci.nsIFile);
let profileName = "mochitest-test-profile-temp-" + Date.now();
let tempProfile = profileService.createProfile(currentProfileDir, profileName);
canReset = yield getConfigurationPromise("canReset");
ok(canReset, "Should be able to reset from mochitest's temporary profile once it's in the profile manager.");
yield gContentAPI.resetFirefox();
yield dialogPromise;
tempProfile.remove(false);
canReset = yield getConfigurationPromise("canReset");
ok(!canReset, "Shouldn't be able to reset from mochitest's temporary profile once removed from the profile manager.");
});

View File

@ -9,7 +9,7 @@ MOZ_ARG_WITH_STRING(android-cxx-stl,
[ --with-android-cxx-stl=VALUE
use the specified C++ STL (stlport, libstdc++, libc++)],
android_cxx_stl=$withval,
android_cxx_stl=mozstlport)
android_cxx_stl=libc++)
define([MIN_ANDROID_VERSION], [9])
android_version=MIN_ANDROID_VERSION

View File

@ -5230,24 +5230,21 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
// Create a URL to pass all the error information through to the page.
#undef SAFE_ESCAPE
#define SAFE_ESCAPE(cstring, escArg1, escArg2) \
{ \
char* s = nsEscape(escArg1, escArg2); \
if (!s) \
return NS_ERROR_OUT_OF_MEMORY; \
cstring.Adopt(s); \
#define SAFE_ESCAPE(output, input, params) \
if (NS_WARN_IF(!NS_Escape(input, output, params))) { \
return NS_ERROR_OUT_OF_MEMORY; \
}
nsCString escapedUrl, escapedCharset, escapedError, escapedDescription,
escapedCSSClass;
SAFE_ESCAPE(escapedUrl, url.get(), url_Path);
SAFE_ESCAPE(escapedCharset, charset.get(), url_Path);
SAFE_ESCAPE(escapedError,
NS_ConvertUTF16toUTF8(aErrorType).get(), url_Path);
SAFE_ESCAPE(escapedUrl, url, url_Path);
SAFE_ESCAPE(escapedCharset, charset, url_Path);
SAFE_ESCAPE(escapedError, NS_ConvertUTF16toUTF8(aErrorType), url_Path);
SAFE_ESCAPE(escapedDescription,
NS_ConvertUTF16toUTF8(aDescription).get(), url_Path);
NS_ConvertUTF16toUTF8(aDescription), url_Path);
if (aCSSClass) {
SAFE_ESCAPE(escapedCSSClass, aCSSClass, url_Path);
nsCString cssClass(aCSSClass);
SAFE_ESCAPE(escapedCSSClass, cssClass, url_Path);
}
nsCString errorPageUrl("about:");
errorPageUrl.AppendASCII(aErrorPage);
@ -5276,9 +5273,7 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
nsresult rv = GetAppManifestURL(manifestURL);
if (manifestURL.Length() > 0) {
nsCString manifestParam;
SAFE_ESCAPE(manifestParam,
NS_ConvertUTF16toUTF8(manifestURL).get(),
url_Path);
SAFE_ESCAPE(manifestParam, NS_ConvertUTF16toUTF8(manifestURL), url_Path);
errorPageUrl.AppendLiteral("&m=");
errorPageUrl.AppendASCII(manifestParam.get());
}

View File

@ -172,50 +172,69 @@ var gAnimationsTests = [
}
]
},
];
// Test cases that check results of adding/removing a 'width' property on the
// same animation object.
var gAnimationWithGeometricKeyframeTests = [
{
// FIXME: Once we have KeyframeEffect.setFrames, we should rewrite
// this test case to check that runningOnCompositor is restored to true
// after 'width' keyframe is removed from the keyframes.
desc: 'transform on compositor with animation of geometric properties',
desc: 'transform',
frames: {
width: ['100px', '200px'],
transform: ['translate(0px)', 'translate(100px)']
},
expected: [
{
property: 'width',
runningOnCompositor: false
},
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
expected: {
withoutGeometric: [
{
property: 'transform',
runningOnCompositor: true
}
],
withGeometric: [
{
property: 'width',
runningOnCompositor: false
},
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
}
},
{
desc: 'opacity and transform on compositor with animation of geometric ' +
'properties',
desc: 'opacity and transform',
frames: {
width: ['100px', '200px'],
opacity: [0, 1],
transform: ['translate(0px)', 'translate(100px)']
},
expected: [
{
property: 'width',
runningOnCompositor: false
},
{
property: 'opacity',
runningOnCompositor: true
},
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
expected: {
withoutGeometric: [
{
property: 'opacity',
runningOnCompositor: true
},
{
property: 'transform',
runningOnCompositor: true
}
],
withGeometric: [
{
property: 'width',
runningOnCompositor: false
},
{
property: 'opacity',
runningOnCompositor: true
},
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
}
},
];
@ -349,75 +368,106 @@ var gMultipleAsyncAnimationsTests = [
},
];
// FIXME: Once we have KeyframeEffect.setFrames, we should rewrite
// these test cases to check that runningOnCompositor is restored to true
// after 'width' keyframe is removed from the keyframes.
// Test cases that check results of adding/removing a 'width' keyframe on the
// same animation object, where multiple animation objects belong to the same
// element.
// The 'width' property is added to animations[1].
var gMultipleAsyncAnimationsWithGeometricKeyframeTests = [
{
desc: 'transform and opacity with animation of geometric properties',
desc: 'transform and opacity with geometric keyframes',
animations: [
{
frames: {
transform: ['translate(0px)', 'translate(100px)']
},
expected: [
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
expected: {
withoutGeometric: [
{
property: 'transform',
runningOnCompositor: true
}
],
withGeometric: [
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
}
},
{
frames: {
width: ['100px', '200px'],
opacity: [0, 1]
},
expected: [
{
property: 'width',
runningOnCompositor: false,
},
{
property: 'opacity',
runningOnCompositor: true,
}
]
expected: {
withoutGeometric: [
{
property: 'opacity',
runningOnCompositor: true,
}
],
withGeometric: [
{
property: 'width',
runningOnCompositor: false,
},
{
property: 'opacity',
runningOnCompositor: true,
}
]
}
}
],
},
{
desc: 'opacity and transform with animation of geometric properties',
desc: 'opacity and transform with geometric keyframes',
animations: [
{
frames: {
width: ['100px', '200px'],
transform: ['translate(0px)', 'translate(100px)']
},
expected: [
{
property: 'width',
runningOnCompositor: false,
},
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
},
{
frames: {
opacity: [0, 1]
},
expected: [
{
property: 'opacity',
runningOnCompositor: true,
}
]
expected: {
withoutGeometric: [
{
property: 'opacity',
runningOnCompositor: true,
}
],
withGeometric: [
{
property: 'opacity',
runningOnCompositor: true,
}
]
}
},
{
frames: {
transform: ['translate(0px)', 'translate(100px)']
},
expected: {
withoutGeometric: [
{
property: 'transform',
runningOnCompositor: true
}
],
withGeometric: [
{
property: 'width',
runningOnCompositor: false,
},
{
property: 'transform',
runningOnCompositor: false,
warning: 'AnimationWarningTransformWithGeometricProperties'
}
]
}
}
],
]
},
];
@ -544,6 +594,49 @@ function start() {
}, subtest.desc);
});
gAnimationWithGeometricKeyframeTests.forEach(function(subtest) {
promise_test(function(t) {
var animation = addDivAndAnimate(t,
{ class: 'compositable' },
subtest.frames, 100 * MS_PER_SEC);
return animation.ready.then(function() {
// First, a transform animation is running on compositor.
assert_animation_property_state_equals(
animation.effect.getProperties(),
subtest.expected.withoutGeometric);
}).then(function() {
// Add a 'width' property.
var keyframes = animation.effect.getKeyframes();
keyframes[0].width = '100px';
keyframes[1].width = '200px';
animation.effect.setKeyframes(keyframes);
return waitForFrame();
}).then(function() {
// Now the transform animation is not running on compositor because of
// the 'width' property.
assert_animation_property_state_equals(
animation.effect.getProperties(),
subtest.expected.withGeometric);
}).then(function() {
// Remove the 'width' property.
var keyframes = animation.effect.getKeyframes();
delete keyframes[0].width;
delete keyframes[1].width;
animation.effect.setKeyframes(keyframes);
return waitForFrame();
}).then(function() {
// Finally, the transform animation is running on compositor.
assert_animation_property_state_equals(
animation.effect.getProperties(),
subtest.expected.withoutGeometric);
});
}, 'An animation has: ' + subtest.desc);
});
gPerformanceWarningTests.forEach(function(subtest) {
promise_test(function(t) {
var animation = addDivAndAnimate(t,
@ -616,10 +709,44 @@ function start() {
return animation;
});
return waitForAllAnimations(animations).then(function() {
// First, all animations are running on compositor.
animations.forEach(function(anim) {
assert_animation_property_state_equals(
anim.effect.getProperties(),
anim.expected);
anim.expected.withoutGeometric);
});
}).then(function() {
// Add a 'width' property to animations[1].
var keyframes = animations[1].effect.getKeyframes();
keyframes[0].width = '100px';
keyframes[1].width = '200px';
animations[1].effect.setKeyframes(keyframes);
return waitForFrame();
}).then(function() {
// Now the transform animation is not running on compositor because of
// the 'width' property.
animations.forEach(function(anim) {
assert_animation_property_state_equals(
anim.effect.getProperties(),
anim.expected.withGeometric);
});
}).then(function() {
// Remove the 'width' property from animations[1].
var keyframes = animations[1].effect.getKeyframes();
delete keyframes[0].width;
delete keyframes[1].width;
animations[1].effect.setKeyframes(keyframes);
return waitForFrame();
}).then(function() {
// Finally, all animations are running on compositor.
animations.forEach(function(anim) {
assert_animation_property_state_equals(
anim.effect.getProperties(),
anim.expected.withoutGeometric);
});
});
}, 'Multiple animations with geometric property: ' + subtest.desc);

View File

@ -39,6 +39,8 @@ support-files =
mozilla/file_disabled_properties.html
mozilla/file_hide_and_show.html
mozilla/file_partial_keyframes.html
style/file_animation-seeking-with-current-time.html
style/file_animation-seeking-with-start-time.html
testcommon.js
[css-animations/test_animations-dynamic-changes.html]
@ -82,3 +84,5 @@ skip-if = (toolkit == 'gonk' && debug)
[mozilla/test_disabled_properties.html]
[mozilla/test_hide_and_show.html]
[mozilla/test_partial_keyframes.html]
[style/test_animation-seeking-with-current-time.html]
[style/test_animation-seeking-with-start-time.html]

View File

@ -0,0 +1,121 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Tests for seeking using Animation.currentTime</title>
<style>
.animated-div {
margin-left: -10px;
animation-timing-function: linear ! important;
}
@keyframes anim {
from { margin-left: 0px; }
to { margin-left: 100px; }
}
</style>
<script src="../testcommon.js"></script>
</head>
<body>
<script type="text/javascript">
'use strict';
function assert_marginLeft_equals(target, expect, description) {
var marginLeft = parseFloat(getComputedStyle(target).marginLeft);
assert_equals(marginLeft, expect, description);
}
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function() {
animation.currentTime = 90 * MS_PER_SEC;
assert_marginLeft_equals(div, 90,
'Computed style is updated when seeking forwards in active interval');
animation.currentTime = 10 * MS_PER_SEC;
assert_marginLeft_equals(div, 10,
'Computed style is updated when seeking backwards in active interval');
});
}, 'Seeking forwards and backward in active interval');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
assert_marginLeft_equals(div, -10,
'Computed style is unaffected in before phase with no backwards fill');
// before -> active (non-active -> active)
animation.currentTime = 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed style is updated when seeking forwards from ' +
'not \'in effect\' to \'in effect\' state');
});
}, 'Seeking to non-\'in effect\' from \'in effect\' (before -> active)');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
// move to after phase
animation.currentTime = 250 * MS_PER_SEC;
assert_marginLeft_equals(div, -10,
'Computed style is unaffected in after phase with no forwards fill');
// after -> active (non-active -> active)
animation.currentTime = 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed style is updated when seeking backwards from ' +
'not \'in effect\' to \'in effect\' state');
});
}, 'Seeking to non-\'in effect\' from \'in effect\' (after -> active)');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
// move to active phase
animation.currentTime = 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed value is set during active phase');
// active -> before
animation.currentTime = 50 * MS_PER_SEC;
assert_marginLeft_equals(div, -10,
'Computed value is not effected after seeking backwards from ' +
'\'in effect\' to not \'in effect\' state');
});
}, 'Seeking to \'in effect\' from non-\'in effect\' (active -> before)');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
// move to active phase
animation.currentTime = 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed value is set during active phase');
// active -> after
animation.currentTime = 250 * MS_PER_SEC;
assert_marginLeft_equals(div, -10,
'Computed value is not affected after seeking forwards from ' +
'\'in effect\' to not \'in effect\' state');
});
}, 'Seeking to \'in effect\' from non-\'in effect\' (active -> after)');
done();
</script>
</body>
</html>

View File

@ -0,0 +1,121 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Tests for seeking using Animation.startTime</title>
<style>
.animated-div {
margin-left: -10px;
animation-timing-function: linear ! important;
}
@keyframes anim {
from { margin-left: 0px; }
to { margin-left: 100px; }
}
</style>
<script src="../testcommon.js"></script>
</head>
<body>
<script type="text/javascript">
'use strict';
function assert_marginLeft_equals(target, expect, description) {
var marginLeft = parseFloat(getComputedStyle(target).marginLeft);
assert_equals(marginLeft, expect, description);
}
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function() {
animation.startTime = animation.timeline.currentTime - 90 * MS_PER_SEC
assert_marginLeft_equals(div, 90,
'Computed style is updated when seeking forwards in active interval');
animation.startTime = animation.timeline.currentTime - 10 * MS_PER_SEC;
assert_marginLeft_equals(div, 10,
'Computed style is updated when seeking backwards in active interval');
});
}, 'Seeking forwards and backward in active interval');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
assert_marginLeft_equals(div, -10,
'Computed style is unaffected in before phase with no backwards fill');
// before -> active (non-active -> active)
animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed style is updated when seeking forwards from ' +
'not \'in effect\' to \'in effect\' state');
});
}, 'Seeking to non-\'in effect\' from \'in effect\' (before -> active)');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
// move to after phase
animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
assert_marginLeft_equals(div, -10,
'Computed style is unaffected in after phase with no forwards fill');
// after -> active (non-active -> active)
animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed style is updated when seeking backwards from ' +
'not \'in effect\' to \'in effect\' state');
});
}, 'Seeking to non-\'in effect\' from \'in effect\' (after -> active)');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
// move to active phase
animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed value is set during active phase');
// active -> before
animation.startTime = animation.timeline.currentTime - 50 * MS_PER_SEC;
assert_marginLeft_equals(div, -10,
'Computed value is not affected after seeking backwards from ' +
'\'in effect\' to not \'in effect\' state');
});
}, 'Seeking to \'in effect\' from non-\'in effect\' (active -> before)');
promise_test(function(t) {
var div = addDiv(t, {'class': 'animated-div'});
div.style.animation = "anim 100s 100s";
var animation = div.getAnimations()[0];
return animation.ready.then(function(t) {
// move to active phase
animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
assert_marginLeft_equals(div, 50,
'Computed value is set during active phase');
// active -> after
animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
assert_marginLeft_equals(div, -10,
'Computed value is not affected after seeking forwards from ' +
'\'in effect\' to not \'in effect\' state');
});
}, 'Seeking to \'in effect\' from non-\'in effect\' (active -> after)');
done();
</script>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
{ "set": [["dom.animations-api.core.enabled", true]]},
function() {
window.open("file_animation-seeking-with-current-time.html");
});
</script>
</html>

View File

@ -0,0 +1,15 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
{ "set": [["dom.animations-api.core.enabled", true]]},
function() {
window.open("file_animation-seeking-with-start-time.html");
});
</script>
</html>

View File

@ -2181,6 +2181,13 @@ GK_ATOM(TypingTxnName, "Typing")
GK_ATOM(IMETxnName, "IME")
GK_ATOM(DeleteTxnName, "Deleting")
// Font families
GK_ATOM(serif, "serif")
GK_ATOM(sans_serif, "sans-serif")
GK_ATOM(cursive, "cursive")
GK_ATOM(fantasy, "fantasy")
GK_ATOM(monospace, "monospace")
// IPC stuff
GK_ATOM(Remote, "remote")
GK_ATOM(RemoteId, "_remote_id")
@ -2433,3 +2440,15 @@ GK_ATOM(vr_state, "vr-state")
// Contextual Identity / Containers
GK_ATOM(usercontextid, "usercontextid")
// Namespaces
GK_ATOM(nsuri_xmlns, "http://www.w3.org/2000/xmlns/")
GK_ATOM(nsuri_xml, "http://www.w3.org/XML/1998/namespace")
GK_ATOM(nsuri_xhtml, "http://www.w3.org/1999/xhtml")
GK_ATOM(nsuri_xlink, "http://www.w3.org/1999/xlink")
GK_ATOM(nsuri_xslt, "http://www.w3.org/1999/XSL/Transform")
GK_ATOM(nsuri_xbl, "http://www.mozilla.org/xbl")
GK_ATOM(nsuri_mathml, "http://www.w3.org/1998/Math/MathML")
GK_ATOM(nsuri_rdf, "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
GK_ATOM(nsuri_xul, "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")
GK_ATOM(nsuri_svg, "http://www.w3.org/2000/svg")

View File

@ -16,6 +16,7 @@
#include "mozilla/dom/NodeInfo.h"
#include "nsCOMArray.h"
#include "nsContentCreatorFunctions.h"
#include "nsGkAtoms.h"
#include "nsString.h"
#include "mozilla/dom/NodeInfo.h"
#include "mozilla/ClearOnShutdown.h"
@ -25,17 +26,6 @@
using namespace mozilla;
using namespace mozilla::dom;
#define kXMLNSNameSpaceURI "http://www.w3.org/2000/xmlns/"
#define kXMLNameSpaceURI "http://www.w3.org/XML/1998/namespace"
#define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml"
#define kXLinkNameSpaceURI "http://www.w3.org/1999/xlink"
#define kXSLTNameSpaceURI "http://www.w3.org/1999/XSL/Transform"
#define kXBLNameSpaceURI "http://www.mozilla.org/xbl"
#define kMathMLNameSpaceURI "http://www.w3.org/1998/Math/MathML"
#define kRDFNameSpaceURI "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define kXULNameSpaceURI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
#define kSVGNameSpaceURI "http://www.w3.org/2000/svg"
StaticAutoPtr<nsNameSpaceManager> nsNameSpaceManager::sInstance;
/* static */ nsNameSpaceManager*
@ -57,20 +47,20 @@ bool nsNameSpaceManager::Init()
{
nsresult rv;
#define REGISTER_NAMESPACE(uri, id) \
rv = AddNameSpace(NS_LITERAL_STRING(uri), id); \
rv = AddNameSpace(dont_AddRef(uri), id); \
NS_ENSURE_SUCCESS(rv, false)
// Need to be ordered according to ID.
REGISTER_NAMESPACE(kXMLNSNameSpaceURI, kNameSpaceID_XMLNS);
REGISTER_NAMESPACE(kXMLNameSpaceURI, kNameSpaceID_XML);
REGISTER_NAMESPACE(kXHTMLNameSpaceURI, kNameSpaceID_XHTML);
REGISTER_NAMESPACE(kXLinkNameSpaceURI, kNameSpaceID_XLink);
REGISTER_NAMESPACE(kXSLTNameSpaceURI, kNameSpaceID_XSLT);
REGISTER_NAMESPACE(kXBLNameSpaceURI, kNameSpaceID_XBL);
REGISTER_NAMESPACE(kMathMLNameSpaceURI, kNameSpaceID_MathML);
REGISTER_NAMESPACE(kRDFNameSpaceURI, kNameSpaceID_RDF);
REGISTER_NAMESPACE(kXULNameSpaceURI, kNameSpaceID_XUL);
REGISTER_NAMESPACE(kSVGNameSpaceURI, kNameSpaceID_SVG);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xmlns, kNameSpaceID_XMLNS);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xml, kNameSpaceID_XML);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xhtml, kNameSpaceID_XHTML);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xlink, kNameSpaceID_XLink);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xslt, kNameSpaceID_XSLT);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xbl, kNameSpaceID_XBL);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_MathML);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_rdf, kNameSpaceID_RDF);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_svg, kNameSpaceID_SVG);
#undef REGISTER_NAMESPACE
@ -87,11 +77,12 @@ nsNameSpaceManager::RegisterNameSpace(const nsAString& aURI,
return NS_OK;
}
nsCOMPtr<nsIAtom> atom = NS_Atomize(aURI);
nsresult rv = NS_OK;
if (!mURIToIDTable.Get(&aURI, &aNameSpaceID)) {
if (!mURIToIDTable.Get(atom, &aNameSpaceID)) {
aNameSpaceID = mURIArray.Length() + 1; // id is index + 1
rv = AddNameSpace(aURI, aNameSpaceID);
rv = AddNameSpace(atom.forget(), aNameSpaceID);
if (NS_FAILED(rv)) {
aNameSpaceID = kNameSpaceID_Unknown;
}
@ -114,7 +105,7 @@ nsNameSpaceManager::GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI)
return NS_ERROR_ILLEGAL_VALUE;
}
aURI = *mURIArray.ElementAt(index);
mURIArray.ElementAt(index)->ToString(aURI);
return NS_OK;
}
@ -128,7 +119,8 @@ nsNameSpaceManager::GetNameSpaceID(const nsAString& aURI)
int32_t nameSpaceID;
if (mURIToIDTable.Get(&aURI, &nameSpaceID)) {
nsCOMPtr<nsIAtom> atom = NS_Atomize(aURI);
if (mURIToIDTable.Get(atom, &nameSpaceID)) {
NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
return nameSpaceID;
}
@ -177,9 +169,10 @@ nsNameSpaceManager::HasElementCreator(int32_t aNameSpaceID)
false;
}
nsresult nsNameSpaceManager::AddNameSpace(const nsAString& aURI,
nsresult nsNameSpaceManager::AddNameSpace(already_AddRefed<nsIAtom> aURI,
const int32_t aNameSpaceID)
{
nsCOMPtr<nsIAtom> uri = aURI;
if (aNameSpaceID < 0) {
// We've wrapped... Can't do anything else here; just bail.
return NS_ERROR_OUT_OF_MEMORY;
@ -188,13 +181,8 @@ nsresult nsNameSpaceManager::AddNameSpace(const nsAString& aURI,
NS_ASSERTION(aNameSpaceID - 1 == (int32_t) mURIArray.Length(),
"BAD! AddNameSpace not called in right order!");
nsString* uri = new nsString(aURI);
if (!mURIArray.AppendElement(uri)) {
delete uri;
return NS_ERROR_OUT_OF_MEMORY;
}
mURIToIDTable.Put(uri, aNameSpaceID);
mURIArray.AppendElement(uri.forget());
mURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID);
return NS_OK;
}

View File

@ -8,50 +8,14 @@
#define nsNameSpaceManager_h___
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsIAtom.h"
#include "nsTArray.h"
#include "mozilla/StaticPtr.h"
class nsAString;
class nsNameSpaceKey : public PLDHashEntryHdr
{
public:
typedef const nsAString* KeyType;
typedef const nsAString* KeyTypePointer;
explicit nsNameSpaceKey(KeyTypePointer aKey) : mKey(aKey)
{
}
nsNameSpaceKey(const nsNameSpaceKey& toCopy) : mKey(toCopy.mKey)
{
}
KeyType GetKey() const
{
return mKey;
}
bool KeyEquals(KeyType aKey) const
{
return mKey->Equals(*aKey);
}
static KeyTypePointer KeyToPointer(KeyType aKey)
{
return aKey;
}
static PLDHashNumber HashKey(KeyTypePointer aKey) {
return mozilla::HashString(*aKey);
}
enum {
ALLOW_MEMMOVE = true
};
private:
const nsAString* mKey;
};
/**
* The Name Space Manager tracks the association between a NameSpace
* URI and the int32_t runtime id. Mappings between NameSpaces and
@ -75,6 +39,12 @@ public:
int32_t& aNameSpaceID);
virtual nsresult GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI);
nsIAtom* NameSpaceURIAtom(int32_t aNameSpaceID) {
MOZ_ASSERT(aNameSpaceID > 0 && (int64_t) aNameSpaceID <= (int64_t) mURIArray.Length());
return mURIArray.ElementAt(aNameSpaceID - 1); // id is index + 1
}
virtual int32_t GetNameSpaceID(const nsAString& aURI);
virtual bool HasElementCreator(int32_t aNameSpaceID);
@ -82,10 +52,10 @@ public:
static nsNameSpaceManager* GetInstance();
private:
bool Init();
nsresult AddNameSpace(const nsAString& aURI, const int32_t aNameSpaceID);
nsresult AddNameSpace(already_AddRefed<nsIAtom> aURI, const int32_t aNameSpaceID);
nsDataHashtable<nsNameSpaceKey,int32_t> mURIToIDTable;
nsTArray< nsAutoPtr<nsString> > mURIArray;
nsDataHashtable<nsISupportsHashKey, int32_t> mURIToIDTable;
nsTArray<nsCOMPtr<nsIAtom>> mURIArray;
static mozilla::StaticAutoPtr<nsNameSpaceManager> sInstance;
};

View File

@ -194,9 +194,9 @@ nsXHTMLContentSerializer::EscapeURI(nsIContent* aContent, const nsAString& aURI,
if (textToSubURI && !IsASCII(part)) {
rv = textToSubURI->ConvertAndEscape(mCharset.get(), part.get(), getter_Copies(escapedURI));
NS_ENSURE_SUCCESS(rv, rv);
}
else {
escapedURI.Adopt(nsEscape(NS_ConvertUTF16toUTF8(part).get(), url_Path));
} else if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(part), escapedURI,
url_Path))) {
return NS_ERROR_OUT_OF_MEMORY;
}
AppendASCIItoUTF16(escapedURI, aEscapedURI);
@ -212,9 +212,9 @@ nsXHTMLContentSerializer::EscapeURI(nsIContent* aContent, const nsAString& aURI,
if (textToSubURI) {
rv = textToSubURI->ConvertAndEscape(mCharset.get(), part.get(), getter_Copies(escapedURI));
NS_ENSURE_SUCCESS(rv, rv);
}
else {
escapedURI.Adopt(nsEscape(NS_ConvertUTF16toUTF8(part).get(), url_Path));
} else if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(part), escapedURI,
url_Path))) {
return NS_ERROR_OUT_OF_MEMORY;
}
AppendASCIItoUTF16(escapedURI, aEscapedURI);
}

View File

@ -26,7 +26,6 @@ const METHODS = {
findNext: {},
clearMatch: {},
executeScript: { alwaysFails: true }, // needs browser:universalxss
getStructuredData: {},
getWebManifest: {},
mute: {},
unmute: {},

View File

@ -13,7 +13,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Microformats.js");
Cu.import("resource://gre/modules/ExtensionContent.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "acs",
@ -285,7 +284,6 @@ BrowserElementChild.prototype = {
"get-audio-channel-muted": this._recvGetAudioChannelMuted,
"set-audio-channel-muted": this._recvSetAudioChannelMuted,
"get-is-audio-channel-active": this._recvIsAudioChannelActive,
"get-structured-data": this._recvGetStructuredData,
"get-web-manifest": this._recvGetWebManifest,
}
@ -1546,300 +1544,6 @@ BrowserElementChild.prototype = {
sendAsyncMsg('got-set-input-method-active', msgData);
},
_processMicroformatValue(field, value) {
if (['node', 'resolvedNode', 'semanticType'].includes(field)) {
return null;
} else if (Array.isArray(value)) {
var result = value.map(i => this._processMicroformatValue(field, i))
.filter(i => i !== null);
return result.length ? result : null;
} else if (typeof value == 'string') {
return value;
} else if (typeof value == 'object' && value !== null) {
return this._processMicroformatItem(value);
}
return null;
},
// This function takes legacy Microformat data (hCard and hCalendar)
// and produces the same result that the equivalent Microdata data
// would produce.
_processMicroformatItem(microformatData) {
var result = {};
if (microformatData.semanticType == 'geo') {
return microformatData.latitude + ';' + microformatData.longitude;
}
if (microformatData.semanticType == 'hCard') {
result.type = ["http://microformats.org/profile/hcard"];
} else if (microformatData.semanticType == 'hCalendar') {
result.type = ["http://microformats.org/profile/hcalendar#vevent"];
}
for (let field of Object.getOwnPropertyNames(microformatData)) {
var processed = this._processMicroformatValue(field, microformatData[field]);
if (processed === null) {
continue;
}
if (!result.properties) {
result.properties = {};
}
if (Array.isArray(processed)) {
result.properties[field] = processed;
} else {
result.properties[field] = [processed];
}
}
return result;
},
_findItemProperties: function(node, properties, alreadyProcessed) {
if (node.itemProp) {
var value;
if (node.itemScope) {
value = this._processItem(node, alreadyProcessed);
} else {
value = node.itemValue;
}
for (let i = 0; i < node.itemProp.length; ++i) {
var property = node.itemProp[i];
if (!properties[property]) {
properties[property] = [];
}
properties[property].push(value);
}
}
if (!node.itemScope) {
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
}
},
_processItem: function(node, alreadyProcessed = []) {
if (alreadyProcessed.includes(node)) {
return "ERROR";
}
alreadyProcessed.push(node);
var result = {};
if (node.itemId) {
result.id = node.itemId;
}
if (node.itemType) {
result.type = [];
for (let i = 0; i < node.itemType.length; ++i) {
result.type.push(node.itemType[i]);
}
}
var properties = {};
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
if (node.itemRef) {
for (let i = 0; i < node.itemRef.length; ++i) {
var refNode = content.document.getElementById(node.itemRef[i]);
this._findItemProperties(refNode, properties, alreadyProcessed);
}
}
result.properties = properties;
return result;
},
_recvGetStructuredData: function(data) {
var result = {
items: []
};
var microdataItems = content.document.getItems();
for (let microdataItem of microdataItems) {
result.items.push(this._processItem(microdataItem));
}
var hCardItems = Microformats.get("hCard", content.document);
for (let hCardItem of hCardItems) {
if (!hCardItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCardItem));
}
}
var hCalendarItems = Microformats.get("hCalendar", content.document);
for (let hCalendarItem of hCalendarItems) {
if (!hCalendarItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCalendarItem));
}
}
var resultString = JSON.stringify(result);
sendAsyncMsg('got-structured-data', {
id: data.json.id,
successRv: resultString
});
},
_processMicroformatValue(field, value) {
if (['node', 'resolvedNode', 'semanticType'].includes(field)) {
return null;
} else if (Array.isArray(value)) {
var result = value.map(i => this._processMicroformatValue(field, i))
.filter(i => i !== null);
return result.length ? result : null;
} else if (typeof value == 'string') {
return value;
} else if (typeof value == 'object' && value !== null) {
return this._processMicroformatItem(value);
}
return null;
},
// This function takes legacy Microformat data (hCard and hCalendar)
// and produces the same result that the equivalent Microdata data
// would produce.
_processMicroformatItem(microformatData) {
var result = {};
if (microformatData.semanticType == 'geo') {
return microformatData.latitude + ';' + microformatData.longitude;
}
if (microformatData.semanticType == 'hCard') {
result.type = ["http://microformats.org/profile/hcard"];
} else if (microformatData.semanticType == 'hCalendar') {
result.type = ["http://microformats.org/profile/hcalendar#vevent"];
}
for (let field of Object.getOwnPropertyNames(microformatData)) {
var processed = this._processMicroformatValue(field, microformatData[field]);
if (processed === null) {
continue;
}
if (!result.properties) {
result.properties = {};
}
if (Array.isArray(processed)) {
result.properties[field] = processed;
} else {
result.properties[field] = [processed];
}
}
return result;
},
_findItemProperties: function(node, properties, alreadyProcessed) {
if (node.itemProp) {
var value;
if (node.itemScope) {
value = this._processItem(node, alreadyProcessed);
} else {
value = node.itemValue;
}
for (let i = 0; i < node.itemProp.length; ++i) {
var property = node.itemProp[i];
if (!properties[property]) {
properties[property] = [];
}
properties[property].push(value);
}
}
if (!node.itemScope) {
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
}
},
_processItem: function(node, alreadyProcessed = []) {
if (alreadyProcessed.includes(node)) {
return "ERROR";
}
alreadyProcessed.push(node);
var result = {};
if (node.itemId) {
result.id = node.itemId;
}
if (node.itemType) {
result.type = [];
for (let i = 0; i < node.itemType.length; ++i) {
result.type.push(node.itemType[i]);
}
}
var properties = {};
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
if (node.itemRef) {
for (let i = 0; i < node.itemRef.length; ++i) {
var refNode = content.document.getElementById(node.itemRef[i]);
this._findItemProperties(refNode, properties, alreadyProcessed);
}
}
result.properties = properties;
return result;
},
_recvGetStructuredData: function(data) {
var result = {
items: []
};
var microdataItems = content.document.getItems();
for (let microdataItem of microdataItems) {
result.items.push(this._processItem(microdataItem));
}
var hCardItems = Microformats.get("hCard", content.document);
for (let hCardItem of hCardItems) {
if (!hCardItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCardItem));
}
}
var hCalendarItems = Microformats.get("hCalendar", content.document);
for (let hCalendarItem of hCalendarItems) {
if (!hCalendarItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCalendarItem));
}
}
var resultString = JSON.stringify(result);
sendAsyncMsg('got-structured-data', {
id: data.json.id,
successRv: resultString
});
},
// The docShell keeps a weak reference to the progress listener, so we need
// to keep a strong ref to it ourselves.
_progressListener: {

View File

@ -389,7 +389,6 @@ BrowserElementParent.prototype = {
"got-audio-channel-muted": this._gotDOMRequestResult,
"got-set-audio-channel-muted": this._gotDOMRequestResult,
"got-is-audio-channel-active": this._gotDOMRequestResult,
"got-structured-data": this._gotDOMRequestResult,
"got-web-manifest": this._gotDOMRequestResult,
};
@ -1208,8 +1207,6 @@ BrowserElementParent.prototype = {
return req;
},
getStructuredData: defineDOMRequestMethod('get-structured-data'),
getWebManifest: defineDOMRequestMethod('get-web-manifest'),
/**
* Called when the visibility of the window which owns this iframe changes.

View File

@ -1,111 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*globals async, is, SimpleTest, browserElementTestHelpers*/
// Bug 119580 - getStructuredData tests
'use strict';
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
const EMPTY_URL = 'file_empty.html';
const MICRODATA_URL = 'file_microdata.html';
const MICRODATA_ITEMREF_URL = 'file_microdata_itemref.html';
const MICRODATA_BAD_ITEMREF_URL = 'file_microdata_bad_itemref.html';
const MICROFORMATS_URL = 'file_microformats.html';
var test1 = async(function* () {
var structuredData = yield requestStructuredData(EMPTY_URL);
is(structuredData.items && structuredData.items.length, 0,
'There should be 0 items.');
});
var test2 = async(function* () {
var structuredData = yield requestStructuredData(MICRODATA_URL);
is(structuredData.items && structuredData.items.length, 2,
'There should be two items.');
is(structuredData.items[0].type[0], 'http://schema.org/Recipe',
'Can get item type.');
is(structuredData.items[0].properties['datePublished'][0], '2009-05-08',
'Can get item property.');
is(structuredData.items[1]
.properties["aggregateRating"][0]
.properties["ratingValue"][0],
'4', 'Can get nested item property.');
});
var test3 = async(function* () {
var structuredData = yield requestStructuredData(MICROFORMATS_URL);
is(structuredData.items && structuredData.items.length, 2,
'There should be two items.');
is(structuredData.items[0].type[0], 'http://microformats.org/profile/hcard',
'Got hCard object.');
is(structuredData.items[0]
.properties["adr"][0]
.properties["country-name"][0],
'France', 'Can read hCard properties.');
is(structuredData.items[0]
.properties["adr"][0]
.properties["type"]
.includes('home') &&
structuredData.items[0]
.properties["adr"][0]
.properties["type"]
.includes('postal'),
true, 'Property can contain multiple values.');
is(structuredData.items[0]
.properties["geo"][0],
'48.816667;2.366667', 'Geo value is formatted as per WHATWG spec.');
is(structuredData.items[1].type[0],
'http://microformats.org/profile/hcalendar#vevent',
'Got hCalendar object.');
is(structuredData.items[1]
.properties["dtstart"][0],
'2005-10-05', 'Can read hCalendar properties');
});
var test4 = async(function* () {
var structuredData = yield requestStructuredData(MICRODATA_ITEMREF_URL);
is(structuredData.items[0].properties["license"][0],
'http://www.opensource.org/licenses/mit-license.php', 'itemref works.');
is(structuredData.items[1].properties["license"][0],
'http://www.opensource.org/licenses/mit-license.php',
'Two items can successfully share an itemref.');
});
var test5 = async(function* () {
var structuredData = yield requestStructuredData(MICRODATA_BAD_ITEMREF_URL);
is(structuredData.items[0]
.properties["band"][0]
.properties["cycle"][0]
.properties["band"][0],
'ERROR', 'Cyclic reference should be detected as an error.');
});
Promise
.all([test1(), test2(), test3(), test4(), test5()])
.then(SimpleTest.finish);
function requestStructuredData(url) {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.src = url;
document.body.appendChild(iframe);
return new Promise((resolve, reject) => {
iframe.addEventListener('mozbrowserloadend', function loadend() {
iframe.removeEventListener('mozbrowserloadend', loadend);
SimpleTest.executeSoon(() => {
var req = iframe.getStructuredData();
req.onsuccess = (ev) => {
document.body.removeChild(iframe);
resolve(JSON.parse(req.result));
};
req.onerror = (ev) => {
document.body.removeChild(iframe);
reject(new Error(req.error));
};
});
});
});
}

View File

@ -14,7 +14,6 @@ support-files =
[test_browserElement_oop_AudioChannelSeeking.html]
tags = audiochannel
[test_browserElement_oop_getStructuredData.html]
[test_browserElement_oop_Viewmode.html]
[test_browserElement_oop_ThemeColor.html]
[test_browserElement_inproc_ErrorSecurity.html]

View File

@ -41,7 +41,6 @@ support-files =
browserElement_FrameWrongURI.js
browserElement_GetScreenshot.js
browserElement_GetScreenshotDppx.js
browserElement_getStructuredData.js
browserElement_getWebManifest.js
browserElement_Iconchange.js
browserElement_LoadEvents.js
@ -265,7 +264,6 @@ tags = audiochannel
[test_browserElement_inproc_AudioChannel_nested.html]
tags = audiochannel
[test_browserElement_inproc_SetNFCFocus.html]
[test_browserElement_inproc_getStructuredData.html]
[test_browserElement_inproc_OpenWindowEmpty.html]
skip-if = (toolkit == 'gonk') # Test doesn't work on B2G emulator
[test_browserElement_inproc_ActiveStateChangeOnChangingMutedOrVolume.html]

View File

@ -1,14 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 1195801</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8" src="async.js"></script>
<script type="application/javascript;version=1.8" src="browserElement_getStructuredData.js"></script>
</script>
</body>
</html>

View File

@ -1,14 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 1195801</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8" src="async.js"></script>
<script type="application/javascript;version=1.8" src="browserElement_getStructuredData.js"></script>
</script>
</body>
</html>

View File

@ -110,16 +110,4 @@ interface nsIBrowserElementAPI : nsISupports
* http://w3c.github.io/manifest/
*/
nsIDOMDOMRequest getWebManifest();
/**
* Returns a JSON string representing Microdata objects on the page.
* Format is described at:
* https://html.spec.whatwg.org/multipage/microdata.html#json
*
* Also contains hCard and hCalendar objects after converting them
* to equivalent Microdata objects described at:
* https://html.spec.whatwg.org/multipage/microdata.html#vcard
* https://html.spec.whatwg.org/multipage/microdata.html#vevent
*/
nsIDOMDOMRequest getStructuredData();
};

View File

@ -572,7 +572,7 @@ nsGonkCameraControl::PushParameters()
if (NS_GetCurrentThread() != mCameraThread) {
DOM_CAMERA_LOGT("%s:%d - dispatching to Camera Thread\n", __func__, __LINE__);
nsCOMPtr<nsIRunnable> pushParametersTask =
NS_NewRunnableMethod(this, &nsGonkCameraControl::PushParametersImpl);
NewRunnableMethod(this, &nsGonkCameraControl::PushParametersImpl);
return mCameraThread->Dispatch(pushParametersTask, NS_DISPATCH_NORMAL);
}

View File

@ -470,6 +470,7 @@ static const DOMTokenListSupportedToken sSupportedRelValues[] = {
"alternate",
"preconnect",
"icon",
"search",
nullptr
};

View File

@ -785,22 +785,6 @@ nsBrowserElement::ExecuteScript(const nsAString& aScript,
return req.forget().downcast<DOMRequest>();
}
already_AddRefed<DOMRequest>
nsBrowserElement::GetStructuredData(ErrorResult& aRv)
{
NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
nsCOMPtr<nsIDOMDOMRequest> req;
nsresult rv = mBrowserElementAPI->GetStructuredData(getter_AddRefs(req));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
return req.forget().downcast<DOMRequest>();
}
already_AddRefed<DOMRequest>
nsBrowserElement::GetWebManifest(ErrorResult& aRv)
{

View File

@ -112,8 +112,6 @@ public:
const dom::BrowserElementExecuteScriptOptions& aOptions,
ErrorResult& aRv);
already_AddRefed<dom::DOMRequest> GetStructuredData(ErrorResult& aRv);
already_AddRefed<dom::DOMRequest> GetWebManifest(ErrorResult& aRv);
void SetNFCFocus(bool isFocus,

View File

@ -281,8 +281,10 @@ nsFSURLEncoded::GetEncodedSubmission(nsIURI* aURI,
HandleMailtoSubject(path);
// Append the body to and force-plain-text args to the mailto line
nsCString escapedBody;
escapedBody.Adopt(nsEscape(mQueryString.get(), url_XAlphas));
nsAutoCString escapedBody;
if (NS_WARN_IF(!NS_Escape(mQueryString, escapedBody, url_XAlphas))) {
return NS_ERROR_OUT_OF_MEMORY;
}
path += NS_LITERAL_CSTRING("&force-plain-text=Y&body=") + escapedBody;
@ -666,11 +668,11 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
HandleMailtoSubject(path);
// Append the body to and force-plain-text args to the mailto line
char* escapedBuf = nsEscape(NS_ConvertUTF16toUTF8(mBody).get(),
url_XAlphas);
NS_ENSURE_TRUE(escapedBuf, NS_ERROR_OUT_OF_MEMORY);
nsCString escapedBody;
escapedBody.Adopt(escapedBuf);
nsAutoCString escapedBody;
if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(mBody), escapedBody,
url_XAlphas))) {
return NS_ERROR_OUT_OF_MEMORY;
}
path += NS_LITERAL_CSTRING("&force-plain-text=Y&body=") + escapedBody;

View File

@ -169,7 +169,7 @@ NuwaParent::RecvNotifyReady()
// mContentParent have to go the the main thread. The mContentParent will
// be alive when the runnable runs.
nsCOMPtr<nsIRunnable> runnable =
NS_NewNonOwningRunnableMethod(mContentParent.get(),
NewNonOwningRunnableMethod(mContentParent.get(),
&ContentParent::OnNuwaReady);
MOZ_ASSERT(runnable);
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
@ -200,7 +200,7 @@ NuwaParent::RecvAddNewProcess(const uint32_t& aPid,
mBlocked = false;
} else {
nsCOMPtr<nsIRunnable> runnable =
NS_NewNonOwningRunnableMethodWithArgs<
NewNonOwningRunnableMethod<
uint32_t,
UniquePtr<nsTArray<ProtocolFdMapping>>&& >(
mContentParent.get(),

View File

@ -242,7 +242,7 @@ PreallocatedProcessManagerImpl::ScheduleDelayedNuwaFork()
return;
}
RefPtr<CancelableRunnable> task = NS_NewCancelableRunnableMethod(
RefPtr<CancelableRunnable> task = NewCancelableRunnableMethod(
this, &PreallocatedProcessManagerImpl::DelayedNuwaFork);
mPreallocateAppProcessTask = task;
MessageLoop::current()->PostDelayedTask(task.forget(),

View File

@ -201,6 +201,13 @@ public:
virtual media::TimeIntervals GetBuffered() = 0;
// By default, it is assumed that the entire resource can be evicted once
// all samples have been demuxed.
virtual int64_t GetEvictionOffset(const media::TimeUnit& aTime)
{
return INT64_MAX;
}
// If the MediaTrackDemuxer and MediaDataDemuxer hold cross references.
// BreakCycles must be overridden.
virtual void BreakCycles()

View File

@ -1269,9 +1269,21 @@ TrackBuffersManager::CompleteCodedFrameProcessing()
// 6. Remove the media segment bytes from the beginning of the input buffer.
// Clear our demuxer from any already processed data.
// As we have handled a complete media segment, it is safe to evict all data
// from the resource.
mCurrentInputBuffer->EvictAll();
int64_t safeToEvict = std::min(
HasVideo()
? mVideoTracks.mDemuxer->GetEvictionOffset(mVideoTracks.mLastParsedEndTime)
: INT64_MAX,
HasAudio()
? mAudioTracks.mDemuxer->GetEvictionOffset(mAudioTracks.mLastParsedEndTime)
: INT64_MAX);
ErrorResult rv;
mCurrentInputBuffer->EvictBefore(safeToEvict, rv);
if (rv.Failed()) {
rv.SuppressException();
RejectProcessing(NS_ERROR_OUT_OF_MEMORY, __func__);
return;
}
mInputDemuxer->NotifyDataRemoved();
RecreateParser(true);
@ -1642,9 +1654,11 @@ TrackBuffersManager::InsertFrames(TrackBuffer& aSamples,
// We allow a fuzz factor in our interval of half a frame length,
// as fuzz is +/- value, giving an effective leeway of a full frame
// length.
TimeIntervals range(aIntervals);
range.SetFuzz(trackBuffer.mLongestFrameDuration / 2);
trackBuffer.mSanitizedBufferedRanges += range;
if (aIntervals.Length()) {
TimeIntervals range(aIntervals);
range.SetFuzz(trackBuffer.mLongestFrameDuration / 2);
trackBuffer.mSanitizedBufferedRanges += range;
}
}
void

View File

@ -11,7 +11,7 @@
#include "AbstractMediaDecoder.h"
#include "AudioChannelService.h"
#include "MediaStreamSource.h"
#include "gfxPrefs.h"
#include "MediaPrefs.h"
#ifdef MOZ_AUDIO_OFFLOAD
#include <stagefright/Utils.h>
@ -35,7 +35,7 @@ MediaOmxCommonReader::MediaOmxCommonReader(AbstractMediaDecoder *aDecoder)
bool MediaOmxCommonReader::IsMonoAudioEnabled()
{
return gfxPrefs::MonoAudio();
return MediaPrefs::MonoAudio();
}
#ifdef MOZ_AUDIO_OFFLOAD

View File

@ -59,9 +59,7 @@ AgnosticDecoderModule::CreateAudioDecoder(const AudioInfo& aConfig,
aAudioTaskQueue,
aCallback);
} else if (WaveDataDecoder::IsWave(aConfig.mMimeType)) {
m = new WaveDataDecoder(*aConfig.GetAsAudioInfo(),
aAudioTaskQueue,
aCallback);
m = new WaveDataDecoder(*aConfig.GetAsAudioInfo(), aCallback);
}
return m.forget();

View File

@ -47,13 +47,9 @@ DecodeULawSample(uint8_t aValue)
}
WaveDataDecoder::WaveDataDecoder(const AudioInfo& aConfig,
TaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback)
: mInfo(aConfig)
, mTaskQueue(aTaskQueue)
, mCallback(aCallback)
, mIsFlushing(false)
, mFrames(0)
{
}
@ -72,32 +68,15 @@ WaveDataDecoder::Init()
nsresult
WaveDataDecoder::Input(MediaRawData* aSample)
{
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>(
this, &WaveDataDecoder::ProcessDecode, aSample));
return NS_OK;
}
void
WaveDataDecoder::ProcessDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mIsFlushing) {
return;
}
if (!DoDecode(aSample)) {
mCallback->Error();
} else if (mTaskQueue->IsEmpty()) {
mCallback->InputExhausted();
}
return NS_OK;
}
bool
WaveDataDecoder::DoDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
size_t aLength = aSample->Size();
ByteReader aReader = ByteReader(aSample->Data(), aLength);
int64_t aOffset = aSample->mOffset;
@ -150,36 +129,20 @@ WaveDataDecoder::DoDecode(MediaRawData* aSample)
Move(buffer),
mInfo.mChannels,
mInfo.mRate));
mFrames += frames;
return true;
}
void
WaveDataDecoder::ProcessDrain()
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
mCallback->DrainComplete();
}
nsresult
WaveDataDecoder::Drain()
{
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
mTaskQueue->Dispatch(NewRunnableMethod(this, &WaveDataDecoder::ProcessDrain));
mCallback->DrainComplete();
return NS_OK;
}
nsresult
WaveDataDecoder::Flush()
{
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
mIsFlushing = true;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([this] () {
mFrames = 0;
});
SyncRunnable::DispatchToThread(mTaskQueue, r);
mIsFlushing = false;
return NS_OK;
}

View File

@ -16,7 +16,6 @@ class WaveDataDecoder : public MediaDataDecoder
{
public:
WaveDataDecoder(const AudioInfo& aConfig,
TaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback);
// Return true if mimetype is Wave
@ -33,16 +32,10 @@ private:
return "wave audio decoder";
}
void ProcessDecode(MediaRawData* aSample);
bool DoDecode(MediaRawData* aSample);
void ProcessDrain();
const AudioInfo& mInfo;
const RefPtr<TaskQueue> mTaskQueue;
MediaDataDecoderCallback* mCallback;
Atomic<bool> mIsFlushing;
int64_t mFrames;
};
} // namespace mozilla

View File

@ -549,11 +549,13 @@ MediaCodecDataDecoder::HandleEOS(int32_t aOutputStatus)
mDecoder->ReleaseOutputBuffer(aOutputStatus, false);
}
TimeUnit
Maybe<TimeUnit>
MediaCodecDataDecoder::GetOutputDuration()
{
MOZ_ASSERT(!mDurations.empty(), "Should have had a duration queued");
const TimeUnit duration = mDurations.front();
if (mDurations.empty()) {
return Nothing();
}
const Maybe<TimeUnit> duration = Some(mDurations.front());
mDurations.pop_front();
return duration;
}
@ -564,19 +566,26 @@ MediaCodecDataDecoder::ProcessOutput(
{
AutoLocalJNIFrame frame(jni::GetEnvForThread(), 1);
const TimeUnit duration = GetOutputDuration();
const Maybe<TimeUnit> duration = GetOutputDuration();
if (!duration) {
// Some devices report failure in QueueSample while actually succeeding at
// it, in which case we get an output buffer without having a cached duration
// (bug 1273523).
return NS_OK;
}
const auto buffer = jni::Object::LocalRef::Adopt(
frame.GetEnv()->GetObjectArrayElement(mOutputBuffers.Get(), aStatus));
if (buffer) {
// The buffer will be null on Android L if we are decoding to a Surface.
void* directBuffer = frame.GetEnv()->GetDirectBufferAddress(buffer.Get());
Output(aInfo, directBuffer, aFormat, duration);
Output(aInfo, directBuffer, aFormat, duration.value());
}
// The Surface will be updated at this point (for video).
mDecoder->ReleaseOutputBuffer(aStatus, true);
PostOutput(aInfo, aFormat, duration);
PostOutput(aInfo, aFormat, duration.value());
return NS_OK;
}

View File

@ -11,6 +11,7 @@
#include "SurfaceTexture.h"
#include "TimeUnits.h"
#include "mozilla/Monitor.h"
#include "mozilla/Maybe.h"
#include <deque>
@ -105,7 +106,7 @@ protected:
nsresult QueueSample(const MediaRawData* aSample);
nsresult QueueEOS();
void HandleEOS(int32_t aOutputStatus);
media::TimeUnit GetOutputDuration();
Maybe<media::TimeUnit> GetOutputDuration();
nsresult ProcessOutput(widget::sdk::BufferInfo::Param aInfo,
widget::sdk::MediaFormat::Param aFormat,
int32_t aStatus);

View File

@ -14,10 +14,12 @@
#include "DXVA2Manager.h"
#include "nsThreadUtils.h"
#include "Layers.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/layers/LayersTypes.h"
#include "MediaInfo.h"
#include "MediaPrefs.h"
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "nsWindowsHelpers.h"
#include "gfx2DGlue.h"
#include "gfxWindowsPlatform.h"
@ -26,6 +28,7 @@
#include "mozilla/Telemetry.h"
#include "nsPrintfCString.h"
#include "MediaTelemetryConstants.h"
#include "GMPUtils.h" // For SplitAt. TODO: Move SplitAt to a central place.
extern mozilla::LogModule* GetPDMLog();
#define LOG(...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
@ -151,91 +154,125 @@ WMFVideoMFTManager::GetMediaSubtypeGUID()
};
}
struct BlacklistedD3D11DLL
struct D3D11BlacklistingCache
{
constexpr
BlacklistedD3D11DLL(LPCWSTR aName, DWORD a, DWORD b, DWORD c, DWORD d)
: name(aName), ms((a << 16) | b), ls((c << 16) | d)
{}
LPCWSTR name;
DWORD ms;
DWORD ls;
};
static constexpr BlacklistedD3D11DLL sBlacklistedD3D11DLL[] =
{
// Keep same DLL names together.
BlacklistedD3D11DLL(L"igd10umd32.dll", 9,17,10,2857),
BlacklistedD3D11DLL(L"isonyvideoprocessor.dll", 4,1,2247,8090),
BlacklistedD3D11DLL(L"isonyvideoprocessor.dll", 4,1,2153,6200),
BlacklistedD3D11DLL(L"tosqep.dll", 1,2,15,526),
BlacklistedD3D11DLL(L"tosqep.dll", 1,1,12,201),
BlacklistedD3D11DLL(L"tosqep.dll", 1,0,11,318),
BlacklistedD3D11DLL(L"tosqep.dll", 1,0,11,215),
BlacklistedD3D11DLL(L"tosqep64.dll", 1,1,12,201),
BlacklistedD3D11DLL(L"tosqep64.dll", 1,0,11,215),
// Keep this last.
BlacklistedD3D11DLL(nullptr, 0,0,0,0)
// D3D11-blacklist pref last seen.
nsCString mBlacklistPref;
// Non-empty if a D3D11-blacklisted DLL was found.
nsCString mBlacklistedDLL;
};
StaticAutoPtr<D3D11BlacklistingCache> sD3D11BlacklistingCache;
// If a blacklisted DLL is found, return its information, otherwise nullptr.
static const BlacklistedD3D11DLL*
IsD3D11DLLBlacklisted()
// If a blacklisted DLL is found, return its information, otherwise "".
static const nsACString&
FindD3D11BlacklistedDLL()
{
NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
// Cache the result, so we only check DLLs once per browser run.
static const BlacklistedD3D11DLL* sAlreadySearched = nullptr;
if (sAlreadySearched) {
// If we point at the last empty entry, there's no actual blacklisting.
return sAlreadySearched->name ? sAlreadySearched : nullptr;
if (!sD3D11BlacklistingCache) {
// First time here, create persistent data that will be reused in all
// D3D11-blacklisting checks.
sD3D11BlacklistingCache = new D3D11BlacklistingCache();
ClearOnShutdown(&sD3D11BlacklistingCache);
}
WCHAR systemPath[MAX_PATH + 1];
LPCWSTR previousDLLName = L"";
VS_FIXEDFILEINFO *vInfo = nullptr;
// vInfo is a pointer into infoData, that's why we keep it outside of the loop.
UniquePtr<unsigned char[]> infoData;
nsAdoptingCString blacklist =
Preferences::GetCString("media.wmf.disable-d3d11-for-dlls");
if (blacklist.IsEmpty()) {
// Empty blacklist -> No blacklisting.
sD3D11BlacklistingCache->mBlacklistPref.SetLength(0);
sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0);
return sD3D11BlacklistingCache->mBlacklistedDLL;
}
for (const BlacklistedD3D11DLL* dll = sBlacklistedD3D11DLL; ; ++dll) {
if (!dll->name) {
// End of list, no blacklisting.
sAlreadySearched = dll;
return nullptr;
}
// Check if we need to check another DLL (compare by pointer to name string)
if (wcscmp(previousDLLName, dll->name) != 0) {
previousDLLName = dll->name;
vInfo = nullptr;
infoData = nullptr;
if (!ConstructSystem32Path(dll->name, systemPath, MAX_PATH + 1)) {
// Cannot build path -> Assume it's not the blacklisted DLL.
continue;
}
// Detect changes in pref.
if (sD3D11BlacklistingCache->mBlacklistPref.Equals(blacklist)) {
// Same blacklist -> Return same result (i.e., don't check DLLs again).
return sD3D11BlacklistingCache->mBlacklistedDLL;
}
// Adopt new pref now, so we don't work on it again.
sD3D11BlacklistingCache->mBlacklistPref = blacklist;
DWORD zero;
DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
if (infoSize == 0) {
// Can't get file info -> Assume we don't have the blacklisted DLL.
continue;
}
infoData = MakeUnique<unsigned char[]>(infoSize);
UINT vInfoLen;
if (!GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get())
|| !VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen)) {
// Can't find version -> Assume it's not blacklisted.
vInfo = nullptr;
infoData = nullptr;
continue;
}
// media.wmf.disable-d3d11-for-dlls format: (whitespace is trimmed)
// "dll1.dll: 1.2.3.4[, more versions...][; more dlls...]"
nsTArray<nsCString> dlls;
SplitAt(";", blacklist, dlls);
for (const auto& dll : dlls) {
nsTArray<nsCString> nameAndVersions;
SplitAt(":", dll, nameAndVersions);
if (nameAndVersions.Length() != 2) {
NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' dll:versions format");
continue;
}
if (vInfo
&& vInfo->dwFileVersionMS == dll->ms
&& vInfo->dwFileVersionLS == dll->ls) {
// Blacklisted! Keep pointer to bad DLL.
sAlreadySearched = dll;
return dll;
nameAndVersions[0].CompressWhitespace();
NS_ConvertUTF8toUTF16 name(nameAndVersions[0]);
WCHAR systemPath[MAX_PATH + 1];
if (!ConstructSystem32Path(name.get(), systemPath, MAX_PATH + 1)) {
// Cannot build path -> Assume it's not the blacklisted DLL.
continue;
}
DWORD zero;
DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
if (infoSize == 0) {
// Can't get file info -> Assume we don't have the blacklisted DLL.
continue;
}
// vInfo is a pointer into infoData, that's why we keep it outside of the loop.
auto infoData = MakeUnique<unsigned char[]>(infoSize);
VS_FIXEDFILEINFO *vInfo;
UINT vInfoLen;
if (!GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get())
|| !VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen)
|| !vInfo) {
// Can't find version -> Assume it's not blacklisted.
continue;
}
nsTArray<nsCString> versions;
SplitAt(",", nameAndVersions[1], versions);
for (const auto& version : versions) {
nsTArray<nsCString> numberStrings;
SplitAt(".", version, numberStrings);
if (numberStrings.Length() != 4) {
NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' a.b.c.d version format");
continue;
}
DWORD numbers[4];
nsresult errorCode = NS_OK;
for (int i = 0; i < 4; ++i) {
numberStrings[i].CompressWhitespace();
numbers[i] = DWORD(numberStrings[i].ToInteger(&errorCode));
if (NS_FAILED(errorCode)) {
break;
}
if (numbers[i] > UINT16_MAX) {
errorCode = NS_ERROR_FAILURE;
break;
}
}
if (NS_FAILED(errorCode)) {
NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' a.b.c.d version format");
continue;
}
if (vInfo->dwFileVersionMS == ((numbers[0] << 16) | numbers[1])
&& vInfo->dwFileVersionLS == ((numbers[2] << 16) | numbers[3])) {
// Blacklisted! Record bad DLL.
sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0);
sD3D11BlacklistingCache->mBlacklistedDLL.AppendPrintf(
"%s (%lu.%lu.%lu.%lu)",
nameAndVersions[0].get(), numbers[0], numbers[1], numbers[2], numbers[3]);
return sD3D11BlacklistingCache->mBlacklistedDLL;
}
}
}
// No blacklisted DLL.
sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0);
return sD3D11BlacklistingCache->mBlacklistedDLL;
}
class CreateDXVAManagerEvent : public Runnable {
@ -251,13 +288,10 @@ public:
nsCString secondFailureReason;
if (mBackend == LayersBackend::LAYERS_D3D11 &&
MediaPrefs::PDMWMFAllowD3D11() && IsWin8OrLater()) {
const BlacklistedD3D11DLL* blacklistedDLL = IsD3D11DLLBlacklisted();
if (blacklistedDLL) {
failureReason->AppendPrintf(
"D3D11 blacklisted with DLL %s (%u.%u.%u.%u)",
blacklistedDLL->name,
blacklistedDLL->ms >> 16, blacklistedDLL->ms & 0xFFu,
blacklistedDLL->ls >> 16, blacklistedDLL->ls & 0xFFu);
const nsACString& blacklistedDLL = FindD3D11BlacklistedDLL();
if (!blacklistedDLL.IsEmpty()) {
failureReason->AppendPrintf("D3D11 blacklisted with DLL %s",
blacklistedDLL);
} else {
mDXVA2Manager = DXVA2Manager::CreateD3D11DXVA(*failureReason);
if (mDXVA2Manager) {
@ -298,7 +332,9 @@ WMFVideoMFTManager::InitializeDXVA(bool aForceD3D9)
// The DXVA manager must be created on the main thread.
RefPtr<CreateDXVAManagerEvent> event =
new CreateDXVAManagerEvent(aForceD3D9 ? LayersBackend::LAYERS_D3D9 : mLayersBackend, mDXVAFailureReason);
new CreateDXVAManagerEvent(aForceD3D9 ? LayersBackend::LAYERS_D3D9
: mLayersBackend,
mDXVAFailureReason);
if (NS_IsMainThread()) {
event->Run();

View File

@ -19,7 +19,12 @@ namespace mozilla {
class NesteggPacketHolder {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NesteggPacketHolder)
NesteggPacketHolder() : mPacket(nullptr), mOffset(-1), mTimestamp(-1), mIsKeyframe(false) {}
NesteggPacketHolder()
: mPacket(nullptr)
, mOffset(-1)
, mTimestamp(-1)
, mDuration(-1)
, mIsKeyframe(false) {}
bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, bool aIsKeyframe)
{
@ -36,12 +41,17 @@ public:
mTrack = aTrack;
mIsKeyframe = aIsKeyframe;
uint64_t duration_ns;
if (!nestegg_packet_duration(aPacket, &duration_ns)) {
mDuration = duration_ns / 1000;
}
return true;
}
nestegg_packet* Packet() { MOZ_ASSERT(IsInitialized()); return mPacket; }
int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; }
int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; }
int64_t Duration() { MOZ_ASSERT(IsInitialized()); return mDuration; }
unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; }
bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; }
@ -62,6 +72,9 @@ private:
// Packet presentation timestamp in microseconds.
int64_t mTimestamp;
// Packet duration in microseconds; -1 if unknown or retrieval failed.
int64_t mDuration;
// Track ID.
unsigned mTrack;

View File

@ -510,8 +510,9 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
return false;
}
int64_t tstamp = holder->Timestamp();
int64_t duration = holder->Duration();
// The end time of this frame is the start time of the next frame. Fetch
// The end time of this frame is the start time of the next frame. Fetch
// the timestamp of the next packet for this track. If we've reached the
// end of the resource, use the file's duration as the end time of this
// video frame.
@ -521,6 +522,8 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushAudioPacket(next_holder);
} else if (duration >= 0) {
next_tstamp = tstamp + duration;
} else if (!mIsMediaSource ||
(mIsMediaSource && mLastAudioFrameTime.isSome())) {
next_tstamp = tstamp;
@ -534,6 +537,8 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushVideoPacket(next_holder);
} else if (duration >= 0) {
next_tstamp = tstamp + duration;
} else if (!mIsMediaSource ||
(mIsMediaSource && mLastVideoFrameTime.isSome())) {
next_tstamp = tstamp;
@ -665,7 +670,10 @@ WebMDemuxer::DemuxPacket()
{
nestegg_packet* packet;
int r = nestegg_read_packet(mContext, &packet);
if (r <= 0) {
if (r == 0) {
nestegg_read_reset(mContext);
return nullptr;
} else if (r < 0) {
return nullptr;
}
@ -892,7 +900,7 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
void
WebMTrackDemuxer::SetNextKeyFrameTime()
{
if (mType != TrackInfo::kVideoTrack) {
if (mType != TrackInfo::kVideoTrack || mParent->IsMediaSource()) {
return;
}
@ -991,11 +999,13 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
uint32_t parsed = 0;
bool found = false;
RefPtr<MediaRawData> sample;
int64_t sampleTime;
WEBM_DEBUG("TimeThreshold: %f", aTimeThreshold.ToSeconds());
while (!found && (sample = NextSample())) {
parsed++;
if (sample->mKeyframe && sample->mTime >= aTimeThreshold.ToMicroseconds()) {
sampleTime = sample->mTime;
if (sample->mKeyframe && sampleTime >= aTimeThreshold.ToMicroseconds()) {
found = true;
mSamples.Reset();
mSamples.PushFront(sample.forget());
@ -1004,7 +1014,7 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
SetNextKeyFrameTime();
if (found) {
WEBM_DEBUG("next sample: %f (parsed: %d)",
media::TimeUnit::FromMicroseconds(sample->mTime).ToSeconds(),
media::TimeUnit::FromMicroseconds(sampleTime).ToSeconds(),
parsed);
return SkipAccessPointPromise::CreateAndResolve(parsed, __func__);
} else {
@ -1025,5 +1035,16 @@ WebMTrackDemuxer::BreakCycles()
mParent = nullptr;
}
int64_t
WebMTrackDemuxer::GetEvictionOffset(const media::TimeUnit& aTime)
{
int64_t offset;
if (!mParent->GetOffsetForTime(aTime.ToNanoseconds(), &offset)) {
return 0;
}
return offset;
}
#undef WEBM_DEBUG
} // namespace mozilla

View File

@ -230,6 +230,8 @@ public:
media::TimeIntervals GetBuffered() override;
int64_t GetEvictionOffset(const media::TimeUnit& aTime) override;
void BreakCycles() override;
private:

View File

@ -14,6 +14,7 @@
#include "SpeechRecognitionResult.h"
#include "SpeechRecognitionResultList.h"
#include "nsIObserverService.h"
#include "MediaPrefs.h"
#include "mozilla/Services.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
@ -302,7 +303,7 @@ PocketSphinxSpeechRecognitionService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(mRecognition->mTestConfig.mFakeRecognitionService,
MOZ_ASSERT(MediaPrefs::WebSpeechFakeRecognitionService(),
"Got request to fake recognition service event, "
"but " TEST_PREFERENCE_FAKE_RECOGNITION_SERVICE " is not set");

View File

@ -32,11 +32,9 @@ interfaces = [
'smil',
'apps',
'gamepad',
'push',
]
if not CONFIG['MOZ_SIMPLEPUSH']:
interfaces += ['push']
DIRS += ['interfaces/' + i for i in interfaces]
DIRS += [

View File

@ -23,6 +23,7 @@
#include "nsVolumeService.h"
#include "AutoMounterSetting.h"
#include "base/message_loop.h"
#include "base/task.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/FileUtils.h"
#include "mozilla/Hal.h"

View File

@ -20,6 +20,7 @@
#include <pthread.h>
#include <hardware/gps.h>
#include "base/task.h"
#include "GeolocationUtil.h"
#include "mozstumbler/MozStumbler.h"
#include "mozilla/Preferences.h"
@ -813,7 +814,7 @@ GonkGPSGeolocationProvider::Init()
}
#endif
NS_DispatchToMainThread(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::StartGPS));
NS_DispatchToMainThread(NewRunnableMethod(this, &GonkGPSGeolocationProvider::StartGPS));
}
void
@ -1001,7 +1002,7 @@ GonkGPSGeolocationProvider::Startup()
NS_ENSURE_SUCCESS(rv, rv);
}
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::Init),
mInitThread->Dispatch(NewRunnableMethod(this, &GonkGPSGeolocationProvider::Init),
NS_DISPATCH_NORMAL);
mNetworkLocationProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1");
@ -1063,7 +1064,7 @@ GonkGPSGeolocationProvider::Shutdown()
}
}
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS),
mInitThread->Dispatch(NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS),
NS_DISPATCH_NORMAL);
return NS_OK;

View File

@ -22,6 +22,7 @@
#include <limits>
#include "mozilla/dom/network/NetUtils.h"
#include "mozilla/fallible.h"
#include "base/task.h"
#include <errno.h>
#include <string.h>

View File

@ -13,6 +13,7 @@
#include "nsXULAppAPI.h"
#include "base/message_loop.h"
#include "base/task.h"
#include "mozilla/Scoped.h"
#include "mozilla/StaticPtr.h"

View File

@ -5,6 +5,7 @@
#include "nsVolume.h"
#include "base/message_loop.h"
#include "base/task.h"
#include "nsIPowerManagerService.h"
#include "nsISupportsUtils.h"
#include "nsIVolume.h"

View File

@ -29,6 +29,7 @@
#include "nsXULAppAPI.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/Services.h"
#include "base/task.h"
#undef VOLUME_MANAGER_LOG_TAG
#define VOLUME_MANAGER_LOG_TAG "nsVolumeService"

View File

@ -175,11 +175,6 @@ interface BrowserElementPrivileged {
DOMRequest executeScript(DOMString script,
optional BrowserElementExecuteScriptOptions options);
[Throws,
Pref="dom.mozBrowserFramesEnabled",
CheckAllPermissions="browser"]
DOMRequest getStructuredData();
[Throws,
Pref="dom.mozBrowserFramesEnabled",
CheckAllPermissions="browser"]

View File

@ -957,6 +957,15 @@ GetOrCreateMapEntryForPrototype(JSContext *cx, JS::Handle<JSObject*> proto)
return entry;
}
static
nsXBLPrototypeBinding*
GetProtoBindingFromClassObject(JSObject* obj)
{
MOZ_ASSERT(JS_GetClass(obj) == &gPrototypeJSClass);
return static_cast<nsXBLPrototypeBinding*>(::JS_GetReservedSlot(obj, 0).toPrivate());
}
// static
nsresult
nsXBLBinding::DoInitJSClass(JSContext *cx,
@ -1012,7 +1021,9 @@ nsXBLBinding::DoInitJSClass(JSContext *cx,
*aNew = !desc.object();
if (desc.object()) {
proto = &desc.value().toObject();
MOZ_ASSERT(JS_GetClass(js::UncheckedUnwrap(proto)) == &gPrototypeJSClass);
DebugOnly<nsXBLPrototypeBinding*> cachedBinding =
GetProtoBindingFromClassObject(js::UncheckedUnwrap(proto));
MOZ_ASSERT(cachedBinding == aProtoBinding);
} else {
// We need to create the prototype. First, enter the compartment where it's

View File

@ -858,119 +858,120 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
nsresult rv = aBindingURI->CloneIgnoringRef(getter_AddRefs(documentURI));
NS_ENSURE_SUCCESS(rv, rv);
nsBindingManager *bindingManager = nullptr;
// The first thing to check is the binding manager, which (if it exists)
// should have a reference to the nsXBLDocumentInfo if this document
// has ever loaded this binding before.
if (aBoundDocument) {
bindingManager = aBoundDocument->BindingManager();
info = bindingManager->GetXBLDocumentInfo(documentURI);
if (aBoundDocument->IsStaticDocument() &&
IsChromeOrResourceURI(aBindingURI)) {
aForceSyncLoad = true;
}
}
// It's possible the document is already being loaded. If so, there's no
// document yet, but we need to glom on our request so that it will be
// processed whenever the doc does finish loading.
NodeInfo *ni = nullptr;
if (aBoundElement)
ni = aBoundElement->NodeInfo();
if (!info && bindingManager &&
(!ni || !(ni->Equals(nsGkAtoms::scrollbar, kNameSpaceID_XUL) ||
ni->Equals(nsGkAtoms::thumb, kNameSpaceID_XUL) ||
((ni->Equals(nsGkAtoms::input) ||
ni->Equals(nsGkAtoms::select)) &&
aBoundElement->IsHTMLElement()))) && !aForceSyncLoad) {
nsCOMPtr<nsIStreamListener> listener;
if (bindingManager)
listener = bindingManager->GetLoadingDocListener(documentURI);
if (listener) {
nsXBLStreamListener* xblListener =
static_cast<nsXBLStreamListener*>(listener.get());
// Create a new load observer.
if (!xblListener->HasRequest(aBindingURI, aBoundElement)) {
nsXBLBindingRequest* req = new nsXBLBindingRequest(aBindingURI, aBoundElement);
xblListener->AddRequest(req);
}
return NS_OK;
}
}
#ifdef MOZ_XUL
// We've got a file. Check our XBL document cache.
// The second line of defense is the global nsXULPrototypeCache,
// if it's being used.
nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance();
bool useXULCache = cache && cache->IsEnabled();
if (useXULCache) {
// The first line of defense is the chrome cache.
if (!info && useXULCache) {
// This cache crosses the entire product, so that any XBL bindings that are
// part of chrome will be reused across all XUL documents.
info = cache->GetXBLDocumentInfo(documentURI);
}
#endif
bool useStartupCache = useXULCache && IsChromeOrResourceURI(documentURI);
if (!info) {
// The second line of defense is the binding manager's document table.
nsBindingManager *bindingManager = nullptr;
if (aBoundDocument) {
bindingManager = aBoundDocument->BindingManager();
info = bindingManager->GetXBLDocumentInfo(documentURI);
if (aBoundDocument->IsStaticDocument() &&
IsChromeOrResourceURI(aBindingURI)) {
aForceSyncLoad = true;
}
}
NodeInfo *ni = nullptr;
if (aBoundElement)
ni = aBoundElement->NodeInfo();
if (!info && bindingManager &&
(!ni || !(ni->Equals(nsGkAtoms::scrollbar, kNameSpaceID_XUL) ||
ni->Equals(nsGkAtoms::thumb, kNameSpaceID_XUL) ||
((ni->Equals(nsGkAtoms::input) ||
ni->Equals(nsGkAtoms::select)) &&
aBoundElement->IsHTMLElement()))) && !aForceSyncLoad) {
// The third line of defense is to investigate whether or not the
// document is currently being loaded asynchronously. If so, there's no
// document yet, but we need to glom on our request so that it will be
// processed whenever the doc does finish loading.
nsCOMPtr<nsIStreamListener> listener;
if (bindingManager)
listener = bindingManager->GetLoadingDocListener(documentURI);
if (listener) {
nsXBLStreamListener* xblListener =
static_cast<nsXBLStreamListener*>(listener.get());
// Create a new load observer.
if (!xblListener->HasRequest(aBindingURI, aBoundElement)) {
nsXBLBindingRequest* req = new nsXBLBindingRequest(aBindingURI, aBoundElement);
xblListener->AddRequest(req);
}
return NS_OK;
}
}
#ifdef MOZ_XUL
// Next, look in the startup cache
bool useStartupCache = useXULCache && IsChromeOrResourceURI(documentURI);
if (!info && useStartupCache) {
rv = nsXBLDocumentInfo::ReadPrototypeBindings(documentURI, getter_AddRefs(info));
if (NS_SUCCEEDED(rv)) {
cache->PutXBLDocumentInfo(info);
if (bindingManager) {
// Cache it in our binding manager's document table.
bindingManager->PutXBLDocumentInfo(info);
}
}
}
}
#endif
if (!info) {
// Finally, if all lines of defense fail, we go and fetch the binding
// document.
if (!info) {
// Finally, if all lines of defense fail, we go and fetch the binding
// document.
// Always load chrome synchronously
bool chrome;
if (NS_SUCCEEDED(documentURI->SchemeIs("chrome", &chrome)) && chrome)
aForceSyncLoad = true;
// Always load chrome synchronously
bool chrome;
if (NS_SUCCEEDED(documentURI->SchemeIs("chrome", &chrome)) && chrome)
aForceSyncLoad = true;
nsCOMPtr<nsIDocument> document;
rv = FetchBindingDocument(aBoundElement, aBoundDocument, documentURI,
aBindingURI, aOriginPrincipal, aForceSyncLoad,
getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> document;
rv = FetchBindingDocument(aBoundElement, aBoundDocument, documentURI,
aBindingURI, aOriginPrincipal, aForceSyncLoad,
getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
if (document) {
nsBindingManager *xblDocBindingManager = document->BindingManager();
info = xblDocBindingManager->GetXBLDocumentInfo(documentURI);
if (!info) {
NS_ERROR("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?");
return NS_ERROR_FAILURE;
}
xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle.
if (document) {
nsBindingManager *xblDocBindingManager = document->BindingManager();
info = xblDocBindingManager->GetXBLDocumentInfo(documentURI);
if (!info) {
NS_ERROR("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?");
return NS_ERROR_FAILURE;
}
xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle.
// If the doc is a chrome URI, then we put it into the XUL cache.
// If the doc is a chrome URI, then we put it into the XUL cache.
#ifdef MOZ_XUL
if (useStartupCache) {
cache->PutXBLDocumentInfo(info);
if (useStartupCache) {
cache->PutXBLDocumentInfo(info);
// now write the bindings into the startup cache
info->WritePrototypeBindings();
}
#endif
if (bindingManager) {
// Also put it in our binding manager's document table.
bindingManager->PutXBLDocumentInfo(info);
}
// now write the bindings into the startup cache
info->WritePrototypeBindings();
}
#endif
}
}
if (info && bindingManager) {
// Cache it in our binding manager's document table. This way,
// we can ensure that if the document has loaded this binding
// before, it can continue to use it even if the XUL prototype
// cache gets flushed. That way, if a flush does occur, we
// don't get into a weird state where we're using different
// XBLDocumentInfos for the same XBL document in a single
// document that has loaded some bindings.
bindingManager->PutXBLDocumentInfo(info);
}
info.forget(aResult);
return NS_OK;

View File

@ -136,7 +136,7 @@ DrawTargetSkia::DrawTargetSkia()
: mSnapshot(nullptr)
#ifdef MOZ_WIDGET_COCOA
, mCG(nullptr)
, mColorSpace(CGColorSpaceCreateDeviceRGB())
, mColorSpace(nullptr)
, mCanvasData(nullptr)
, mCGSize(0, 0)
#endif
@ -147,10 +147,14 @@ DrawTargetSkia::~DrawTargetSkia()
{
#ifdef MOZ_WIDGET_COCOA
if (mCG) {
CGColorSpaceRelease(mColorSpace);
CGContextRelease(mCG);
mCG = nullptr;
}
if (mColorSpace) {
CGColorSpaceRelease(mColorSpace);
mColorSpace = nullptr;
}
#endif
}
@ -844,6 +848,10 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
return mCG;
}
if (!mColorSpace) {
mColorSpace = CGColorSpaceCreateDeviceRGB();
}
if (mCG) {
// Release the old CG context since it's no longer valid.
CGContextRelease(mCG);
@ -923,6 +931,7 @@ DrawTargetSkia::FillGlyphsWithCG(ScaledFont *aFont,
Vector<CGGlyph,32> glyphs;
Vector<CGPoint,32> positions;
if (!SetupCGGlyphs(cgContext, aBuffer, glyphs, positions)) {
ReturnCGContext(cgContext);
return false;
}

View File

@ -141,6 +141,7 @@ enum class LogReason : int {
InvalidCommandList,
AsyncTransactionTimeout, // 30
TextureCreation,
InvalidCacheSurface,
// End
MustBeLessThanThis = 101,
};

View File

@ -45,7 +45,6 @@ UNIFIED_SOURCES += [
'Intervals.cpp',
'json.cpp',
'Justifier.cpp',
'NameTable.cpp',
'Pass.cpp',
'Position.cpp',
'SegCache.cpp',
@ -59,6 +58,12 @@ UNIFIED_SOURCES += [
'UtfCodec.cpp',
]
# Excluded from UNIFIED_SOURCES because <cmath> from other files breaks it,
# see bug 1272647.
SOURCES += [
'NameTable.cpp',
]
# tell graphite2 not to export symbols, we'll be linking it directly with
# thebes
DEFINES['GRAPHITE2_STATIC'] = True

View File

@ -28,13 +28,13 @@
#define NS_THEME_TOOLBAR 12
// A single toolbar button (with no associated dropdown)
#define NS_THEME_TOOLBAR_BUTTON 13
#define NS_THEME_TOOLBARBUTTON 13
// A dual toolbar button (e.g., a Back button with a dropdown)
#define NS_THEME_TOOLBAR_DUAL_BUTTON 14
#define NS_THEME_DUALBUTTON 14
// The dropdown portion of a toolbar button
#define NS_THEME_TOOLBAR_BUTTON_DROPDOWN 15
#define NS_THEME_TOOLBARBUTTON_DROPDOWN 15
// Various arrows that go in buttons
#define NS_THEME_BUTTON_ARROW_UP 16
@ -43,10 +43,10 @@
#define NS_THEME_BUTTON_ARROW_PREVIOUS 19
// A separator. Can be horizontal or vertical.
#define NS_THEME_TOOLBAR_SEPARATOR 20
#define NS_THEME_SEPARATOR 20
// The gripper for a toolbar.
#define NS_THEME_TOOLBAR_GRIPPER 21
#define NS_THEME_TOOLBARGRIPPER 21
// A splitter. Can be horizontal or vertical.
#define NS_THEME_SPLITTER 22
@ -55,11 +55,11 @@
#define NS_THEME_STATUSBAR 23
// A single pane of a status bar.
#define NS_THEME_STATUSBAR_PANEL 24
#define NS_THEME_STATUSBARPANEL 24
// The resizer background area in a status bar
// for the resizer widget in the corner of a window.
#define NS_THEME_STATUSBAR_RESIZER_PANEL 25
#define NS_THEME_RESIZER_PANEL 25
// The resizer itself.
#define NS_THEME_RESIZER 26
@ -68,62 +68,62 @@
#define NS_THEME_LISTBOX 31
// A listbox item
#define NS_THEME_LISTBOX_LISTITEM 32
#define NS_THEME_LISTITEM 32
// A tree widget
#define NS_THEME_TREEVIEW 41
// A tree item
#define NS_THEME_TREEVIEW_TREEITEM 42
#define NS_THEME_TREEITEM 42
// A tree widget twisty
#define NS_THEME_TREEVIEW_TWISTY 43
#define NS_THEME_TREETWISTY 43
// A tree widget branch line
#define NS_THEME_TREEVIEW_LINE 44
#define NS_THEME_TREELINE 44
// A listbox or tree widget header
#define NS_THEME_TREEVIEW_HEADER 45
#define NS_THEME_TREEHEADER 45
// An individual header cell
#define NS_THEME_TREEVIEW_HEADER_CELL 46
#define NS_THEME_TREEHEADERCELL 46
// The sort arrow for a header.
#define NS_THEME_TREEVIEW_HEADER_SORTARROW 47
#define NS_THEME_TREEHEADERSORTARROW 47
// Open tree widget twisty
#define NS_THEME_TREEVIEW_TWISTY_OPEN 48
#define NS_THEME_TREETWISTYOPEN 48
// A horizontal progress bar.
#define NS_THEME_PROGRESSBAR 51
// The progress bar's progress indicator
#define NS_THEME_PROGRESSBAR_CHUNK 52
#define NS_THEME_PROGRESSCHUNK 52
// A vertical progress bar.
#define NS_THEME_PROGRESSBAR_VERTICAL 53
// A vertical progress chunk
#define NS_THEME_PROGRESSBAR_CHUNK_VERTICAL 54
#define NS_THEME_PROGRESSCHUNK_VERTICAL 54
// A horizontal meter bar.
#define NS_THEME_METERBAR 55
// The meter bar's meter indicator
#define NS_THEME_METERBAR_CHUNK 56
#define NS_THEME_METERCHUNK 56
// A single tab in a tab widget.
#define NS_THEME_TAB 61
// A single pane (inside the tabpanels container)
#define NS_THEME_TAB_PANEL 62
#define NS_THEME_TABPANEL 62
// The tab panels container.
#define NS_THEME_TAB_PANELS 65
#define NS_THEME_TABPANELS 65
// The tabs scroll arrows (left/right)
#define NS_THEME_TAB_SCROLLARROW_BACK 66
#define NS_THEME_TAB_SCROLLARROW_FORWARD 67
#define NS_THEME_TAB_SCROLL_ARROW_BACK 66
#define NS_THEME_TAB_SCROLL_ARROW_FORWARD 67
// A tooltip
#define NS_THEME_TOOLTIP 71
@ -132,10 +132,10 @@
#define NS_THEME_SPINNER 72
// The up button of a spin control
#define NS_THEME_SPINNER_UP_BUTTON 73
#define NS_THEME_SPINNER_UPBUTTON 73
// The down button of a spin control
#define NS_THEME_SPINNER_DOWN_BUTTON 74
#define NS_THEME_SPINNER_DOWNBUTTON 74
// The textfield of a spin control
#define NS_THEME_SPINNER_TEXTFIELD 75
@ -154,18 +154,18 @@
#define NS_THEME_SCROLLBAR_VERTICAL 83
// A scrollbar button (up/down/left/right)
#define NS_THEME_SCROLLBAR_BUTTON_UP 84
#define NS_THEME_SCROLLBAR_BUTTON_DOWN 85
#define NS_THEME_SCROLLBAR_BUTTON_LEFT 86
#define NS_THEME_SCROLLBAR_BUTTON_RIGHT 87
#define NS_THEME_SCROLLBARBUTTON_UP 84
#define NS_THEME_SCROLLBARBUTTON_DOWN 85
#define NS_THEME_SCROLLBARBUTTON_LEFT 86
#define NS_THEME_SCROLLBARBUTTON_RIGHT 87
// The scrollbar track
#define NS_THEME_SCROLLBAR_TRACK_HORIZONTAL 88
#define NS_THEME_SCROLLBAR_TRACK_VERTICAL 89
#define NS_THEME_SCROLLBARTRACK_HORIZONTAL 88
#define NS_THEME_SCROLLBARTRACK_VERTICAL 89
// The scrollbar thumb
#define NS_THEME_SCROLLBAR_THUMB_HORIZONTAL 90
#define NS_THEME_SCROLLBAR_THUMB_VERTICAL 91
#define NS_THEME_SCROLLBARTHUMB_HORIZONTAL 90
#define NS_THEME_SCROLLBARTHUMB_VERTICAL 91
// A non-disappearing scrollbar.
#define NS_THEME_SCROLLBAR_NON_DISAPPEARING 92
@ -183,36 +183,36 @@
#define NS_THEME_SEARCHFIELD 98
// A dropdown list.
#define NS_THEME_DROPDOWN 101
#define NS_THEME_MENULIST 101
// The dropdown button(s) that open up a dropdown list.
#define NS_THEME_DROPDOWN_BUTTON 102
#define NS_THEME_MENULIST_BUTTON 102
// The text part of a dropdown list, to left of button
#define NS_THEME_DROPDOWN_TEXT 103
#define NS_THEME_MENULIST_TEXT 103
// An editable textfield with a dropdown list (a combobox)
#define NS_THEME_DROPDOWN_TEXTFIELD 104
#define NS_THEME_MENULIST_TEXTFIELD 104
// A slider
#define NS_THEME_SCALE_HORIZONTAL 111
#define NS_THEME_SCALE_VERTICAL 112
#define NS_THEME_SCALE_HORIZONTAL 111
#define NS_THEME_SCALE_VERTICAL 112
// A slider's thumb
#define NS_THEME_SCALE_THUMB_HORIZONTAL 113
#define NS_THEME_SCALE_THUMB_VERTICAL 114
#define NS_THEME_SCALETHUMB_HORIZONTAL 113
#define NS_THEME_SCALETHUMB_VERTICAL 114
// If the platform supports it, the left/right chunks
// of the slider thumb
#define NS_THEME_SCALE_THUMB_START 115
#define NS_THEME_SCALE_THUMB_END 116
#define NS_THEME_SCALETHUMBSTART 115
#define NS_THEME_SCALETHUMBEND 116
// The ticks for a slider.
#define NS_THEME_SCALE_TICK 117
#define NS_THEME_SCALETHUMBTICK 117
// nsRangeFrame and its subparts
#define NS_THEME_RANGE 120
#define NS_THEME_RANGE_THUMB 121
#define NS_THEME_RANGE 120
#define NS_THEME_RANGE_THUMB 121
// A groupbox
#define NS_THEME_GROUPBOX 149
@ -257,13 +257,13 @@
// Vista Rebars
#define NS_THEME_WIN_COMMUNICATIONS_TOOLBOX 221
#define NS_THEME_WIN_MEDIA_TOOLBOX 222
#define NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX 223
#define NS_THEME_WIN_BROWSERTABBAR_TOOLBOX 223
// Titlebar elements on the Mac
#define NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON 226
#define NS_THEME_MAC_FULLSCREEN_BUTTON 226
// Mac help button
#define NS_THEME_MOZ_MAC_HELP_BUTTON 227
#define NS_THEME_MAC_HELP_BUTTON 227
// Vista glass
#define NS_THEME_WIN_BORDERLESS_GLASS 229

View File

@ -262,6 +262,11 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
NS_ASSERTION(cIndex < aLength, "cIndex beyond word length");
++clusters[cIndex].nGlyphs;
// bump |after| index if it falls in the middle of a surrogate pair
if (NS_IS_HIGH_SURROGATE(aText[after]) && after < aLength - 1 &&
NS_IS_LOW_SURROGATE(aText[after + 1])) {
after++;
}
// extend cluster if necessary to reach the glyph's "after" index
if (clusters[cIndex].baseChar + clusters[cIndex].nChars < after + 1) {
clusters[cIndex].nChars = after + 1 - clusters[cIndex].baseChar;

View File

@ -8,6 +8,7 @@
#include <fcntl.h>
#include <errno.h>
#include "base/message_loop.h"
#include "base/task.h"
#include "DiskSpaceWatcher.h"
#include "fanotify.h"
#include "nsIObserverService.h"
@ -24,13 +25,6 @@ namespace mozilla { namespace hal_impl { class GonkDiskSpaceWatcher; } }
using namespace mozilla::hal_impl;
template<>
struct RunnableMethodTraits<GonkDiskSpaceWatcher>
{
static void RetainCallee(GonkDiskSpaceWatcher* obj) { }
static void ReleaseCallee(GonkDiskSpaceWatcher* obj) { }
};
namespace mozilla {
namespace hal_impl {
@ -311,7 +305,7 @@ StartDiskSpaceWatcher()
gHalDiskSpaceWatcher = new GonkDiskSpaceWatcher();
XRE_GetIOMessageLoop()->PostTask(
NewRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStart));
NewNonOwningRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStart));
}
void
@ -323,7 +317,7 @@ StopDiskSpaceWatcher()
}
XRE_GetIOMessageLoop()->PostTask(
NewRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStop));
NewNonOwningRunnableMethod(gHalDiskSpaceWatcher, &GonkDiskSpaceWatcher::DoStop));
}
} // namespace hal_impl

View File

@ -43,6 +43,7 @@
#include "utils/threads.h"
#include "base/message_loop.h"
#include "base/task.h"
#include "Hal.h"
#include "HalImpl.h"

View File

@ -22,6 +22,7 @@
#include "base/basictypes.h"
#include "base/thread.h"
#include "base/task.h"
#include "GonkSensorsInterface.h"
#include "GonkSensorsPollInterface.h"

View File

@ -18,6 +18,7 @@
#include <sysutils/NetlinkEvent.h>
#include "base/message_loop.h"
#include "base/task.h"
#include "Hal.h"
#include "HalLog.h"

View File

@ -31,6 +31,7 @@
#include "HalLog.h"
#include "nsDebug.h"
#include "base/message_loop.h"
#include "base/task.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/FileUtils.h"
#include "mozilla/Monitor.h"

View File

@ -1036,7 +1036,8 @@ SurfaceCache::Insert(imgFrame* aSurface,
// Refuse null surfaces.
if (!aSurface) {
MOZ_CRASH("Don't pass null surfaces to SurfaceCache::Insert");
gfxDevCrash(LogReason::InvalidCacheSurface) << "Null surface in SurfaceCache::Insert";
return InsertOutcome::FAILURE;
}
MutexAutoLock lock(sInstance->GetMutex());

View File

@ -87,8 +87,7 @@ NS_IMETHODIMP nsTextToSubURI::ConvertAndEscape(
outlen += finLen;
}
}
pBuf[outlen] = '\0';
*_retval = nsEscape(pBuf, url_XPAlphas);
*_retval = nsEscape(pBuf, outlen, nullptr, url_XPAlphas);
if (nullptr == *_retval) {
rv = NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -9,6 +9,7 @@
#include <sys/socket.h>
#include "android/log.h"
#include "base/task.h"
#include "nsWhitespaceTokenizer.h"
#include "nsXULAppAPI.h"

View File

@ -114,13 +114,21 @@ struct Zone
JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|.
public:
// Stack GC roots for Rooted GC pointers.
js::RootedListHeads stackRoots_;
template <typename T> friend class JS::Rooted;
bool needsIncrementalBarrier_;
Zone(JSRuntime* runtime, JSTracer* barrierTracerArg)
: runtime_(runtime),
barrierTracer_(barrierTracerArg),
needsIncrementalBarrier_(false)
{}
{
for (auto& stackRootPtr : stackRoots_) {
stackRootPtr = nullptr;
}
}
bool needsIncrementalBarrier() const {
return needsIncrementalBarrier_;
@ -143,7 +151,7 @@ struct Zone
return runtime_;
}
static JS::shadow::Zone* asShadowZone(JS::Zone* zone) {
static MOZ_ALWAYS_INLINE JS::shadow::Zone* asShadowZone(JS::Zone* zone) {
return reinterpret_cast<JS::shadow::Zone*>(zone);
}
};

View File

@ -634,18 +634,25 @@ namespace JS {
template <typename T>
class MOZ_RAII Rooted : public js::RootedBase<T>
{
/* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */
void registerWithRootLists(js::RootLists& roots) {
this->stack = &roots.stackRoots_[JS::MapTypeToRootKind<T>::kind];
inline void registerWithRootLists(js::RootedListHeads& roots) {
this->stack = &roots[JS::MapTypeToRootKind<T>::kind];
this->prev = *stack;
*stack = reinterpret_cast<Rooted<void*>*>(this);
}
js::RootLists& rootLists(js::ContextFriendFields* cx) { return cx->roots; }
js::RootLists& rootLists(JSContext* cx) { return js::ContextFriendFields::get(cx)->roots; }
js::RootLists& rootLists(js::PerThreadDataFriendFields* pt) { return pt->roots; }
js::RootLists& rootLists(JSRuntime* rt) {
return js::PerThreadDataFriendFields::getMainThread(rt)->roots;
inline js::RootedListHeads& rootLists(js::ContextFriendFields* cx) {
return rootLists(reinterpret_cast<JSContext*>(cx));
}
inline js::RootedListHeads& rootLists(JSContext* cx) {
if (JS::Zone* zone = js::GetContextZone(cx))
return JS::shadow::Zone::asShadowZone(zone)->stackRoots_;
return rootLists(js::GetRuntime(cx));
}
inline js::RootedListHeads& rootLists(js::PerThreadDataFriendFields* pt) {
return pt->roots.stackRoots_;
}
inline js::RootedListHeads& rootLists(JSRuntime* rt) {
return js::PerThreadDataFriendFields::getMainThread(rt)->roots.stackRoots_;
}
public:

View File

@ -98,15 +98,10 @@ JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
enum class RootKind : int8_t
{
// These map 1:1 with trace kinds.
BaseShape = 0,
JitCode,
LazyScript,
Object,
ObjectGroup,
Script,
Shape,
String,
Symbol,
#define EXPAND_ROOT_KIND(name, _0, _1) \
name,
JS_FOR_EACH_TRACEKIND(EXPAND_ROOT_KIND)
#undef EXPAND_ROOT_KIND
// These tagged pointers are special-cased for performance.
Id,

View File

@ -53,7 +53,7 @@ Fail(JSContext* cx, const char* str)
}
static bool
Fail(JSContext* cx, Decoder& d, const char* str)
Fail(JSContext* cx, const Decoder& d, const char* str)
{
uint32_t offset = d.currentOffset();
char offsetStr[sizeof "4294967295"];
@ -83,7 +83,7 @@ class ValidatingPolicy : public ExprIterPolicy
static const bool Validate = true;
// Fail by printing a message, using the contains JSContext.
bool fail(const char* str, Decoder& d) {
bool fail(const char* str, const Decoder& d) {
return Fail(cx_, d, str);
}
@ -97,20 +97,17 @@ class FunctionDecoder
const ModuleGenerator& mg_;
ValidatingExprIter iter_;
const ValTypeVector& locals_;
const DeclaredSig& sig_;
public:
FunctionDecoder(JSContext* cx, const ModuleGenerator& mg, Decoder& d,
uint32_t funcIndex, const ValTypeVector& locals)
const ValTypeVector& locals)
: mg_(mg),
iter_(ValidatingPolicy(cx), d),
locals_(locals),
sig_(mg.funcSig(funcIndex))
locals_(locals)
{}
const ModuleGenerator& mg() const { return mg_; }
ValidatingExprIter& iter() { return iter_; }
const ValTypeVector& locals() const { return locals_; }
const DeclaredSig& sig() const { return sig_; }
bool checkI64Support() {
if (!IsI64Implemented())
@ -790,19 +787,23 @@ DecodeMemorySection(JSContext* cx, Decoder& d, ModuleGenerator& mg, MutableHandl
if (!d.readVarU32(&initialSizePages))
return Fail(cx, d, "expected initial memory size");
CheckedInt<int32_t> initialSize = initialSizePages;
CheckedInt<uint32_t> initialSize = initialSizePages;
initialSize *= PageSize;
if (!initialSize.isValid())
return Fail(cx, d, "initial memory size too big");
// ArrayBufferObject can't currently allocate more than INT32_MAX bytes.
if (initialSize.value() > uint32_t(INT32_MAX))
return false;
uint32_t maxSizePages;
if (!d.readVarU32(&maxSizePages))
return Fail(cx, d, "expected initial memory size");
CheckedInt<int32_t> maxSize = maxSizePages;
CheckedInt<uint32_t> maxSize = maxSizePages;
maxSize *= PageSize;
if (!maxSize.isValid())
return Fail(cx, d, "initial memory size too big");
return Fail(cx, d, "maximum memory size too big");
uint8_t exported;
if (!d.readFixedU8(&exported))
@ -932,7 +933,8 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
return false;
ValTypeVector locals;
if (!locals.appendAll(mg.funcSig(funcIndex).args()))
const DeclaredSig& sig = mg.funcSig(funcIndex);
if (!locals.appendAll(sig.args()))
return false;
if (!DecodeLocalEntries(d, &locals))
@ -943,7 +945,7 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
return false;
}
FunctionDecoder f(cx, mg, d, funcIndex, locals);
FunctionDecoder f(cx, mg, d, locals);
if (!f.iter().readFunctionStart())
return false;
@ -953,7 +955,7 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
return false;
}
if (!f.iter().readFunctionEnd(f.sig().ret(), nullptr))
if (!f.iter().readFunctionEnd(sig.ret(), nullptr))
return false;
if (d.currentPosition() != bodyEnd)

View File

@ -664,9 +664,9 @@ class Decoder
return cur_ == end_;
}
uintptr_t bytesRemain() const {
size_t bytesRemain() const {
MOZ_ASSERT(end_ >= cur_);
return uintptr_t(end_ - cur_);
return size_t(end_ - cur_);
}
const uint8_t* currentPosition() const {
return cur_;

View File

@ -205,7 +205,7 @@ struct ExprIterPolicy
static const bool Output = false;
// This function is called to report failures.
static bool fail(const char*, Decoder&) {
static bool fail(const char*, const Decoder&) {
MOZ_CRASH("unexpected validation failure");
return false;
}
@ -666,7 +666,7 @@ ExprIter<Policy>::readReturn(Value* value)
uint32_t arity;
if (!readVarU32(&arity))
return fail("failed to read return arity");
if (arity > 1)
if (Validate && arity > 1)
return fail("return arity too big");
TypeAndValue<Value> tv;
@ -880,7 +880,7 @@ ExprIter<Policy>::readBr(uint32_t* relativeDepth, ExprType* type, Value* value)
uint32_t arity;
if (!readVarU32(&arity))
return fail("unable to read br arity");
if (arity > 1)
if (Validate && arity > 1)
return fail("br arity too big");
uint32_t validateRelativeDepth;
@ -919,7 +919,7 @@ ExprIter<Policy>::readBrIf(uint32_t* relativeDepth, ExprType* type, Value* value
uint32_t arity;
if (!readVarU32(&arity))
return fail("unable to read br_if arity");
if (arity > 1)
if (Validate && arity > 1)
return fail("br_if arity too big");
uint32_t validateRelativeDepth;
@ -964,7 +964,7 @@ ExprIter<Policy>::readBrTable(uint32_t* tableLength, ExprType* type,
uint32_t arity;
if (!readVarU32(&arity))
return fail("unable to read br_table arity");
if (arity > 1)
if (Validate && arity > 1)
return fail("br_table arity too big");
TypeAndValue<Value> tv;

View File

@ -55,6 +55,11 @@ if [ ! -f "$ABSDIR/variants/$VARIANT" ]; then
exit 1
fi
if [[ "$VARIANT" = "nonunified" ]]; then
# Hack the moz.build files to turn off unified compilation.
find "$SOURCE/js/src" -name moz.build -exec sed -i 's/UNIFIED_SOURCES/SOURCES/' '{}' ';'
fi
(cd "$SOURCE/js/src"; autoconf-2.13 || autoconf2.13 || autoconf213)
TRY_OVERRIDE=$SOURCE/js/src/config.try
@ -216,6 +221,10 @@ elif [[ "$VARIANT" = "arm-sim" ||
"$VARIANT" = "arm-sim-osx" ||
"$VARIANT" = "plaindebug" ]]; then
export JSTESTS_EXTRA_ARGS=--jitflags=debug
elif [[ "$VARIANT" = "nonunified" ]]; then
RUN_JSTESTS=false
RUN_JITTEST=false
RUN_JSAPITESTS=false
elif [[ "$VARIANT" = arm64* ]]; then
# The ARM64 simulator is slow, so some tests are timing out.
# Run a reduced set of test cases so this doesn't take hours.

View File

@ -0,0 +1 @@
--enable-debug

View File

@ -217,23 +217,10 @@ js::Allocate(ExclusiveContext* cx)
return GCRuntime::tryNewTenuredThing<T, allowGC>(cx, kind, thingSize);
}
#define FOR_ALL_NON_OBJECT_GC_LAYOUTS(macro) \
macro(JS::Symbol) \
macro(JSExternalString) \
macro(JSFatInlineString) \
macro(JSScript) \
macro(JSString) \
macro(js::AccessorShape) \
macro(js::BaseShape) \
macro(js::LazyScript) \
macro(js::ObjectGroup) \
macro(js::Shape) \
macro(js::jit::JitCode)
#define DECL_ALLOCATOR_INSTANCES(type) \
#define DECL_ALLOCATOR_INSTANCES(allocKind, traceKind, type, sizedType) \
template type* js::Allocate<type, NoGC>(ExclusiveContext* cx);\
template type* js::Allocate<type, CanGC>(ExclusiveContext* cx);
FOR_ALL_NON_OBJECT_GC_LAYOUTS(DECL_ALLOCATOR_INSTANCES)
FOR_EACH_NONOBJECT_ALLOCKIND(DECL_ALLOCATOR_INSTANCES)
#undef DECL_ALLOCATOR_INSTANCES
template <typename T, AllowGC allowGC>

View File

@ -114,39 +114,60 @@ enum class AllocKind {
LAST = LIMIT - 1
};
// Macro to enumerate the different allocation kinds supplying information about
// the trace kind, C++ type and allocation size.
#define FOR_EACH_OBJECT_ALLOCKIND(D) \
/* AllocKind TraceKind TypeName SizedType */ \
D(FUNCTION, Object, JSObject, JSFunction) \
D(FUNCTION_EXTENDED, Object, JSObject, FunctionExtended) \
D(OBJECT0, Object, JSObject, JSObject_Slots0) \
D(OBJECT0_BACKGROUND, Object, JSObject, JSObject_Slots0) \
D(OBJECT2, Object, JSObject, JSObject_Slots2) \
D(OBJECT2_BACKGROUND, Object, JSObject, JSObject_Slots2) \
D(OBJECT4, Object, JSObject, JSObject_Slots4) \
D(OBJECT4_BACKGROUND, Object, JSObject, JSObject_Slots4) \
D(OBJECT8, Object, JSObject, JSObject_Slots8) \
D(OBJECT8_BACKGROUND, Object, JSObject, JSObject_Slots8) \
D(OBJECT12, Object, JSObject, JSObject_Slots12) \
D(OBJECT12_BACKGROUND, Object, JSObject, JSObject_Slots12) \
D(OBJECT16, Object, JSObject, JSObject_Slots16) \
D(OBJECT16_BACKGROUND, Object, JSObject, JSObject_Slots16)
#define FOR_EACH_NONOBJECT_ALLOCKIND(D) \
/* AllocKind TraceKind TypeName SizedType */ \
D(SCRIPT, Script, JSScript, JSScript) \
D(LAZY_SCRIPT, LazyScript, js::LazyScript, js::LazyScript) \
D(SHAPE, Shape, js::Shape, js::Shape) \
D(ACCESSOR_SHAPE, Shape, js::AccessorShape, js::AccessorShape) \
D(BASE_SHAPE, BaseShape, js::BaseShape, js::BaseShape) \
D(OBJECT_GROUP, ObjectGroup, js::ObjectGroup, js::ObjectGroup) \
D(FAT_INLINE_STRING, String, JSFatInlineString, JSFatInlineString) \
D(STRING, String, JSString, JSString) \
D(EXTERNAL_STRING, String, JSExternalString, JSExternalString) \
D(SYMBOL, Symbol, JS::Symbol, JS::Symbol) \
D(JITCODE, JitCode, js::jit::JitCode, js::jit::JitCode)
#define FOR_EACH_ALLOCKIND(D) \
/* PrettyName TypeName */ \
D(FUNCTION, JSFunction) \
D(FUNCTION_EXTENDED, JSFunction) \
D(OBJECT0, JSObject) \
D(OBJECT0_BACKGROUND, JSObject) \
D(OBJECT2, JSObject) \
D(OBJECT2_BACKGROUND, JSObject) \
D(OBJECT4, JSObject) \
D(OBJECT4_BACKGROUND, JSObject) \
D(OBJECT8, JSObject) \
D(OBJECT8_BACKGROUND, JSObject) \
D(OBJECT12, JSObject) \
D(OBJECT12_BACKGROUND, JSObject) \
D(OBJECT16, JSObject) \
D(OBJECT16_BACKGROUND, JSObject) \
D(SCRIPT, JSScript) \
D(LAZY_SCRIPT, js::LazyScript) \
D(SHAPE, js::Shape) \
D(ACCESSOR_SHAPE, js::AccessorShape) \
D(BASE_SHAPE, js::BaseShape) \
D(OBJECT_GROUP, js::ObjectGroup) \
D(FAT_INLINE_STRING, JSFatInlineString) \
D(STRING, JSString) \
D(EXTERNAL_STRING, JSExternalString) \
D(SYMBOL, JS::Symbol) \
D(JITCODE, js::JitCode)
FOR_EACH_OBJECT_ALLOCKIND(D) \
FOR_EACH_NONOBJECT_ALLOCKIND(D)
static_assert(int(AllocKind::FIRST) == 0, "Various places depend on AllocKind starting at 0, "
"please audit them carefully!");
static_assert(int(AllocKind::OBJECT_FIRST) == 0, "Various places depend on AllocKind::OBJECT_FIRST "
"being 0, please audit them carefully!");
inline bool
IsAllocKind(AllocKind kind)
{
return kind >= AllocKind::FIRST && kind <= AllocKind::LIMIT;
}
inline bool
IsValidAllocKind(AllocKind kind)
{
return kind >= AllocKind::FIRST && kind <= AllocKind::LAST;
}
inline bool
IsObjectAllocKind(AllocKind kind)
{
@ -159,17 +180,6 @@ IsShapeAllocKind(AllocKind kind)
return kind == AllocKind::SHAPE || kind == AllocKind::ACCESSOR_SHAPE;
}
inline bool
IsValidAllocKind(AllocKind kind)
{
return kind >= AllocKind::FIRST && kind <= AllocKind::LAST;
}
inline bool IsAllocKind(AllocKind kind)
{
return kind >= AllocKind::FIRST && kind <= AllocKind::LIMIT;
}
// Returns a sequence for use in a range-based for loop,
// to iterate over all alloc kinds.
inline decltype(mozilla::MakeEnumeratedRange<int>(AllocKind::FIRST, AllocKind::LIMIT))
@ -210,31 +220,10 @@ static inline JS::TraceKind
MapAllocToTraceKind(AllocKind kind)
{
static const JS::TraceKind map[] = {
JS::TraceKind::Object, /* AllocKind::FUNCTION */
JS::TraceKind::Object, /* AllocKind::FUNCTION_EXTENDED */
JS::TraceKind::Object, /* AllocKind::OBJECT0 */
JS::TraceKind::Object, /* AllocKind::OBJECT0_BACKGROUND */
JS::TraceKind::Object, /* AllocKind::OBJECT2 */
JS::TraceKind::Object, /* AllocKind::OBJECT2_BACKGROUND */
JS::TraceKind::Object, /* AllocKind::OBJECT4 */
JS::TraceKind::Object, /* AllocKind::OBJECT4_BACKGROUND */
JS::TraceKind::Object, /* AllocKind::OBJECT8 */
JS::TraceKind::Object, /* AllocKind::OBJECT8_BACKGROUND */
JS::TraceKind::Object, /* AllocKind::OBJECT12 */
JS::TraceKind::Object, /* AllocKind::OBJECT12_BACKGROUND */
JS::TraceKind::Object, /* AllocKind::OBJECT16 */
JS::TraceKind::Object, /* AllocKind::OBJECT16_BACKGROUND */
JS::TraceKind::Script, /* AllocKind::SCRIPT */
JS::TraceKind::LazyScript, /* AllocKind::LAZY_SCRIPT */
JS::TraceKind::Shape, /* AllocKind::SHAPE */
JS::TraceKind::Shape, /* AllocKind::ACCESSOR_SHAPE */
JS::TraceKind::BaseShape, /* AllocKind::BASE_SHAPE */
JS::TraceKind::ObjectGroup, /* AllocKind::OBJECT_GROUP */
JS::TraceKind::String, /* AllocKind::FAT_INLINE_STRING */
JS::TraceKind::String, /* AllocKind::STRING */
JS::TraceKind::String, /* AllocKind::EXTERNAL_STRING */
JS::TraceKind::Symbol, /* AllocKind::SYMBOL */
JS::TraceKind::JitCode, /* AllocKind::JITCODE */
#define EXPAND_ELEMENT(allocKind, traceKind, type, sizedType) \
JS::TraceKind::traceKind,
FOR_EACH_ALLOCKIND(EXPAND_ELEMENT)
#undef EXPAND_ELEMENT
};
static_assert(MOZ_ARRAY_LENGTH(map) == size_t(AllocKind::LIMIT),
@ -326,6 +315,9 @@ class TenuredCell : public Cell
static MOZ_ALWAYS_INLINE void writeBarrierPost(void* cellp, TenuredCell* prior,
TenuredCell* next);
// Default implementation for kinds that don't require fixup.
void fixupAfterMovingGC() {}
#ifdef DEBUG
inline bool isAligned() const;
#endif

View File

@ -350,6 +350,9 @@ AssertRootMarkingPhase(JSTracer* trc)
// statically select the correct Cell layout for marking. Below, we instantiate
// each override with a declaration of the most derived layout type.
//
// The use of TraceKind::Null for the case where the type is not matched
// generates a compile error as no template instantiated for that kind.
//
// Usage:
// BaseGCType<T>::type
//
@ -357,16 +360,13 @@ AssertRootMarkingPhase(JSTracer* trc)
// BaseGCType<JSFunction>::type => JSObject
// BaseGCType<UnownedBaseShape>::type => BaseShape
// etc.
template <typename T,
JS::TraceKind = IsBaseOf<JSObject, T>::value ? JS::TraceKind::Object
: IsBaseOf<JSString, T>::value ? JS::TraceKind::String
: IsBaseOf<JS::Symbol, T>::value ? JS::TraceKind::Symbol
: IsBaseOf<JSScript, T>::value ? JS::TraceKind::Script
: IsBaseOf<Shape, T>::value ? JS::TraceKind::Shape
: IsBaseOf<BaseShape, T>::value ? JS::TraceKind::BaseShape
: IsBaseOf<jit::JitCode, T>::value ? JS::TraceKind::JitCode
: IsBaseOf<LazyScript, T>::value ? JS::TraceKind::LazyScript
: JS::TraceKind::ObjectGroup>
template <typename T, JS::TraceKind =
#define EXPAND_MATCH_TYPE(name, type, _) \
IsBaseOf<type, T>::value ? JS::TraceKind::name :
JS_FOR_EACH_TRACEKIND(EXPAND_MATCH_TYPE)
#undef EXPAND_MATCH_TYPE
JS::TraceKind::Null>
struct BaseGCType;
#define IMPL_BASE_GC_TYPE(name, type_, _) \
template <typename T> struct BaseGCType<T, JS::TraceKind:: name> { typedef type_ type; };

View File

@ -65,25 +65,31 @@ MarkExactStackRootList(JSTracer* trc, JS::Rooted<void*>* rooter, const char* nam
}
}
static inline void
TraceStackRoots(JSTracer* trc, RootedListHeads& stackRoots)
{
#define MARK_ROOTS(name, type, _) \
MarkExactStackRootList<type*>(trc, stackRoots[JS::RootKind::name], "exact-" #name);
JS_FOR_EACH_TRACEKIND(MARK_ROOTS)
#undef MARK_ROOTS
MarkExactStackRootList<jsid>(trc, stackRoots[JS::RootKind::Id], "exact-id");
MarkExactStackRootList<Value>(trc, stackRoots[JS::RootKind::Value], "exact-value");
MarkExactStackRootList<ConcreteTraceable,
js::DispatchWrapper<ConcreteTraceable>::TraceWrapped>(
trc, stackRoots[JS::RootKind::Traceable], "Traceable");
}
void
js::RootLists::traceStackRoots(JSTracer* trc)
{
#define MARK_ROOTS(name, type, _) \
MarkExactStackRootList<type*>(trc, stackRoots_[JS::RootKind::name], "exact-" #name);
JS_FOR_EACH_TRACEKIND(MARK_ROOTS)
#undef MARK_ROOTS
MarkExactStackRootList<jsid>(trc, stackRoots_[JS::RootKind::Id], "exact-id");
MarkExactStackRootList<Value>(trc, stackRoots_[JS::RootKind::Value], "exact-value");
MarkExactStackRootList<ConcreteTraceable,
js::DispatchWrapper<ConcreteTraceable>::TraceWrapped>(
trc, stackRoots_[JS::RootKind::Traceable], "Traceable");
TraceStackRoots(trc, stackRoots_);
}
static void
MarkExactStackRoots(JSRuntime* rt, JSTracer* trc)
{
for (ContextIter cx(rt); !cx.done(); cx.next())
cx->roots.traceStackRoots(trc);
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next())
TraceStackRoots(trc, zone->stackRoots_);
rt->mainThread.roots.traceStackRoots(trc);
}
@ -113,8 +119,6 @@ JS_FOR_EACH_TRACEKIND(MARK_ROOTS)
static void
MarkPersistentRooted(JSRuntime* rt, JSTracer* trc)
{
for (ContextIter cx(rt); !cx.done(); cx.next())
cx->roots.tracePersistentRoots(trc);
rt->mainThread.roots.tracePersistentRoots(trc);
}

View File

@ -0,0 +1,6 @@
// |jit-test| allow-oom
if (!('oomTest' in this))
quit();
evalcx('oomTest(function() { Array(...""); })', newGlobal());

View File

@ -163,3 +163,6 @@ assertErrorMessage(() => wasmEvalText('(module (memory 1) (func (f32.store offse
assertErrorMessage(() => wasmEvalText('(module (memory 1) (func (i32.store offset=0 (i32.const 0) (f32.const 0))))'), TypeError, mismatchError("f32", "i32"));
assertErrorMessage(() => wasmEvalText('(module (memory 1) (func (i32.store offset=0 (i32.const 0) (f64.const 0))))'), TypeError, mismatchError("f64", "i32"));
wasmEvalText('(module (memory 0 65535))')
assertErrorMessage(() => wasmEvalText('(module (memory 0 65536))'), TypeError, /maximum memory size too big/);

View File

@ -147,11 +147,10 @@ wasmEvalText('(module (import $foo "a" "" (result f64)))', {a: ()=> {}});
wasmEvalText('(module (memory 0))');
wasmEvalText('(module (memory 1))');
assertErrorMessage(() => wasmEvalText('(module (memory 65536))'), TypeError, /initial memory size too big/);
assertErrorMessage(() => wasmEvalText('(module (memory 32768))'), TypeError, /initial memory size too big/);
// May OOM, but must not crash:
try {
wasmEvalText('(module (memory 32767))');
wasmEvalText('(module (memory 65535))');
} catch (e) {
print(e);
assertEq(String(e).indexOf("out of memory") != -1, true);

View File

@ -114,7 +114,6 @@ class JitCode : public gc::TenuredCell
void traceChildren(JSTracer* trc);
void finalize(FreeOp* fop);
void fixupAfterMovingGC() {}
void setInvalidated() {
invalidated_ = true;
}

View File

@ -493,6 +493,7 @@ MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuff
MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments")
MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_RANGEERR, "argument {0} must be >= 0")
MSG_DEF(JSMSG_TYPED_ARRAY_DETACHED, 0, JSEXN_TYPEERR, "attempting to access detached ArrayBuffer")
MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS, 0, JSEXN_RANGEERR, "attempting to construct out-of-bounds TypedArray on ArrayBuffer")
// Shared array buffer
MSG_DEF(JSMSG_SHARED_ARRAY_BAD_LENGTH, 0, JSEXN_RANGEERR, "length argument out of range")

View File

@ -6447,19 +6447,67 @@ DescribeScriptedCaller(JSContext* cx, AutoFilename* filename, unsigned* lineno,
return true;
}
// Fast path to get the activation to use for GetScriptedCallerGlobal. If this
// returns false, the fast path didn't work out and the caller has to use the
// (much slower) NonBuiltinFrameIter path.
//
// The optimization here is that we skip Ion-inlined frames and only look at
// 'outer' frames. That's fine: each activation is tied to a single compartment,
// so if an activation contains at least one non-self-hosted frame, we can use
// the activation's global for GetScriptedCallerGlobal. If, however, all 'outer'
// frames are self-hosted, it's possible Ion inlined a non-self-hosted script,
// so we must return false and use the slower path.
static bool
GetScriptedCallerActivationFast(JSContext* cx, Activation** activation)
{
ActivationIterator activationIter(cx->runtime());
while (!activationIter.done() && activationIter->cx() != cx)
++activationIter;
if (activationIter.done()) {
*activation = nullptr;
return true;
}
*activation = activationIter.activation();
if (activationIter->isJit()) {
for (jit::JitFrameIterator iter(activationIter); !iter.done(); ++iter) {
if (iter.isScripted() && !iter.script()->selfHosted())
return true;
}
} else if (activationIter->isInterpreter()) {
for (InterpreterFrameIterator iter((*activation)->asInterpreter()); !iter.done(); ++iter) {
if (!iter.frame()->script()->selfHosted())
return true;
}
}
return false;
}
JS_PUBLIC_API(JSObject*)
GetScriptedCallerGlobal(JSContext* cx)
{
NonBuiltinFrameIter i(cx);
if (i.done())
return nullptr;
Activation* activation;
if (GetScriptedCallerActivationFast(cx, &activation)) {
if (!activation)
return nullptr;
} else {
NonBuiltinFrameIter i(cx);
if (i.done())
return nullptr;
activation = i.activation();
}
// If the caller is hidden, the embedding wants us to return null here so
// that it can check its own stack (see HideScriptedCaller).
if (i.activation()->scriptedCallerIsHidden())
if (activation->scriptedCallerIsHidden())
return nullptr;
GlobalObject* global = i.activation()->compartment()->maybeGlobal();
GlobalObject* global = activation->compartment()->maybeGlobal();
// Noone should be running code in the atoms compartment or running code in
// a compartment without any live objects, so there should definitely be a

View File

@ -261,52 +261,22 @@ const AllocKind gc::slotsToThingKind[] = {
static_assert(JS_ARRAY_LENGTH(slotsToThingKind) == SLOTS_TO_THING_KIND_LIMIT,
"We have defined a slot count for each kind.");
// Assert that SortedArenaList::MinThingSize and sizeof(FreeSpan) are <= the
// real minimum thing size. Also assert each size is a multiple of CellSize.
#define CHECK_THING_SIZE_INNER(x_) \
static_assert(x_ >= SortedArenaList::MinThingSize, \
#x_ " is less than SortedArenaList::MinThingSize!"); \
static_assert(x_ >= sizeof(FreeSpan), \
#x_ " is less than sizeof(FreeSpan)"); \
static_assert(x_ % CellSize == 0, \
#x_ " not a multiple of CellSize");
#define CHECK_THING_SIZE(allocKind, traceKind, type, sizedType) \
static_assert(sizeof(sizedType) >= SortedArenaList::MinThingSize, \
#sizedType " is smaller than SortedArenaList::MinThingSize!"); \
static_assert(sizeof(sizedType) >= sizeof(FreeSpan), \
#sizedType " is smaller than FreeSpan"); \
static_assert(sizeof(sizedType) % CellSize == 0, \
"Size of " #sizedType " is not a multiple of CellSize");
FOR_EACH_ALLOCKIND(CHECK_THING_SIZE);
#undef CHECK_THING_SIZE
#define CHECK_THING_SIZE(...) { __VA_ARGS__ }; /* Define the array. */ \
MOZ_FOR_EACH(CHECK_THING_SIZE_INNER, (), (__VA_ARGS__ 0x20))
#define CHECK_ZEAL(name, value) \
static_assert(ZealMode::Limit >= ZealMode::name, \
"ZealMode::Limit shouldn't be smaller than " #name);
JS_FOR_EACH_ZEAL_MODE(CHECK_ZEAL)
#undef CHECK_ZEAL
const uint32_t Arena::ThingSizes[] = CHECK_THING_SIZE(
sizeof(JSFunction), /* AllocKind::FUNCTION */
sizeof(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */
sizeof(JSObject_Slots0), /* AllocKind::OBJECT0 */
sizeof(JSObject_Slots0), /* AllocKind::OBJECT0_BACKGROUND */
sizeof(JSObject_Slots2), /* AllocKind::OBJECT2 */
sizeof(JSObject_Slots2), /* AllocKind::OBJECT2_BACKGROUND */
sizeof(JSObject_Slots4), /* AllocKind::OBJECT4 */
sizeof(JSObject_Slots4), /* AllocKind::OBJECT4_BACKGROUND */
sizeof(JSObject_Slots8), /* AllocKind::OBJECT8 */
sizeof(JSObject_Slots8), /* AllocKind::OBJECT8_BACKGROUND */
sizeof(JSObject_Slots12), /* AllocKind::OBJECT12 */
sizeof(JSObject_Slots12), /* AllocKind::OBJECT12_BACKGROUND */
sizeof(JSObject_Slots16), /* AllocKind::OBJECT16 */
sizeof(JSObject_Slots16), /* AllocKind::OBJECT16_BACKGROUND */
sizeof(JSScript), /* AllocKind::SCRIPT */
sizeof(LazyScript), /* AllocKind::LAZY_SCRIPT */
sizeof(Shape), /* AllocKind::SHAPE */
sizeof(AccessorShape), /* AllocKind::ACCESSOR_SHAPE */
sizeof(BaseShape), /* AllocKind::BASE_SHAPE */
sizeof(ObjectGroup), /* AllocKind::OBJECT_GROUP */
sizeof(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */
sizeof(JSString), /* AllocKind::STRING */
sizeof(JSExternalString), /* AllocKind::EXTERNAL_STRING */
sizeof(JS::Symbol), /* AllocKind::SYMBOL */
sizeof(jit::JitCode), /* AllocKind::JITCODE */
);
const uint32_t Arena::ThingSizes[] = {
#define EXPAND_THING_SIZE(allocKind, traceKind, type, sizedType) \
sizeof(sizedType),
FOR_EACH_ALLOCKIND(EXPAND_THING_SIZE)
#undef EXPAND_THING_SIZE
};
FreeSpan ArenaLists::placeholder;
@ -316,31 +286,10 @@ FreeSpan ArenaLists::placeholder;
#define OFFSET(type) uint32_t(ArenaHeaderSize + (ArenaSize - ArenaHeaderSize) % sizeof(type))
const uint32_t Arena::FirstThingOffsets[] = {
OFFSET(JSFunction), /* AllocKind::FUNCTION */
OFFSET(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */
OFFSET(JSObject_Slots0), /* AllocKind::OBJECT0 */
OFFSET(JSObject_Slots0), /* AllocKind::OBJECT0_BACKGROUND */
OFFSET(JSObject_Slots2), /* AllocKind::OBJECT2 */
OFFSET(JSObject_Slots2), /* AllocKind::OBJECT2_BACKGROUND */
OFFSET(JSObject_Slots4), /* AllocKind::OBJECT4 */
OFFSET(JSObject_Slots4), /* AllocKind::OBJECT4_BACKGROUND */
OFFSET(JSObject_Slots8), /* AllocKind::OBJECT8 */
OFFSET(JSObject_Slots8), /* AllocKind::OBJECT8_BACKGROUND */
OFFSET(JSObject_Slots12), /* AllocKind::OBJECT12 */
OFFSET(JSObject_Slots12), /* AllocKind::OBJECT12_BACKGROUND */
OFFSET(JSObject_Slots16), /* AllocKind::OBJECT16 */
OFFSET(JSObject_Slots16), /* AllocKind::OBJECT16_BACKGROUND */
OFFSET(JSScript), /* AllocKind::SCRIPT */
OFFSET(LazyScript), /* AllocKind::LAZY_SCRIPT */
OFFSET(Shape), /* AllocKind::SHAPE */
OFFSET(AccessorShape), /* AllocKind::ACCESSOR_SHAPE */
OFFSET(BaseShape), /* AllocKind::BASE_SHAPE */
OFFSET(ObjectGroup), /* AllocKind::OBJECT_GROUP */
OFFSET(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */
OFFSET(JSString), /* AllocKind::STRING */
OFFSET(JSExternalString), /* AllocKind::EXTERNAL_STRING */
OFFSET(JS::Symbol), /* AllocKind::SYMBOL */
OFFSET(jit::JitCode), /* AllocKind::JITCODE */
#define EXPAND_FIRST_THING_OFFSET(allocKind, traceKind, type, sizedType) \
OFFSET(sizedType),
FOR_EACH_ALLOCKIND(EXPAND_FIRST_THING_OFFSET)
#undef EXPAND_FIRST_THING_OFFSET
};
#undef OFFSET
@ -348,31 +297,10 @@ const uint32_t Arena::FirstThingOffsets[] = {
#define COUNT(type) uint32_t((ArenaSize - ArenaHeaderSize) / sizeof(type))
const uint32_t Arena::ThingsPerArena[] = {
COUNT(JSFunction), /* AllocKind::FUNCTION */
COUNT(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */
COUNT(JSObject_Slots0), /* AllocKind::OBJECT0 */
COUNT(JSObject_Slots0), /* AllocKind::OBJECT0_BACKGROUND */
COUNT(JSObject_Slots2), /* AllocKind::OBJECT2 */
COUNT(JSObject_Slots2), /* AllocKind::OBJECT2_BACKGROUND */
COUNT(JSObject_Slots4), /* AllocKind::OBJECT4 */
COUNT(JSObject_Slots4), /* AllocKind::OBJECT4_BACKGROUND */
COUNT(JSObject_Slots8), /* AllocKind::OBJECT8 */
COUNT(JSObject_Slots8), /* AllocKind::OBJECT8_BACKGROUND */
COUNT(JSObject_Slots12), /* AllocKind::OBJECT12 */
COUNT(JSObject_Slots12), /* AllocKind::OBJECT12_BACKGROUND */
COUNT(JSObject_Slots16), /* AllocKind::OBJECT16 */
COUNT(JSObject_Slots16), /* AllocKind::OBJECT16_BACKGROUND */
COUNT(JSScript), /* AllocKind::SCRIPT */
COUNT(LazyScript), /* AllocKind::LAZY_SCRIPT */
COUNT(Shape), /* AllocKind::SHAPE */
COUNT(AccessorShape), /* AllocKind::ACCESSOR_SHAPE */
COUNT(BaseShape), /* AllocKind::BASE_SHAPE */
COUNT(ObjectGroup), /* AllocKind::OBJECT_GROUP */
COUNT(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */
COUNT(JSString), /* AllocKind::STRING */
COUNT(JSExternalString), /* AllocKind::EXTERNAL_STRING */
COUNT(JS::Symbol), /* AllocKind::SYMBOL */
COUNT(jit::JitCode), /* AllocKind::JITCODE */
#define EXPAND_THINGS_PER_ARENA(allocKind, traceKind, type, sizedType) \
COUNT(sizedType),
FOR_EACH_ALLOCKIND(EXPAND_THINGS_PER_ARENA)
#undef EXPAND_THINGS_PER_ARENA
};
#undef COUNT
@ -604,43 +532,12 @@ FinalizeArenas(FreeOp* fop,
ArenaLists::KeepArenasEnum keepArenas)
{
switch (thingKind) {
case AllocKind::FUNCTION:
case AllocKind::FUNCTION_EXTENDED:
case AllocKind::OBJECT0:
case AllocKind::OBJECT0_BACKGROUND:
case AllocKind::OBJECT2:
case AllocKind::OBJECT2_BACKGROUND:
case AllocKind::OBJECT4:
case AllocKind::OBJECT4_BACKGROUND:
case AllocKind::OBJECT8:
case AllocKind::OBJECT8_BACKGROUND:
case AllocKind::OBJECT12:
case AllocKind::OBJECT12_BACKGROUND:
case AllocKind::OBJECT16:
case AllocKind::OBJECT16_BACKGROUND:
return FinalizeTypedArenas<JSObject>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::SCRIPT:
return FinalizeTypedArenas<JSScript>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::LAZY_SCRIPT:
return FinalizeTypedArenas<LazyScript>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::SHAPE:
return FinalizeTypedArenas<Shape>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::ACCESSOR_SHAPE:
return FinalizeTypedArenas<AccessorShape>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::BASE_SHAPE:
return FinalizeTypedArenas<BaseShape>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::OBJECT_GROUP:
return FinalizeTypedArenas<ObjectGroup>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::STRING:
return FinalizeTypedArenas<JSString>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::FAT_INLINE_STRING:
return FinalizeTypedArenas<JSFatInlineString>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::EXTERNAL_STRING:
return FinalizeTypedArenas<JSExternalString>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::SYMBOL:
return FinalizeTypedArenas<JS::Symbol>(fop, src, dest, thingKind, budget, keepArenas);
case AllocKind::JITCODE:
return FinalizeTypedArenas<jit::JitCode>(fop, src, dest, thingKind, budget, keepArenas);
#define EXPAND_CASE(allocKind, traceKind, type, sizedType) \
case AllocKind::allocKind: \
return FinalizeTypedArenas<type>(fop, src, dest, thingKind, budget, keepArenas);
FOR_EACH_ALLOCKIND(EXPAND_CASE)
#undef EXPAND_CASE
default:
MOZ_CRASH("Invalid alloc kind");
}
@ -2543,49 +2440,15 @@ static void
UpdateArenaPointers(MovingTracer* trc, Arena* arena)
{
AllocKind kind = arena->getAllocKind();
JS::TraceKind traceKind = MapAllocToTraceKind(kind);
switch (kind) {
case AllocKind::FUNCTION:
case AllocKind::FUNCTION_EXTENDED:
case AllocKind::OBJECT0:
case AllocKind::OBJECT0_BACKGROUND:
case AllocKind::OBJECT2:
case AllocKind::OBJECT2_BACKGROUND:
case AllocKind::OBJECT4:
case AllocKind::OBJECT4_BACKGROUND:
case AllocKind::OBJECT8:
case AllocKind::OBJECT8_BACKGROUND:
case AllocKind::OBJECT12:
case AllocKind::OBJECT12_BACKGROUND:
case AllocKind::OBJECT16:
case AllocKind::OBJECT16_BACKGROUND:
UpdateArenaPointersTyped<JSObject>(trc, arena, traceKind);
return;
case AllocKind::SCRIPT:
UpdateArenaPointersTyped<JSScript>(trc, arena, traceKind);
return;
case AllocKind::LAZY_SCRIPT:
UpdateArenaPointersTyped<LazyScript>(trc, arena, traceKind);
return;
case AllocKind::SHAPE:
UpdateArenaPointersTyped<Shape>(trc, arena, traceKind);
return;
case AllocKind::ACCESSOR_SHAPE:
UpdateArenaPointersTyped<AccessorShape>(trc, arena, traceKind);
return;
case AllocKind::BASE_SHAPE:
UpdateArenaPointersTyped<BaseShape>(trc, arena, traceKind);
return;
case AllocKind::OBJECT_GROUP:
UpdateArenaPointersTyped<ObjectGroup>(trc, arena, traceKind);
return;
case AllocKind::STRING:
UpdateArenaPointersTyped<JSString>(trc, arena, traceKind);
return;
case AllocKind::JITCODE:
UpdateArenaPointersTyped<jit::JitCode>(trc, arena, traceKind);
#define EXPAND_CASE(allocKind, traceKind, type, sizedType) \
case AllocKind::allocKind: \
UpdateArenaPointersTyped<type>(trc, arena, JS::TraceKind::traceKind); \
return;
FOR_EACH_ALLOCKIND(EXPAND_CASE)
#undef EXPAND_CASE
default:
MOZ_CRASH("Invalid alloc kind for UpdateArenaPointers");
}
@ -3961,11 +3824,13 @@ static const char*
AllocKindToAscii(AllocKind kind)
{
switch(kind) {
#define MAKE_CASE(name, _) case AllocKind:: name: return #name;
FOR_EACH_ALLOCKIND(MAKE_CASE)
#define MAKE_CASE(allocKind, traceKind, type, sizedType) \
case AllocKind:: allocKind: return #allocKind;
FOR_EACH_ALLOCKIND(MAKE_CASE)
#undef MAKE_CASE
case AllocKind::LIMIT: MOZ_FALLTHROUGH;
default: MOZ_CRASH("Unknown AllocKind in AllocKindToAscii");
default:
MOZ_CRASH("Unknown AllocKind in AllocKindToAscii");
}
}
#endif // DEBUG

View File

@ -53,19 +53,19 @@ enum State {
NUM_STATES
};
/* Map from C++ type to alloc kind. JSObject does not have a 1:1 mapping, so must use Arena::thingSize. */
/*
* Map from C++ type to alloc kind for non-object types. JSObject does not have
* a 1:1 mapping, so must use Arena::thingSize.
*
* The AllocKind is available as MapTypeToFinalizeKind<SomeType>::kind.
*/
template <typename T> struct MapTypeToFinalizeKind {};
template <> struct MapTypeToFinalizeKind<JSScript> { static const AllocKind kind = AllocKind::SCRIPT; };
template <> struct MapTypeToFinalizeKind<LazyScript> { static const AllocKind kind = AllocKind::LAZY_SCRIPT; };
template <> struct MapTypeToFinalizeKind<Shape> { static const AllocKind kind = AllocKind::SHAPE; };
template <> struct MapTypeToFinalizeKind<AccessorShape> { static const AllocKind kind = AllocKind::ACCESSOR_SHAPE; };
template <> struct MapTypeToFinalizeKind<BaseShape> { static const AllocKind kind = AllocKind::BASE_SHAPE; };
template <> struct MapTypeToFinalizeKind<ObjectGroup> { static const AllocKind kind = AllocKind::OBJECT_GROUP; };
template <> struct MapTypeToFinalizeKind<JSFatInlineString> { static const AllocKind kind = AllocKind::FAT_INLINE_STRING; };
template <> struct MapTypeToFinalizeKind<JSString> { static const AllocKind kind = AllocKind::STRING; };
template <> struct MapTypeToFinalizeKind<JSExternalString> { static const AllocKind kind = AllocKind::EXTERNAL_STRING; };
template <> struct MapTypeToFinalizeKind<JS::Symbol> { static const AllocKind kind = AllocKind::SYMBOL; };
template <> struct MapTypeToFinalizeKind<jit::JitCode> { static const AllocKind kind = AllocKind::JITCODE; };
#define EXPAND_MAPTYPETOFINALIZEKIND(allocKind, traceKind, type, sizedType) \
template <> struct MapTypeToFinalizeKind<type> { \
static const AllocKind kind = AllocKind::allocKind; \
};
FOR_EACH_NONOBJECT_ALLOCKIND(EXPAND_MAPTYPETOFINALIZEKIND)
#undef EXPAND_MAPTYPETOFINALIZEKIND
template <typename T> struct ParticipatesInCC {};
#define EXPAND_PARTICIPATES_IN_CC(_, type, addToCCKind) \

View File

@ -265,12 +265,15 @@ enum StackKind
StackKindCount
};
using RootedListHeads = mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
JS::Rooted<void*>*>;
// Abstracts JS rooting mechanisms so they can be shared between the JSContext
// and JSRuntime.
class RootLists
{
// Stack GC roots for Rooted GC heap pointers.
mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit, JS::Rooted<void*>*> stackRoots_;
RootedListHeads stackRoots_;
template <typename T> friend class JS::Rooted;
// Stack GC roots for AutoFooRooter classes.

View File

@ -1942,7 +1942,6 @@ class JSScript : public js::gc::TenuredCell
#endif
void finalize(js::FreeOp* fop);
void fixupAfterMovingGC() {}
static const JS::TraceKind TraceKind = JS::TraceKind::Script;
@ -2397,7 +2396,6 @@ class LazyScript : public gc::TenuredCell
friend class GCMarker;
void traceChildren(JSTracer* trc);
void finalize(js::FreeOp* fop);
void fixupAfterMovingGC() {}
static const JS::TraceKind TraceKind = JS::TraceKind::LazyScript;

View File

@ -982,10 +982,16 @@ case "$target" in
_DEFINES_CXXFLAGS='-FI $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT'
CFLAGS="$CFLAGS -W3 -Gy"
CXXFLAGS="$CXXFLAGS -W3 -Gy"
if test "$CPU_ARCH" = "x86"; then
dnl VS2012+ defaults to -arch:SSE2.
CFLAGS="$CFLAGS -arch:IA32"
CXXFLAGS="$CXXFLAGS -arch:IA32"
if test "$CPU_ARCH" = "x86";then
dnl VS2012+ defaults to -arch:SSE2. We want to target nothing
dnl more recent, so set that explicitly here unless another
dnl target arch has already been set.
if test -z `echo $CFLAGS | grep -i [-/]arch:` ; then
CFLAGS="$CFLAGS -arch:SSE2"
fi
if test -z `echo $CXXFLAGS | grep -i [-/]arch:` ; then
CXXFLAGS="$CXXFLAGS -arch:SSE2"
fi
fi
dnl VS2013+ requires -FS when parallel building by make -jN.
dnl If nothing, compiler sometimes causes C1041 error.

View File

@ -0,0 +1,13 @@
// Bug 1227207
var AB = new ArrayBuffer(12); // Length divides 4
var BC = new ArrayBuffer(14); // Length does not divide 4
assertThrowsInstanceOf(() => new Int32Array(AB, -1), RangeError); // 22.2.4.5 #8
assertThrowsInstanceOf(() => new Int32Array(AB, 2), RangeError); // 22.2.4.5 #10
assertThrowsInstanceOf(() => new Int32Array(BC), RangeError); // 22.2.4.5 #13.a
assertThrowsInstanceOf(() => new Int32Array(AB, 16), RangeError); // 22.2.4.5 #13.c
assertThrowsInstanceOf(() => new Int32Array(AB, 0, 4), RangeError); // 22.2.4.5 #14.c
if (typeof reportCompare === "function")
reportCompare(true, true);

View File

@ -82,13 +82,13 @@ function testSharedTypedArray() {
assertThrowsInstanceOf(() => new Int8Array(b, -7), RangeError);
// not congruent mod element size
assertThrowsInstanceOf(() => new Int32Array(b, 3), TypeError); // Bug 1227207: should be RangeError
assertThrowsInstanceOf(() => new Int32Array(b, 3), RangeError);
// start out of range
assertThrowsInstanceOf(() => new Int32Array(b, 4104), TypeError); // Ditto
assertThrowsInstanceOf(() => new Int32Array(b, 4104), RangeError);
// end out of range
assertThrowsInstanceOf(() => new Int32Array(b, 4092, 2), TypeError); // Ditto
assertThrowsInstanceOf(() => new Int32Array(b, 4092, 2), RangeError);
// Views alias the storage
x2[0] = -1;

View File

@ -7715,12 +7715,11 @@ DebuggerObject_checkThis(JSContext* cx, const CallArgs& args, const char* fnname
return nthisobj;
}
#define THIS_DEBUGOBJECT(cx, argc, vp, fnname, args, obj, object) \
CallArgs args = CallArgsFromVp(argc, vp); \
RootedObject obj(cx, DebuggerObject_checkThis(cx, args, fnname)); \
if (!obj) \
return false; \
DebuggerObject& object = obj->as<DebuggerObject>(); \
#define THIS_DEBUGOBJECT(cx, argc, vp, fnname, object) \
CallArgs args = CallArgsFromVp(argc, vp); \
Rooted<DebuggerObject*> object(cx, DebuggerObject_checkThis(cx, args, fnname)); \
if (!object) \
return false; \
#define THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, fnname, args, obj) \
CallArgs args = CallArgsFromVp(argc, vp); \
@ -8505,13 +8504,27 @@ DebuggerObject_preventExtensions(JSContext* cx, unsigned argc, Value* vp)
}
static bool
DebuggerObject_isSealed(JSContext* cx, unsigned argc, Value* vp)
DebuggerObject_isExtensible(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT(cx, argc, vp, "isSealed", args, obj, object);
THIS_DEBUGOBJECT(cx, argc, vp, "isExtensible", object)
bool result;
if (!object.isSealed(cx, &result))
return false;
if (!DebuggerObject::isExtensible(cx, object, result))
return false;
args.rval().setBoolean(result);
return true;
}
static bool
DebuggerObject_isSealed(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT(cx, argc, vp, "isSealed", object)
bool result;
if (!DebuggerObject::isSealed(cx, object, result))
return false;
args.rval().setBoolean(result);
return true;
}
@ -8519,23 +8532,12 @@ DebuggerObject_isSealed(JSContext* cx, unsigned argc, Value* vp)
static bool
DebuggerObject_isFrozen(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT(cx, argc, vp, "isFrozen", args, obj, object);
THIS_DEBUGOBJECT(cx, argc, vp, "isFrozen", object)
bool result;
if (!object.isFrozen(cx, &result))
return false;
args.rval().setBoolean(result);
return true;
}
if (!DebuggerObject::isFrozen(cx, object, result))
return false;
static bool
DebuggerObject_isExtensible(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT(cx, argc, vp, "isExtensible", args, obj, object);
bool result;
if (!object.isExtensible(cx, &result))
return false;
args.rval().setBoolean(result);
return true;
}
@ -8885,10 +8887,10 @@ const JSFunctionSpec DebuggerObject::methods_[] = {
JS_FN("seal", DebuggerObject_seal, 0, 0),
JS_FN("freeze", DebuggerObject_freeze, 0, 0),
JS_FN("preventExtensions", DebuggerObject_preventExtensions, 0, 0),
JS_FN("isSealed", DebuggerObject_isSealed, 0, 0),
JS_FN("forceLexicalInitializationByName", DebuggerObject_forceLexicalInitializationByName, 1, 0),
JS_FN("isFrozen", DebuggerObject_isFrozen, 0, 0),
JS_FN("isExtensible", DebuggerObject_isExtensible, 0, 0),
JS_FN("isSealed", DebuggerObject_isSealed, 0, 0),
JS_FN("isFrozen", DebuggerObject_isFrozen, 0, 0),
JS_FN("apply", DebuggerObject_apply, 0, 0),
JS_FN("call", DebuggerObject_call, 0, 0),
JS_FN("makeDebuggeeValue", DebuggerObject_makeDebuggeeValue, 1, 0),
@ -8933,34 +8935,37 @@ DebuggerObject::create(JSContext* cx, HandleObject proto, HandleObject referent,
return &object;
}
bool
DebuggerObject::isExtensible(JSContext* cx, bool* result) const
/* static */ bool
DebuggerObject::isExtensible(JSContext* cx, Handle<DebuggerObject*> object, bool& result)
{
RootedObject obj(cx, referent());
Maybe<AutoCompartment> ac;
ac.emplace(cx, obj);
ErrorCopier ec(ac);
return IsExtensible(cx, obj, result);
}
bool
DebuggerObject::isSealedHelper(JSContext* cx, SealHelperOp op, const char* name,
bool* result) const
{
RootedObject obj(cx, referent());
RootedObject referent(cx, object->referent());
Maybe<AutoCompartment> ac;
ac.emplace(cx, obj);
ac.emplace(cx, referent);
ErrorCopier ec(ac);
if (op == OpSeal) {
if (!TestIntegrityLevel(cx, obj, IntegrityLevel::Sealed, result))
return false;
} else {
if (!TestIntegrityLevel(cx, obj, IntegrityLevel::Frozen, result))
return false;
}
return true;
return IsExtensible(cx, referent, &result);
}
/* static */ bool
DebuggerObject::isSealed(JSContext* cx, Handle<DebuggerObject*> object, bool& result)
{
RootedObject referent(cx, object->referent());
Maybe<AutoCompartment> ac;
ac.emplace(cx, referent);
ErrorCopier ec(ac);
return TestIntegrityLevel(cx, referent, IntegrityLevel::Sealed, &result);
}
/* static */ bool
DebuggerObject::isFrozen(JSContext* cx, Handle<DebuggerObject*> object, bool& result)
{
RootedObject referent(cx, object->referent());
Maybe<AutoCompartment> ac;
ac.emplace(cx, referent);
ErrorCopier ec(ac);
return TestIntegrityLevel(cx, referent, IntegrityLevel::Frozen, &result);
}

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