mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Merge inbound to m-c. a=merge
This commit is contained in:
commit
4cffb5461e
118
.taskcluster.yml
Normal file
118
.taskcluster.yml
Normal 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}}'
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -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" },
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.");
|
||||
});
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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]
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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")
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ const METHODS = {
|
||||
findNext: {},
|
||||
clearMatch: {},
|
||||
executeScript: { alwaysFails: true }, // needs browser:universalxss
|
||||
getStructuredData: {},
|
||||
getWebManifest: {},
|
||||
mute: {},
|
||||
unmute: {},
|
||||
|
@ -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: {
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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>
|
@ -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>
|
@ -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();
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -470,6 +470,7 @@ static const DOMTokenListSupportedToken sSupportedRelValues[] = {
|
||||
"alternate",
|
||||
"preconnect",
|
||||
"icon",
|
||||
"search",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -230,6 +230,8 @@ public:
|
||||
|
||||
media::TimeIntervals GetBuffered() override;
|
||||
|
||||
int64_t GetEvictionOffset(const media::TimeUnit& aTime) override;
|
||||
|
||||
void BreakCycles() override;
|
||||
|
||||
private:
|
||||
|
@ -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");
|
||||
|
||||
|
@ -32,11 +32,9 @@ interfaces = [
|
||||
'smil',
|
||||
'apps',
|
||||
'gamepad',
|
||||
'push',
|
||||
]
|
||||
|
||||
if not CONFIG['MOZ_SIMPLEPUSH']:
|
||||
interfaces += ['push']
|
||||
|
||||
DIRS += ['interfaces/' + i for i in interfaces]
|
||||
|
||||
DIRS += [
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "base/task.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"]
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -141,6 +141,7 @@ enum class LogReason : int {
|
||||
InvalidCommandList,
|
||||
AsyncTransactionTimeout, // 30
|
||||
TextureCreation,
|
||||
InvalidCacheSurface,
|
||||
// End
|
||||
MustBeLessThanThis = 101,
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "utils/threads.h"
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "base/task.h"
|
||||
|
||||
#include "Hal.h"
|
||||
#include "HalImpl.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/thread.h"
|
||||
#include "base/task.h"
|
||||
|
||||
#include "GonkSensorsInterface.h"
|
||||
#include "GonkSensorsPollInterface.h"
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <sysutils/NetlinkEvent.h>
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "base/task.h"
|
||||
|
||||
#include "Hal.h"
|
||||
#include "HalLog.h"
|
||||
|
@ -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"
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "android/log.h"
|
||||
#include "base/task.h"
|
||||
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
1
js/src/devtools/automation/variants/nonunified
Normal file
1
js/src/devtools/automation/variants/nonunified
Normal file
@ -0,0 +1 @@
|
||||
--enable-debug
|
@ -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>
|
||||
|
116
js/src/gc/Heap.h
116
js/src/gc/Heap.h
@ -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
|
||||
|
@ -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; };
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
6
js/src/jit-test/tests/auto-regress/bug1269074.js
Normal file
6
js/src/jit-test/tests/auto-regress/bug1269074.js
Normal file
@ -0,0 +1,6 @@
|
||||
// |jit-test| allow-oom
|
||||
|
||||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
evalcx('oomTest(function() { Array(...""); })', newGlobal());
|
@ -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/);
|
||||
|
@ -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);
|
||||
|
@ -114,7 +114,6 @@ class JitCode : public gc::TenuredCell
|
||||
|
||||
void traceChildren(JSTracer* trc);
|
||||
void finalize(FreeOp* fop);
|
||||
void fixupAfterMovingGC() {}
|
||||
void setInvalidated() {
|
||||
invalidated_ = true;
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
217
js/src/jsgc.cpp
217
js/src/jsgc.cpp
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
13
js/src/tests/ecma_6/TypedArray/constructor_bad-args.js
Normal file
13
js/src/tests/ecma_6/TypedArray/constructor_bad-args.js
Normal 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);
|
@ -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;
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user