mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 05:48:26 +00:00
Merge m-c to autoland, a=merge
MozReview-Commit-ID: HXFQTGJASw4
This commit is contained in:
commit
9576aa1519
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Touch clobber because of bug 1336456
|
||||
Touch clobber again because of bug 1336456
|
||||
|
@ -1,5 +1,4 @@
|
||||
[DEFAULT]
|
||||
skip-if = (e10s && os == 'win') # Bug 1269369: Document loaded event does not fire in Windows
|
||||
support-files =
|
||||
events.js
|
||||
head.js
|
||||
@ -16,36 +15,62 @@ support-files =
|
||||
|
||||
# Caching tests
|
||||
[browser_caching_attributes.js]
|
||||
skip-if = e10s && os == 'win' # Bug 1288839
|
||||
[browser_caching_description.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_caching_name.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_caching_relations.js]
|
||||
skip-if = e10s && os == 'win' # Bug 1288839
|
||||
[browser_caching_states.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_caching_value.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
|
||||
# Events tests
|
||||
[browser_events_caretmove.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_events_hide.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_events_show.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_events_statechange.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_events_textchange.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
|
||||
# Tree update tests
|
||||
[browser_treeupdate_ariadialog.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_ariaowns.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_canvas.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_cssoverflow.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_doc.js]
|
||||
skip-if = e10s && os == 'win' # Bug 1288839
|
||||
[browser_treeupdate_gencontent.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_hidden.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_imagemap.js]
|
||||
skip-if = e10s # Bug 1318569
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_list.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_list_editabledoc.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_listener.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_optgroup.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_removal.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_table.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_textleaf.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_visibility.js]
|
||||
skip-if = e10s && os == 'win' && os_version == '5.1'
|
||||
[browser_treeupdate_whitespace.js]
|
||||
skip-if = true # Failing due to incorrect index of test container children on document load.
|
||||
|
@ -170,7 +170,22 @@ function* testContainer(browser) {
|
||||
testAccessibleTree(acc, tree);
|
||||
}
|
||||
|
||||
function* waitForImageMap(browser, accDoc) {
|
||||
const id = 'imgmap';
|
||||
const acc = findAccessibleChildByID(accDoc, id);
|
||||
if (acc.firstChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const onReorder = waitForEvent(EVENT_REORDER, id);
|
||||
// Wave over image map
|
||||
yield BrowserTestUtils.synthesizeMouse(`#${id}`, 10, 10,
|
||||
{ type: 'mousemove' }, browser);
|
||||
yield onReorder;
|
||||
}
|
||||
|
||||
addAccessibleTask('doc_treeupdate_imagemap.html', function*(browser, accDoc) {
|
||||
yield waitForImageMap(browser, accDoc);
|
||||
yield testImageMap(browser, accDoc);
|
||||
yield testContainer(browser);
|
||||
});
|
||||
|
@ -6,9 +6,7 @@ support-files =
|
||||
head.js
|
||||
|
||||
[browser_referrer_middle_click.js]
|
||||
skip-if = true # Bug 1315042
|
||||
[browser_referrer_middle_click_in_container.js]
|
||||
skip-if = true # Bug 1315042
|
||||
[browser_referrer_open_link_in_private.js]
|
||||
skip-if = os == 'linux' # Bug 1145199
|
||||
[browser_referrer_open_link_in_tab.js]
|
||||
|
@ -5,9 +5,10 @@ function startMiddleClickTestCase(aTestNumber) {
|
||||
info("browser_referrer_middle_click: " +
|
||||
getReferrerTestDescription(aTestNumber));
|
||||
someTabLoaded(gTestWindow).then(function(aNewTab) {
|
||||
gTestWindow.gBrowser.selectedTab = aNewTab;
|
||||
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
|
||||
startMiddleClickTestCase);
|
||||
BrowserTestUtils.switchTab(gTestWindow.gBrowser, aNewTab).then(() => {
|
||||
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
|
||||
startMiddleClickTestCase);
|
||||
});
|
||||
});
|
||||
|
||||
clickTheLink(gTestWindow, "testlink", {button: 1});
|
||||
|
@ -5,10 +5,11 @@ function startMiddleClickTestCase(aTestNumber) {
|
||||
info("browser_referrer_middle_click: " +
|
||||
getReferrerTestDescription(aTestNumber));
|
||||
someTabLoaded(gTestWindow).then(function(aNewTab) {
|
||||
gTestWindow.gBrowser.selectedTab = aNewTab;
|
||||
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
|
||||
startMiddleClickTestCase,
|
||||
{ userContextId: 3 });
|
||||
BrowserTestUtils.switchTab(gTestWindow.gBrowser, aNewTab).then(() => {
|
||||
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
|
||||
startMiddleClickTestCase,
|
||||
{ userContextId: 3 });
|
||||
});
|
||||
});
|
||||
|
||||
clickTheLink(gTestWindow, "testlink", {button: 1});
|
||||
|
@ -142,6 +142,9 @@ function delayedStartupFinished(aWindow) {
|
||||
function someTabLoaded(aWindow) {
|
||||
return new Promise(function(resolve) {
|
||||
aWindow.gBrowser.addEventListener("load", function onLoad(aEvent) {
|
||||
if (aWindow.location === "about:blank") {
|
||||
return;
|
||||
}
|
||||
let tab = aWindow.gBrowser._getTabForContentWindow(
|
||||
aEvent.target.defaultView.top);
|
||||
if (tab) {
|
||||
|
@ -541,28 +541,32 @@ Cookies.prototype = {
|
||||
},
|
||||
|
||||
_readCookieFile(aFile, aCallback) {
|
||||
let fileReader = new FileReader();
|
||||
let onLoadEnd = () => {
|
||||
fileReader.removeEventListener("loadend", onLoadEnd);
|
||||
File.createFromNsIFile(aFile).then(aFile => {
|
||||
let fileReader = new FileReader();
|
||||
let onLoadEnd = () => {
|
||||
fileReader.removeEventListener("loadend", onLoadEnd);
|
||||
|
||||
if (fileReader.readyState != fileReader.DONE) {
|
||||
Cu.reportError("Could not read cookie contents: " + fileReader.error);
|
||||
aCallback(false);
|
||||
return;
|
||||
}
|
||||
if (fileReader.readyState != fileReader.DONE) {
|
||||
Cu.reportError("Could not read cookie contents: " + fileReader.error);
|
||||
aCallback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let success = true;
|
||||
try {
|
||||
this._parseCookieBuffer(fileReader.result);
|
||||
} catch (ex) {
|
||||
Components.utils.reportError("Unable to migrate cookie: " + ex);
|
||||
success = false;
|
||||
} finally {
|
||||
aCallback(success);
|
||||
}
|
||||
};
|
||||
fileReader.addEventListener("loadend", onLoadEnd);
|
||||
fileReader.readAsText(File.createFromNsIFile(aFile));
|
||||
let success = true;
|
||||
try {
|
||||
this._parseCookieBuffer(fileReader.result);
|
||||
} catch (ex) {
|
||||
Components.utils.reportError("Unable to migrate cookie: " + ex);
|
||||
success = false;
|
||||
} finally {
|
||||
aCallback(success);
|
||||
}
|
||||
};
|
||||
fileReader.addEventListener("loadend", onLoadEnd);
|
||||
fileReader.readAsText(aFile);
|
||||
}, () => {
|
||||
aCallback(false);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1,10 +0,0 @@
|
||||
[
|
||||
{
|
||||
"version": "clang 3.8.0, libgcc 4.8.5",
|
||||
"size": 140319580,
|
||||
"digest": "34e219d7e8eaffa81710631c34d21355563d06335b3c00851e94c1f42f9098788fded8463dd0f67dd699f77b47a0245dd7aff754943a7a03fb5fd145a808254f",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.xz",
|
||||
"unpack": true
|
||||
}
|
||||
]
|
@ -1,19 +1,19 @@
|
||||
[
|
||||
{
|
||||
"version": "clang 3.8.0, libgcc 4.8.5",
|
||||
"size": 140319580,
|
||||
"digest": "34e219d7e8eaffa81710631c34d21355563d06335b3c00851e94c1f42f9098788fded8463dd0f67dd699f77b47a0245dd7aff754943a7a03fb5fd145a808254f",
|
||||
"version": "clang 3.9.0",
|
||||
"size": 168062128,
|
||||
"digest": "2a5458a25792fcade86a56ff0f4acdfa284d2b62966991a7c34a92c2e8c0b4a162ce00512d4467754e7f74598d64c56e91517e1606ed3fba011f7c10e8ad3288",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.xz",
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 3008804,
|
||||
"size": 6075028,
|
||||
"visibility": "public",
|
||||
"digest": "ba6937f14f3d8b26dcb2d39490dee6b0a8afb60f672f5debb71d7b62c1ec52103201b4b1a3d258f945567de531384b36ddb2ce4aa73dc63d72305b11c146847c",
|
||||
"digest": "0b962ba55a5a2fbae44218683bdf6ea0dfe8165aba436173a065f7190976184586b9acf4c23478bc5b6d81a3e00f681bf16df0536c9c9718ad0570d064f69027",
|
||||
"algorithm": "sha512",
|
||||
"unpack": true,
|
||||
"filename": "cctools.tar.gz"
|
||||
"filename": "cctools.tar.xz"
|
||||
},
|
||||
{
|
||||
"size": 35215976,
|
||||
|
@ -15,6 +15,8 @@
|
||||
"cxx": "/home/worker/workspace/build/src/gcc/bin/g++",
|
||||
"as": "/home/worker/workspace/build/src/gcc/bin/gcc",
|
||||
"patches": [
|
||||
"llvm-debug-frame.patch"
|
||||
"llvm-debug-frame.patch",
|
||||
"r277806.patch",
|
||||
"r285657.patch"
|
||||
]
|
||||
}
|
||||
|
@ -22,14 +22,14 @@ CROSS_CCTOOLS_PATH=$topsrcdir/cctools
|
||||
# `browser/config/tooltool-manifests/macosx64/cross-releng.manifest`.
|
||||
CROSS_SYSROOT=$topsrcdir/MacOSX10.7.sdk
|
||||
CROSS_PRIVATE_FRAMEWORKS=$CROSS_SYSROOT/System/Library/PrivateFrameworks
|
||||
FLAGS="-target x86_64-apple-darwin10 -mlinker-version=136 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS_SYSROOT"
|
||||
FLAGS="-target x86_64-apple-darwin11 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS_SYSROOT"
|
||||
|
||||
export CC="$topsrcdir/clang/bin/clang $FLAGS"
|
||||
export CXX="$topsrcdir/clang/bin/clang++ $FLAGS"
|
||||
export CPP="$topsrcdir/clang/bin/clang $FLAGS -E"
|
||||
export LLVMCONFIG=$topsrcdir/clang/bin/llvm-config
|
||||
export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip"
|
||||
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin10-
|
||||
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-
|
||||
export DSYMUTIL=$topsrcdir/clang/bin/llvm-dsymutil
|
||||
export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs
|
||||
export DMG_TOOL=$topsrcdir/dmg/dmg
|
||||
|
@ -28,6 +28,7 @@ const App = createClass({
|
||||
boxModel: PropTypes.shape(Types.boxModel).isRequired,
|
||||
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
|
||||
highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
|
||||
showBoxModelProperties: PropTypes.bool.isRequired,
|
||||
onShowBoxModelEditor: PropTypes.func.isRequired,
|
||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
onShowBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
|
@ -9,6 +9,7 @@ const { addons, createClass, createFactory, DOM: dom, PropTypes } =
|
||||
|
||||
const BoxModelInfo = createFactory(require("./BoxModelInfo"));
|
||||
const BoxModelMain = createFactory(require("./BoxModelMain"));
|
||||
const BoxModelProperties = createFactory(require("./BoxModelProperties"));
|
||||
|
||||
const Types = require("../types");
|
||||
|
||||
@ -18,6 +19,7 @@ module.exports = createClass({
|
||||
|
||||
propTypes: {
|
||||
boxModel: PropTypes.shape(Types.boxModel).isRequired,
|
||||
showBoxModelProperties: PropTypes.bool.isRequired,
|
||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
onShowBoxModelEditor: PropTypes.func.isRequired,
|
||||
onShowBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
@ -28,6 +30,7 @@ module.exports = createClass({
|
||||
render() {
|
||||
let {
|
||||
boxModel,
|
||||
showBoxModelProperties,
|
||||
onHideBoxModelHighlighter,
|
||||
onShowBoxModelEditor,
|
||||
onShowBoxModelHighlighter,
|
||||
@ -45,7 +48,13 @@ module.exports = createClass({
|
||||
}),
|
||||
BoxModelInfo({
|
||||
boxModel,
|
||||
})
|
||||
}),
|
||||
showBoxModelProperties ?
|
||||
BoxModelProperties({
|
||||
boxModel,
|
||||
})
|
||||
:
|
||||
null,
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -0,0 +1,89 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { addons, createClass, createFactory, DOM: dom, PropTypes } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
|
||||
const ComputedProperty = createFactory(require("./ComputedProperty"));
|
||||
|
||||
const Types = require("../types");
|
||||
|
||||
const BOXMODEL_STRINGS_URI = "devtools/client/locales/boxmodel.properties";
|
||||
const BOXMODEL_L10N = new LocalizationHelper(BOXMODEL_STRINGS_URI);
|
||||
|
||||
module.exports = createClass({
|
||||
|
||||
displayName: "BoxModelProperties",
|
||||
|
||||
propTypes: {
|
||||
boxModel: PropTypes.shape(Types.boxModel).isRequired,
|
||||
},
|
||||
|
||||
mixins: [ addons.PureRenderMixin ],
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
isOpen: true,
|
||||
};
|
||||
},
|
||||
|
||||
onToggleExpander() {
|
||||
this.setState({
|
||||
isOpen: !this.state.isOpen,
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
let { boxModel } = this.props;
|
||||
let { layout } = boxModel;
|
||||
|
||||
let layoutInfo = ["box-sizing", "display", "float",
|
||||
"line-height", "position", "z-index"];
|
||||
|
||||
const properties = layoutInfo.map(info => ComputedProperty({
|
||||
name: info,
|
||||
key: info,
|
||||
value: layout[info],
|
||||
}));
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
className: "boxmodel-properties",
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
className: "boxmodel-properties-header",
|
||||
onDoubleClick: this.onToggleExpander,
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
className: "boxmodel-properties-expander theme-twisty",
|
||||
open: this.state.isOpen,
|
||||
onClick: this.onToggleExpander,
|
||||
},
|
||||
),
|
||||
dom.span(
|
||||
{
|
||||
className: "boxmodel-properties-label",
|
||||
title: BOXMODEL_L10N.getStr("boxmodel.propertiesLabel"),
|
||||
},
|
||||
BOXMODEL_L10N.getStr("boxmodel.propertiesLabel"),
|
||||
),
|
||||
),
|
||||
dom.div(
|
||||
{
|
||||
className: "boxmodel-properties-wrapper",
|
||||
hidden: !this.state.isOpen,
|
||||
tabIndex: 0,
|
||||
},
|
||||
properties,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
});
|
@ -0,0 +1,67 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { addons, createClass, DOM: dom, PropTypes } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
module.exports = createClass({
|
||||
|
||||
displayName: "ComputedProperty",
|
||||
|
||||
propTypes: {
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string,
|
||||
},
|
||||
|
||||
mixins: [ addons.PureRenderMixin ],
|
||||
|
||||
onFocus() {
|
||||
this.container.focus();
|
||||
},
|
||||
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
className: "property-view",
|
||||
tabIndex: "0",
|
||||
ref: container => {
|
||||
this.container = container;
|
||||
},
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
className: "property-name-container",
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
className: "property-name theme-fg-color5",
|
||||
tabIndex: "",
|
||||
title: name,
|
||||
onClick: this.onFocus,
|
||||
},
|
||||
name
|
||||
)
|
||||
),
|
||||
dom.div(
|
||||
{
|
||||
className: "property-value-container",
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
className: "property-value theme-fg-color1",
|
||||
dir: "ltr",
|
||||
tabIndex: "",
|
||||
onClick: this.onFocus,
|
||||
},
|
||||
value
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
});
|
@ -12,6 +12,8 @@ DevToolsModules(
|
||||
'BoxModelEditable.js',
|
||||
'BoxModelInfo.js',
|
||||
'BoxModelMain.js',
|
||||
'BoxModelProperties.js',
|
||||
'ComputedProperty.js',
|
||||
'Grid.js',
|
||||
'GridDisplaySettings.js',
|
||||
'GridList.js',
|
||||
|
@ -77,6 +77,12 @@ LayoutView.prototype = {
|
||||
this.loadHighlighterSettings();
|
||||
|
||||
let app = App({
|
||||
/**
|
||||
* Shows the box model properties under the box model if true, otherwise, hidden by
|
||||
* default.
|
||||
*/
|
||||
showBoxModelProperties: true,
|
||||
|
||||
/**
|
||||
* Hides the box-model highlighter on the currently selected element.
|
||||
*/
|
||||
|
@ -35,3 +35,7 @@ boxmodel.content=content
|
||||
# tooltip that appears when hovering over the button that allows users to edit the
|
||||
# position of an element in the page.
|
||||
boxmodel.geometryButton.tooltip=Edit position
|
||||
|
||||
# LOCALIZATION NOTE: (boxmodel.propertiesLabel) This label is displayed as the header
|
||||
# for showing and collapsing the properties underneath the box model in the layout view
|
||||
boxmodel.propertiesLabel=Box Model Properties
|
||||
|
@ -26,20 +26,21 @@ define(function (require, exports, module) {
|
||||
displayName: "Obj",
|
||||
|
||||
propTypes: {
|
||||
object: React.PropTypes.object,
|
||||
object: React.PropTypes.object.isRequired,
|
||||
// @TODO Change this to Object.values once it's supported in Node's version of V8
|
||||
mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])),
|
||||
objectLink: React.PropTypes.func,
|
||||
title: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getTitle: function (object) {
|
||||
let className = object && object.class ? object.class : "Object";
|
||||
let title = this.props.title || object.class || "Object";
|
||||
if (this.props.objectLink) {
|
||||
return this.props.objectLink({
|
||||
object: object
|
||||
}, className);
|
||||
}, title);
|
||||
}
|
||||
return className;
|
||||
return title;
|
||||
},
|
||||
|
||||
safePropIterator: function (object, max) {
|
||||
|
@ -249,3 +249,14 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Box Model Properties: contains a list of relevant box model properties */
|
||||
|
||||
.boxmodel-properties-header {
|
||||
display: flex;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.boxmodel-properties-wrapper {
|
||||
padding: 0 9px;
|
||||
}
|
||||
|
@ -785,7 +785,9 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
||||
"border-left-width",
|
||||
"z-index",
|
||||
"box-sizing",
|
||||
"display"
|
||||
"display",
|
||||
"float",
|
||||
"line-height"
|
||||
]) {
|
||||
layout[prop] = style.getPropertyValue(prop);
|
||||
}
|
||||
|
@ -426,8 +426,6 @@ var testcases = [ {
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "?'.com",
|
||||
fixedURI: "http:///?%27.com",
|
||||
alternateURI: "http://www..com/?%27.com",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
@ -436,14 +434,10 @@ var testcases = [ {
|
||||
protocolChange: true
|
||||
}, {
|
||||
input: "?mozilla",
|
||||
fixedURI: "http:///?mozilla",
|
||||
alternateURI: "http://www..com/?mozilla",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
input: "??mozilla",
|
||||
fixedURI: "http:///??mozilla",
|
||||
alternateURI: "http://www..com/??mozilla",
|
||||
keywordLookup: true,
|
||||
protocolChange: true,
|
||||
}, {
|
||||
|
@ -61,3 +61,14 @@ attribute OfflineResourceList.onprogress
|
||||
attribute OfflineResourceList.onupdateready
|
||||
attribute OfflineResourceList.oncached
|
||||
attribute OfflineResourceList.onobsolete
|
||||
|
||||
// DataTransfer API (gecko-only methods)
|
||||
method DataTransfer.addElement
|
||||
attribute DataTransfer.mozItemCount
|
||||
attribute DataTransfer.mozCursor
|
||||
method DataTransfer.mozTypesAt
|
||||
method DataTransfer.mozClearDataAt
|
||||
method DataTransfer.mozSetDataAt
|
||||
method DataTransfer.mozGetDataAt
|
||||
attribute DataTransfer.mozUserCancelled
|
||||
attribute DataTransfer.mozSourceNode
|
||||
|
@ -718,9 +718,8 @@ nsGlobalWindow::RunIdleRequest(IdleRequest* aRequest,
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
RefPtr<IdleRequest> request(aRequest);
|
||||
nsresult result = request->IdleRun(AsInner(), aDeadline, aDidTimeout);
|
||||
RemoveIdleCallback(request);
|
||||
return result;
|
||||
return request->IdleRun(AsInner(), aDeadline, aDidTimeout);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -655,6 +655,19 @@ nsScriptLoader::CheckContentPolicy(nsIDocument* aDocument,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScriptLoader::ModuleScriptsEnabled()
|
||||
{
|
||||
static bool sEnabledForContent = false;
|
||||
static bool sCachedPref = false;
|
||||
if (!sCachedPref) {
|
||||
sCachedPref = true;
|
||||
Preferences::AddBoolVarCache(&sEnabledForContent, "dom.moduleScripts.enabled", false);
|
||||
}
|
||||
|
||||
return nsContentUtils::IsChromeDoc(mDocument) || sEnabledForContent;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScriptLoader::ModuleMapContainsModule(nsModuleLoadRequest *aRequest) const
|
||||
{
|
||||
@ -1229,15 +1242,27 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest)
|
||||
nsCOMPtr<nsIInterfaceRequestor> prompter(do_QueryInterface(docshell));
|
||||
|
||||
nsSecurityFlags securityFlags;
|
||||
// TODO: the spec currently gives module scripts different CORS behaviour to
|
||||
// classic scripts.
|
||||
securityFlags = aRequest->mCORSMode == CORS_NONE
|
||||
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
|
||||
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
// According to the spec, module scripts have different behaviour to classic
|
||||
// scripts and always use CORS.
|
||||
securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_NONE) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_OMIT;
|
||||
} else if (aRequest->mCORSMode == CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else {
|
||||
MOZ_ASSERT(aRequest->mCORSMode == CORS_USE_CREDENTIALS);
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
} else {
|
||||
securityFlags = aRequest->mCORSMode == CORS_NONE
|
||||
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
|
||||
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
}
|
||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||
|
||||
@ -1449,8 +1474,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
|
||||
nsScriptKind scriptKind = nsScriptKind::Classic;
|
||||
if (!type.IsEmpty()) {
|
||||
// Support type="module" only for chrome documents.
|
||||
if (nsContentUtils::IsChromeDoc(mDocument) && type.LowerCaseEqualsASCII("module")) {
|
||||
if (ModuleScriptsEnabled() && type.LowerCaseEqualsASCII("module")) {
|
||||
scriptKind = nsScriptKind::Module;
|
||||
} else {
|
||||
NS_ENSURE_TRUE(ParseTypeAttribute(type, &version), false);
|
||||
@ -2789,7 +2813,7 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
|
||||
}
|
||||
|
||||
// TODO: Preload module scripts.
|
||||
if (nsContentUtils::IsChromeDoc(mDocument) && aType.LowerCaseEqualsASCII("module")) {
|
||||
if (ModuleScriptsEnabled() && aType.LowerCaseEqualsASCII("module")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -585,6 +585,8 @@ private:
|
||||
JS::SourceBufferHolder GetScriptSource(nsScriptLoadRequest* aRequest,
|
||||
nsAutoString& inlineData);
|
||||
|
||||
bool ModuleScriptsEnabled();
|
||||
|
||||
void SetModuleFetchStarted(nsModuleLoadRequest *aRequest);
|
||||
void SetModuleFetchFinishedAndResumeWaitingRequests(nsModuleLoadRequest *aRequest,
|
||||
nsresult aResult);
|
||||
|
@ -8,10 +8,14 @@ var testFile = Cc["@mozilla.org/file/directory_service;1"]
|
||||
testFile.append("prefs.js");
|
||||
|
||||
addMessageListener("file.open", function () {
|
||||
sendAsyncMessage("file.opened", {
|
||||
file: File.createFromNsIFile(testFile),
|
||||
mtime: testFile.lastModifiedTime,
|
||||
fileWithDate: File.createFromNsIFile(testFile, { lastModified: 123 }),
|
||||
fileDate: 123,
|
||||
File.createFromNsIFile(testFile).then(function(file) {
|
||||
File.createFromNsIFile(testFile, { lastModified: 123 }).then(function(fileWithDate) {
|
||||
sendAsyncMessage("file.opened", {
|
||||
file,
|
||||
mtime: testFile.lastModifiedTime,
|
||||
fileWithDate,
|
||||
fileDate: 123,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,9 @@ addMessageListener("file.create", function (message) {
|
||||
.get("TmpD", Components.interfaces.nsIFile);
|
||||
file.append("foo.txt");
|
||||
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0o600);
|
||||
sendAsyncMessage("file.created", File.createFromNsIFile(file));
|
||||
File.createFromNsIFile(file).then(function(domFile) {
|
||||
sendAsyncMessage("file.created", domFile);
|
||||
});
|
||||
});
|
||||
|
||||
addMessageListener("file.remove", function (message) {
|
||||
|
@ -35,13 +35,22 @@ function createFileWithData(fileData) {
|
||||
|
||||
/** Test for Bug 914381. File's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/
|
||||
var file = createFileWithData("Test bug 914381");
|
||||
var f = File.createFromNsIFile(file);
|
||||
is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js");
|
||||
is(f.mozFullPath, file.path, "mozFullPath returns path if created with nsIFile");
|
||||
File.createFromNsIFile(file).then(f => {
|
||||
is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js");
|
||||
is(f.mozFullPath, file.path, "mozFullPath returns path if created with nsIFile");
|
||||
})
|
||||
.then(() => {
|
||||
return File.createFromFileName(file.path);
|
||||
})
|
||||
.then(f => {
|
||||
is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js");
|
||||
is(f.mozFullPath, "", "mozFullPath returns blank if created with a string");
|
||||
})
|
||||
.then(() => {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
f = File.createFromFileName(file.path);
|
||||
is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js");
|
||||
is(f.mozFullPath, "", "mozFullPath returns blank if created with a string");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -42,30 +42,40 @@ file.append("test");
|
||||
file.append("chrome");
|
||||
file.append("fileconstructor_file.png");
|
||||
|
||||
doTest(File.createFromFileName(file.path));
|
||||
doTest(File.createFromNsIFile(file));
|
||||
function doTest(domfile) {
|
||||
File.createFromFileName(file.path).then(function(domFile) {
|
||||
ok(domfile instanceof File, "File() should return a File");
|
||||
is(domfile.type, "image/png", "File should be a PNG");
|
||||
is(domfile.size, 95, "File has size 95 (and more importantly we can read it)");
|
||||
}
|
||||
|
||||
try {
|
||||
var nonexistentfile = File.createFromFileName("i/sure/hope/this/does/not/exist/anywhere.txt");
|
||||
})
|
||||
.then(() => {
|
||||
return File.createFromNsIFile(file);
|
||||
})
|
||||
.then(function(domFile) {
|
||||
ok(domfile instanceof File, "File() should return a File");
|
||||
is(domfile.type, "image/png", "File should be a PNG");
|
||||
is(domfile.size, 95, "File has size 95 (and more importantly we can read it)");
|
||||
})
|
||||
.then(function() {
|
||||
return File.createFromFileName("i/sure/hope/this/does/not/exist/anywhere.txt");
|
||||
})
|
||||
.then(function() {
|
||||
ok(false, "This should never be reached!");
|
||||
} catch (e) {
|
||||
}, function() {
|
||||
ok(true, "Attempt to construct a non-existent file should fail.");
|
||||
}
|
||||
|
||||
try {
|
||||
}).then(function() {
|
||||
var dir = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties)
|
||||
.get("CurWorkD", Components.interfaces.nsIFile);
|
||||
var dirfile = File.createFromNsIFile(dir);
|
||||
return File.createFromNsIFile(dir);
|
||||
}).then(function() {
|
||||
ok(false, "This should never be reached!");
|
||||
} catch (e) {
|
||||
}, function() {
|
||||
ok(true, "Attempt to construct a file from a directory should fail.");
|
||||
}
|
||||
}).then(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
]]>
|
||||
</script>
|
||||
|
||||
|
@ -13,14 +13,17 @@ function createFileWithData(message) {
|
||||
outStream.write(message, message.length);
|
||||
outStream.close();
|
||||
|
||||
var domFile = File.createFromNsIFile(testFile);
|
||||
return domFile;
|
||||
return File.createFromNsIFile(testFile);
|
||||
}
|
||||
|
||||
addMessageListener("file.open", function (message) {
|
||||
sendAsyncMessage("file.opened", createFileWithData(message));
|
||||
createFileWithData(message).then(function(file) {
|
||||
sendAsyncMessage("file.opened", file);
|
||||
});
|
||||
});
|
||||
|
||||
addMessageListener("file.modify", function (message) {
|
||||
sendAsyncMessage("file.modified", createFileWithData(message));
|
||||
createFileWithData(message).then(function(file) {
|
||||
sendAsyncMessage("file.modified", file);
|
||||
});
|
||||
});
|
||||
|
@ -735,7 +735,7 @@ skip-if = toolkit == 'android'
|
||||
[test_screen_orientation.html]
|
||||
[test_script_loader_crossorigin_data_url.html]
|
||||
[test_selection_with_anon_trees.html]
|
||||
skip-if = toolkit == 'android'
|
||||
skip-if = (toolkit == 'android' || asan) # bug 1330526
|
||||
[test_setInterval_uncatchable_exception.html]
|
||||
skip-if = debug == false
|
||||
[test_settimeout_extra_arguments.html]
|
||||
|
@ -10,8 +10,8 @@ function writeFile(text, answer) {
|
||||
stream.write(text, text.length);
|
||||
stream.close();
|
||||
|
||||
sendAsyncMessage(answer, {
|
||||
file: File.createFromNsIFile(tmpFile)
|
||||
File.createFromNsIFile(tmpFile).then(function(file) {
|
||||
sendAsyncMessage(answer, { file });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,8 @@ addMessageListener("file.open", function () {
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
testFile.append("prefs.js");
|
||||
|
||||
sendAsyncMessage("file.opened", {
|
||||
file: File.createFromNsIFile(testFile)
|
||||
File.createFromNsIFile(testFile).then(function(file) {
|
||||
sendAsyncMessage("file.opened", { file });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -36,7 +36,9 @@
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
#include "mozilla/dom/FileCreatorHelper.h"
|
||||
#include "mozilla/dom/FileSystemUtils.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -581,7 +583,7 @@ File::Constructor(const GlobalObject& aGlobal,
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<File>
|
||||
/* static */ already_AddRefed<Promise>
|
||||
File::CreateFromNsIFile(const GlobalObject& aGlobal,
|
||||
nsIFile* aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
@ -590,45 +592,31 @@ File::CreateFromNsIFile(const GlobalObject& aGlobal,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
|
||||
impl->InitializeChromeFile(window, aData, aBag, true, aGuarantee, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(impl->IsFile());
|
||||
|
||||
if (aBag.mLastModified.WasPassed()) {
|
||||
impl->SetLastModified(aBag.mLastModified.Value());
|
||||
}
|
||||
|
||||
RefPtr<File> domFile = new File(aGlobal.GetAsSupports(), impl);
|
||||
return domFile.forget();
|
||||
RefPtr<Promise> promise =
|
||||
FileCreatorHelper::CreateFile(global, aData, aBag, true, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<File>
|
||||
/* static */ already_AddRefed<Promise>
|
||||
File::CreateFromFileName(const GlobalObject& aGlobal,
|
||||
const nsAString& aData,
|
||||
const nsAString& aPath,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
SystemCallerGuarantee aGuarantee,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
|
||||
impl->InitializeChromeFile(window, aData, aBag, aGuarantee, aRv);
|
||||
if (aRv.Failed()) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
aRv = NS_NewLocalFile(aPath, false, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(impl->IsFile());
|
||||
|
||||
if (aBag.mLastModified.WasPassed()) {
|
||||
impl->SetLastModified(aBag.mLastModified.Value());
|
||||
}
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
RefPtr<File> domFile = new File(aGlobal.GetAsSupports(), impl);
|
||||
return domFile.forget();
|
||||
RefPtr<Promise> promise =
|
||||
FileCreatorHelper::CreateFile(global, file, aBag, false, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,6 +43,7 @@ struct FilePropertyBag;
|
||||
class BlobImpl;
|
||||
class File;
|
||||
class OwningArrayBufferOrArrayBufferViewOrBlobOrUSVString;
|
||||
class Promise;
|
||||
|
||||
class Blob : public nsIDOMBlob
|
||||
, public nsIXHRSendable
|
||||
@ -204,17 +205,17 @@ public:
|
||||
ErrorResult& aRv);
|
||||
|
||||
// ChromeOnly
|
||||
static already_AddRefed<File>
|
||||
static already_AddRefed<Promise>
|
||||
CreateFromFileName(const GlobalObject& aGlobal,
|
||||
const nsAString& aData,
|
||||
const nsAString& aFilePath,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
SystemCallerGuarantee aGuarantee,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// ChromeOnly
|
||||
static already_AddRefed<File>
|
||||
static already_AddRefed<Promise>
|
||||
CreateFromNsIFile(const GlobalObject& aGlobal,
|
||||
nsIFile* aData,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
SystemCallerGuarantee aGuarantee,
|
||||
ErrorResult& aRv);
|
||||
|
187
dom/file/FileCreatorHelper.cpp
Normal file
187
dom/file/FileCreatorHelper.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FileCreatorHelper.h"
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
// Undefine the macro of CreateFile to avoid FileCreatorHelper#CreateFile being
|
||||
// replaced by FileCreatorHelper#CreateFileW.
|
||||
#ifdef CreateFile
|
||||
#undef CreateFile
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* static */ already_AddRefed<Promise>
|
||||
FileCreatorHelper::CreateFile(nsIGlobalObject* aGlobalObject,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(aGlobalObject, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobalObject);
|
||||
|
||||
// Parent process
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
RefPtr<File> file =
|
||||
CreateFileInternal(window, aFile, aBag, aIsFromNsIFile, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
promise->MaybeResolve(file);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// Content process.
|
||||
|
||||
RefPtr<FileCreatorHelper> helper = new FileCreatorHelper(promise, window);
|
||||
|
||||
// The request is sent to the parent process and it's kept alive by
|
||||
// ContentChild.
|
||||
helper->SendRequest(aFile, aBag, aIsFromNsIFile, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<File>
|
||||
FileCreatorHelper::CreateFileInternal(nsPIDOMWindowInner* aWindow,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
bool lastModifiedPassed = false;
|
||||
int64_t lastModified = 0;
|
||||
if (aBag.mLastModified.WasPassed()) {
|
||||
lastModifiedPassed = true;
|
||||
lastModified = aBag.mLastModified.Value();
|
||||
}
|
||||
|
||||
RefPtr<BlobImpl> blobImpl;
|
||||
aRv = CreateBlobImpl(aFile, aBag.mType, aBag.mName, lastModifiedPassed,
|
||||
lastModified, aIsFromNsIFile, getter_AddRefs(blobImpl));
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<File> file = File::Create(aWindow, blobImpl);
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
FileCreatorHelper::FileCreatorHelper(Promise* aPromise,
|
||||
nsPIDOMWindowInner* aWindow)
|
||||
: mPromise(aPromise)
|
||||
, mWindow(aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aPromise);
|
||||
}
|
||||
|
||||
void
|
||||
FileCreatorHelper::SendRequest(nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
if (NS_WARN_IF(!cc)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsID uuid;
|
||||
aRv = nsContentUtils::GenerateUUIDInPlace(uuid);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString path;
|
||||
aRv = aFile->GetPath(path);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
cc->FileCreationRequest(uuid, this, path, aBag.mType, aBag.mName,
|
||||
aBag.mLastModified, aIsFromNsIFile);
|
||||
}
|
||||
|
||||
void
|
||||
FileCreatorHelper::ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv)
|
||||
{
|
||||
if (NS_FAILED(aRv)) {
|
||||
mPromise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<File> file = File::Create(mWindow, aBlobImpl);
|
||||
mPromise->MaybeResolve(file);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
FileCreatorHelper::CreateBlobImplForIPC(const nsAString& aPath,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
bool aLastModifiedPassed,
|
||||
int64_t aLastModified,
|
||||
bool aIsFromNsIFile,
|
||||
BlobImpl** aBlobImpl)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_NewLocalFile(aPath, true, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return CreateBlobImpl(file, aType, aName, aLastModifiedPassed, aLastModified,
|
||||
aIsFromNsIFile, aBlobImpl);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
FileCreatorHelper::CreateBlobImpl(nsIFile* aFile,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
bool aLastModifiedPassed,
|
||||
int64_t aLastModified,
|
||||
bool aIsFromNsIFile,
|
||||
BlobImpl** aBlobImpl)
|
||||
{
|
||||
RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
|
||||
nsresult rv =
|
||||
impl->InitializeChromeFile(aFile, aType, aName, aLastModifiedPassed,
|
||||
aLastModified, aIsFromNsIFile);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(impl->IsFile());
|
||||
|
||||
impl.forget(aBlobImpl);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
88
dom/file/FileCreatorHelper.h
Normal file
88
dom/file/FileCreatorHelper.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_FileCreatorHelper_h
|
||||
#define mozilla_dom_FileCreatorHelper_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
// Undefine the macro of CreateFile to avoid FileCreatorHelper#CreateFile being
|
||||
// replaced by FileCreatorHelper#CreateFileW.
|
||||
#ifdef CreateFile
|
||||
#undef CreateFile
|
||||
#endif
|
||||
|
||||
class nsIFile;
|
||||
class nsIGlobalObject;
|
||||
class nsPIDOMWindowInner;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct ChromeFilePropertyBag;
|
||||
class Promise;
|
||||
class File;
|
||||
|
||||
class FileCreatorHelper final
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(FileCreatorHelper);
|
||||
|
||||
static already_AddRefed<Promise>
|
||||
CreateFile(nsIGlobalObject* aGlobalObject,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv);
|
||||
|
||||
// For IPC only
|
||||
static nsresult
|
||||
CreateBlobImplForIPC(const nsAString& aPath,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
bool aLastModifiedPassed,
|
||||
int64_t aLastModified,
|
||||
bool aIsFromNsIFile,
|
||||
BlobImpl** aBlobImpl);
|
||||
|
||||
private:
|
||||
static already_AddRefed<File>
|
||||
CreateFileInternal(nsPIDOMWindowInner* aWindow,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static nsresult
|
||||
CreateBlobImpl(nsIFile* aFile,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
bool aLastModifiedPassed,
|
||||
int64_t aLastModified,
|
||||
bool aIsFromNsIFile,
|
||||
BlobImpl** aBlobImpl);
|
||||
|
||||
FileCreatorHelper(Promise* aPromise, nsPIDOMWindowInner* aWindow);
|
||||
~FileCreatorHelper() = default;
|
||||
|
||||
void
|
||||
SendRequest(nsIFile* aFile, const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile, ErrorResult& aRv);
|
||||
|
||||
RefPtr<Promise> mPromise;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
};
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_FileCreatorHelper_h
|
@ -323,62 +323,60 @@ MultipartBlobImpl::SetMutable(bool aMutable)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
SystemCallerGuarantee /* unused */,
|
||||
ErrorResult& aRv)
|
||||
nsresult
|
||||
MultipartBlobImpl::InitializeChromeFile(nsIFile* aFile,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
bool aLastModifiedPassed,
|
||||
int64_t aLastModified,
|
||||
bool aIsFromNsIFile)
|
||||
{
|
||||
MOZ_ASSERT(!mImmutable, "Something went wrong ...");
|
||||
if (mImmutable) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mName = aBag.mName;
|
||||
mContentType = aBag.mType;
|
||||
mName = aName;
|
||||
mContentType = aType;
|
||||
mIsFromNsIFile = aIsFromNsIFile;
|
||||
|
||||
bool exists;
|
||||
aRv = aFile->Exists(&exists);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
nsresult rv= aFile->Exists(&exists);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
aRv.Throw(NS_ERROR_FILE_NOT_FOUND);
|
||||
return;
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
bool isDir;
|
||||
aRv = aFile->IsDirectory(&isDir);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
rv = aFile->IsDirectory(&isDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (isDir) {
|
||||
aRv.Throw(NS_ERROR_FILE_IS_DIRECTORY);
|
||||
return;
|
||||
return NS_ERROR_FILE_IS_DIRECTORY;
|
||||
}
|
||||
|
||||
if (mName.IsEmpty()) {
|
||||
aFile->GetLeafName(mName);
|
||||
}
|
||||
|
||||
RefPtr<File> blob = File::CreateFromFile(aWindow, aFile);
|
||||
RefPtr<File> blob = File::CreateFromFile(nullptr, aFile);
|
||||
|
||||
// Pre-cache size.
|
||||
blob->GetSize(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
ErrorResult error;
|
||||
blob->GetSize(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
// Pre-cache modified date.
|
||||
blob->GetLastModified(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
blob->GetLastModified(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
// XXXkhuey this is terrible
|
||||
@ -390,24 +388,16 @@ MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
|
||||
mBlobImpls = blobSet.GetBlobImpls();
|
||||
|
||||
SetLengthAndModifiedDate(aRv);
|
||||
NS_WARNING_ASSERTION(!aRv.Failed(), "SetLengthAndModifiedDate failed");
|
||||
}
|
||||
|
||||
void
|
||||
MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
SystemCallerGuarantee aGuarantee,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file;
|
||||
aRv = NS_NewLocalFile(aData, false, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
SetLengthAndModifiedDate(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
InitializeChromeFile(aWindow, file, aBag, false, aGuarantee, aRv);
|
||||
if (aLastModifiedPassed) {
|
||||
SetLastModified(aLastModified);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -61,18 +61,12 @@ public:
|
||||
bool aNativeEOL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
SystemCallerGuarantee aGuarantee,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
nsIFile* aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
SystemCallerGuarantee /* unused */,
|
||||
ErrorResult& aRv);
|
||||
nsresult InitializeChromeFile(nsIFile* aData,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
bool aLastModifiedPassed,
|
||||
int64_t aLastModified,
|
||||
bool aIsFromNsIFile);
|
||||
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
|
@ -21,6 +21,7 @@ EXPORTS += [
|
||||
EXPORTS.mozilla.dom += [
|
||||
'BlobSet.h',
|
||||
'File.h',
|
||||
'FileCreatorHelper.h',
|
||||
'FileList.h',
|
||||
'FileReader.h',
|
||||
'MultipartBlobImpl.h',
|
||||
@ -31,6 +32,7 @@ EXPORTS.mozilla.dom += [
|
||||
UNIFIED_SOURCES += [
|
||||
'BlobSet.cpp',
|
||||
'File.cpp',
|
||||
'FileCreatorHelper.cpp',
|
||||
'FileList.cpp',
|
||||
'FileReader.cpp',
|
||||
'MultipartBlobImpl.cpp',
|
||||
|
@ -2,9 +2,14 @@ Components.utils.importGlobalProperties(['File']);
|
||||
|
||||
addMessageListener("create-file-objects", function(message) {
|
||||
let files = []
|
||||
let promises = [];
|
||||
for (fileName of message.fileNames) {
|
||||
files.push(File.createFromFileName(fileName));
|
||||
promises.push(File.createFromFileName(fileName).then(function(file) {
|
||||
files.push(file);
|
||||
}));
|
||||
}
|
||||
|
||||
sendAsyncMessage("created-file-objects", files);
|
||||
Promise.all(promises).then(function() {
|
||||
sendAsyncMessage("created-file-objects", files);
|
||||
});
|
||||
});
|
||||
|
@ -17,13 +17,26 @@ function createFileWithData(fileData) {
|
||||
}
|
||||
outStream.write(fileData, fileData.length);
|
||||
outStream.close();
|
||||
var domFile = File.createFromNsIFile(testFile);
|
||||
if (willDelete) {
|
||||
testFile.remove(/* recursive: */ false);
|
||||
}
|
||||
return domFile;
|
||||
return File.createFromNsIFile(testFile).then(domFile => {
|
||||
if (willDelete) {
|
||||
testFile.remove(/* recursive: */ false);
|
||||
}
|
||||
|
||||
return domFile;
|
||||
});
|
||||
}
|
||||
|
||||
addMessageListener("files.open", function (message) {
|
||||
sendAsyncMessage("files.opened", message.map(createFileWithData));
|
||||
let promises = [];
|
||||
let list = [];
|
||||
|
||||
for (let fileData of message) {
|
||||
promises.push(createFileWithData(fileData).then(domFile => {
|
||||
list.push(domFile);
|
||||
}));
|
||||
}
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
sendAsyncMessage("files.opened", list);
|
||||
});
|
||||
});
|
||||
|
@ -35,8 +35,10 @@ addMessageListener("entries.open", function (e) {
|
||||
dir2.append('subsubdir');
|
||||
dir2.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0o700);
|
||||
|
||||
sendAsyncMessage("entries.opened", {
|
||||
data: [ new Directory(tmpDir.path), File.createFromNsIFile(tmpFile) ]
|
||||
File.createFromNsIFile(tmpFile).then(function(file) {
|
||||
sendAsyncMessage("entries.opened", {
|
||||
data: [ new Directory(tmpDir.path), file ]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -123,7 +123,7 @@ addMessageListener("file.open", function (e) {
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
testFile.append("prefs.js");
|
||||
|
||||
sendAsyncMessage("file.opened", {
|
||||
file: File.createFromNsIFile(testFile)
|
||||
File.createFromNsIFile(testFile).then(function(file) {
|
||||
sendAsyncMessage("file.opened", { file });
|
||||
});
|
||||
});
|
||||
|
@ -2,5 +2,15 @@ var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
Cu.importGlobalProperties(["File"]);
|
||||
|
||||
addMessageListener("files.open", function (message) {
|
||||
sendAsyncMessage("files.opened", message.map(path => File.createFromFileName(path)));
|
||||
let list = [];
|
||||
let promises = [];
|
||||
for (let path of message) {
|
||||
promises.push(File.createFromFileName(path).then(file => {
|
||||
list.push(file);
|
||||
}));
|
||||
}
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
sendAsyncMessage("files.opened", list);
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,8 @@ addMessageListener("file.open", function (e) {
|
||||
.QueryInterface(Ci.nsIProperties)
|
||||
.get('ProfD', Ci.nsIFile);
|
||||
tmpFile.append('prefs.js');
|
||||
sendAsyncMessage("file.opened", {
|
||||
data: [ File.createFromNsIFile(tmpFile) ]
|
||||
|
||||
File.createFromNsIFile(tmpFile).then(file => {
|
||||
sendAsyncMessage("file.opened", { data: [ file ] });
|
||||
});
|
||||
});
|
||||
|
@ -11,10 +11,13 @@ addMessageListener("file.open", function (stem) {
|
||||
file.append(stem);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
|
||||
}
|
||||
sendAsyncMessage("file.opened", {
|
||||
fullPath: file.path,
|
||||
leafName: file.leafName,
|
||||
domFile: File.createFromNsIFile(file),
|
||||
|
||||
File.createFromNsIFile(file).then(function(domFile) {
|
||||
sendAsyncMessage("file.opened", {
|
||||
fullPath: file.path,
|
||||
leafName: file.leafName,
|
||||
domFile,
|
||||
});
|
||||
});
|
||||
} catch(e) {
|
||||
sendAsyncMessage("fail", e.toString());
|
||||
|
@ -154,13 +154,14 @@ function checkInputURL()
|
||||
sendString("ttp://mozilla.org");
|
||||
checkValidApplies(element);
|
||||
|
||||
for (var i=0; i<13; ++i) {
|
||||
for (var i=0; i<10; ++i) {
|
||||
synthesizeKey("VK_BACK_SPACE", {});
|
||||
checkValidApplies(element);
|
||||
}
|
||||
|
||||
synthesizeKey("VK_BACK_SPACE", {});
|
||||
for (var i=0; i<4; ++i) {
|
||||
// "http://" is now invalid
|
||||
for (var i=0; i<7; ++i) {
|
||||
checkInvalidApplies(element);
|
||||
synthesizeKey("VK_BACK_SPACE", {});
|
||||
}
|
||||
|
@ -27472,6 +27472,11 @@ IndexGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (cloneInfo->mHasPreprocessInfo) {
|
||||
IDB_WARNING("Preprocessing for indexes not yet implemented!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@ -27848,6 +27853,11 @@ CursorOpBase::PopulateResponseFromStatement(
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (cloneInfo.mHasPreprocessInfo) {
|
||||
IDB_WARNING("Preprocessing for cursors not yet implemented!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (aInitializeResponse) {
|
||||
mResponse = nsTArray<ObjectStoreCursorResponse>();
|
||||
} else {
|
||||
@ -27891,6 +27901,11 @@ CursorOpBase::PopulateResponseFromStatement(
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (cloneInfo.mHasPreprocessInfo) {
|
||||
IDB_WARNING("Preprocessing for cursors not yet implemented!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aInitializeResponse);
|
||||
mResponse = IndexCursorResponse();
|
||||
|
||||
|
@ -112,7 +112,10 @@ support-files =
|
||||
unit/test_transaction_ordering.js
|
||||
unit/test_unique_index_update.js
|
||||
unit/test_view_put_get_values.js
|
||||
unit/test_wasm_cursors.js
|
||||
unit/test_wasm_getAll.js
|
||||
unit/test_wasm_index_getAllObjects.js
|
||||
unit/test_wasm_indexes.js
|
||||
unit/test_wasm_put_get_values.js
|
||||
unit/test_writer_starvation.js
|
||||
|
||||
@ -257,5 +260,8 @@ skip-if = e10s
|
||||
[test_transaction_ordering.html]
|
||||
[test_unique_index_update.html]
|
||||
[test_view_put_get_values.html]
|
||||
[test_wasm_cursors.html]
|
||||
[test_wasm_getAll.html]
|
||||
[test_wasm_index_getAllObjects.html]
|
||||
[test_wasm_indexes.html]
|
||||
[test_wasm_put_get_values.html]
|
||||
|
20
dom/indexedDB/test/test_wasm_cursors.html
Normal file
20
dom/indexedDB/test/test_wasm_cursors.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7" src="unit/test_wasm_cursors.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="file.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
20
dom/indexedDB/test/test_wasm_index_getAllObjects.html
Normal file
20
dom/indexedDB/test/test_wasm_index_getAllObjects.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7" src="unit/test_wasm_index_getAllObjects.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="file.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
20
dom/indexedDB/test/test_wasm_indexes.html
Normal file
20
dom/indexedDB/test/test_wasm_indexes.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7" src="unit/test_wasm_indexes.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="file.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
66
dom/indexedDB/test/unit/test_wasm_cursors.js
Normal file
66
dom/indexedDB/test/unit/test_wasm_cursors.js
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function* testSteps()
|
||||
{
|
||||
const name =
|
||||
this.window ? window.location.pathname : "test_wasm_cursors.js";
|
||||
|
||||
const objectStoreName = "Wasm";
|
||||
|
||||
const wasmData = { key: 1, value: null };
|
||||
|
||||
if (!isWasmSupported()) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
getWasmBinary('(module (func (nop)))');
|
||||
let binary = yield undefined;
|
||||
wasmData.value = getWasmModule(binary);
|
||||
|
||||
info("Opening database");
|
||||
|
||||
let request = indexedDB.open(name);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = continueToNextStepSync;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
// upgradeneeded
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
request.result.createObjectStore(objectStoreName);
|
||||
|
||||
yield undefined;
|
||||
|
||||
// success
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
info("Storing wasm");
|
||||
|
||||
let objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
request = objectStore.add(wasmData.value, wasmData.key);
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
is(request.result, wasmData.key, "Got correct key");
|
||||
|
||||
info("Opening cursor");
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.addEventListener("error", new ExpectError("UnknownError", true));
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
}
|
@ -10,9 +10,13 @@ function* testSteps()
|
||||
const name =
|
||||
this.window ? window.location.pathname : "test_wasm_getAll.js";
|
||||
|
||||
const objectStoreInfo = { name: "Wasm", options: { autoIncrement: true } };
|
||||
const objectStoreName = "Wasm";
|
||||
|
||||
const values = [ 42, [], [] ];
|
||||
const wasmData = [
|
||||
{ key: 1, value: 42 },
|
||||
{ key: 2, value: [null, null, null] },
|
||||
{ key: 3, value: [null, null, null, null, null] }
|
||||
];
|
||||
|
||||
if (!isWasmSupported()) {
|
||||
finishTest();
|
||||
@ -21,35 +25,35 @@ function* testSteps()
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 1)))');
|
||||
let binary = yield undefined;
|
||||
values[1].push(getWasmModule(binary));
|
||||
wasmData[1].value[0] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 2)))');
|
||||
binary = yield undefined;
|
||||
values[1].push(getWasmModule(binary));
|
||||
wasmData[1].value[1] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 3)))');
|
||||
binary = yield undefined;
|
||||
values[1].push(getWasmModule(binary));
|
||||
wasmData[1].value[2] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 4)))');
|
||||
binary = yield undefined;
|
||||
values[2].push(getWasmModule(binary));
|
||||
wasmData[2].value[0] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 5)))');
|
||||
binary = yield undefined;
|
||||
values[2].push(getWasmModule(binary));
|
||||
wasmData[2].value[1] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 6)))');
|
||||
binary = yield undefined;
|
||||
values[2].push(getWasmModule(binary));
|
||||
wasmData[2].value[2] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 7)))');
|
||||
binary = yield undefined;
|
||||
values[2].push(getWasmModule(binary));
|
||||
wasmData[2].value[3] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 8)))');
|
||||
binary = yield undefined;
|
||||
values[2].push(getWasmModule(binary));
|
||||
wasmData[2].value[4] = getWasmModule(binary);
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
@ -63,8 +67,7 @@ function* testSteps()
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
request.result.createObjectStore(objectStoreInfo.name,
|
||||
objectStoreInfo.options);
|
||||
request.result.createObjectStore(objectStoreName);
|
||||
|
||||
yield undefined;
|
||||
|
||||
@ -74,13 +77,13 @@ function* testSteps()
|
||||
|
||||
info("Storing values");
|
||||
|
||||
let objectStore = db.transaction([objectStoreInfo.name], "readwrite")
|
||||
.objectStore(objectStoreInfo.name);
|
||||
let objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
let addedCount = 0;
|
||||
for (let i in values) {
|
||||
request = objectStore.add(values[i]);
|
||||
for (let i in wasmData) {
|
||||
request = objectStore.add(wasmData[i].value, wasmData[i].key);
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedCount == values.length) {
|
||||
if (++addedCount == wasmData.length) {
|
||||
continueToNextStep();
|
||||
}
|
||||
}
|
||||
@ -89,32 +92,42 @@ function* testSteps()
|
||||
|
||||
info("Getting values");
|
||||
|
||||
request = db.transaction(objectStoreInfo.name)
|
||||
.objectStore(objectStoreInfo.name).getAll();
|
||||
request = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName)
|
||||
.getAll();
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
// Can't call yield inside of the verify function.
|
||||
let resultsToProcess = [];
|
||||
info("Verifying values");
|
||||
|
||||
function verifyResult(result, value) {
|
||||
if (value instanceof WebAssembly.Module) {
|
||||
resultsToProcess.push({ result: result, value: value });
|
||||
} else if (value instanceof Array) {
|
||||
is(result instanceof Array, true, "Got an array object");
|
||||
is(result.length, value.length, "Same length");
|
||||
for (let i in value) {
|
||||
verifyResult(result[i], value[i]);
|
||||
// Can't call yield inside of the verify function.
|
||||
let modulesToProcess = [];
|
||||
|
||||
function verifyArray(array1, array2) {
|
||||
is(array1 instanceof Array, true, "Got an array object");
|
||||
is(array1.length, array2.length, "Same length");
|
||||
}
|
||||
|
||||
function verifyData(data1, data2) {
|
||||
if (data2 instanceof Array) {
|
||||
verifyArray(data1, data2);
|
||||
for (let i in data2) {
|
||||
verifyData(data1[i], data2[i]);
|
||||
}
|
||||
} else if (data2 instanceof WebAssembly.Module) {
|
||||
modulesToProcess.push({ module1: data1, module2: data2 });
|
||||
} else {
|
||||
is(result, value, "Same value");
|
||||
is(data1, data2, "Same value");
|
||||
}
|
||||
}
|
||||
|
||||
verifyResult(request.result, values);
|
||||
verifyArray(request.result, wasmData);
|
||||
for (let i in wasmData) {
|
||||
verifyData(request.result[i], wasmData[i].value);
|
||||
}
|
||||
|
||||
for (let resultToProcess of resultsToProcess) {
|
||||
verifyWasmModule(resultToProcess.result, resultToProcess.value);
|
||||
for (let moduleToProcess of modulesToProcess) {
|
||||
verifyWasmModule(moduleToProcess.module1, moduleToProcess.module2);
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
|
110
dom/indexedDB/test/unit/test_wasm_index_getAllObjects.js
Normal file
110
dom/indexedDB/test/unit/test_wasm_index_getAllObjects.js
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function* testSteps()
|
||||
{
|
||||
const name =
|
||||
this.window ? window.location.pathname : "test_wasm_getAll.js";
|
||||
|
||||
const objectStoreName = "Wasm";
|
||||
|
||||
const wasmData = [
|
||||
{ key: 1, value: { name: "foo1", data: 42 } },
|
||||
{ key: 2, value: { name: "foo2", data: [null, null, null] } },
|
||||
{ key: 3, value: { name: "foo3", data: [null, null, null, null, null] } }
|
||||
];
|
||||
|
||||
const indexData = { name: "nameIndex", keyPath: "name", options: { } };
|
||||
|
||||
if (!isWasmSupported()) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 1)))');
|
||||
let binary = yield undefined;
|
||||
wasmData[1].value.data[0] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 2)))');
|
||||
binary = yield undefined;
|
||||
wasmData[1].value.data[1] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 3)))');
|
||||
binary = yield undefined;
|
||||
wasmData[1].value.data[2] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 4)))');
|
||||
binary = yield undefined;
|
||||
wasmData[2].value.data[0] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 5)))');
|
||||
binary = yield undefined;
|
||||
wasmData[2].value.data[1] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 6)))');
|
||||
binary = yield undefined;
|
||||
wasmData[2].value.data[2] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 7)))');
|
||||
binary = yield undefined;
|
||||
wasmData[2].value.data[3] = getWasmModule(binary);
|
||||
|
||||
getWasmBinary('(module (func (result i32) (i32.const 8)))');
|
||||
binary = yield undefined;
|
||||
wasmData[2].value.data[4] = getWasmModule(binary);
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = continueToNextStepSync;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
// upgradeneeded
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
let objectStore = request.result.createObjectStore(objectStoreName);
|
||||
|
||||
info("Creating index");
|
||||
|
||||
objectStore.createIndex(indexData.name, indexData.keyPath, indexData.options);
|
||||
|
||||
yield undefined;
|
||||
|
||||
// success
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
info("Storing values");
|
||||
|
||||
objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
let addedCount = 0;
|
||||
for (let i in wasmData) {
|
||||
request = objectStore.add(wasmData[i].value, wasmData[i].key);
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedCount == wasmData.length) {
|
||||
continueToNextStep();
|
||||
}
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
info("Getting values");
|
||||
|
||||
request = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName)
|
||||
.index("nameIndex")
|
||||
.getAll();
|
||||
request.addEventListener("error", new ExpectError("UnknownError", true));
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
}
|
79
dom/indexedDB/test/unit/test_wasm_indexes.js
Normal file
79
dom/indexedDB/test/unit/test_wasm_indexes.js
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function* testSteps()
|
||||
{
|
||||
const name =
|
||||
this.window ? window.location.pathname : "test_wasm_indexes.js";
|
||||
|
||||
const objectStoreName = "Wasm";
|
||||
|
||||
const wasmData = { key: 1, value: { name: "foo", data: null } };
|
||||
|
||||
const indexData = { name: "nameIndex", keyPath: "name", options: { } };
|
||||
|
||||
if (!isWasmSupported()) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
getWasmBinary('(module (func (nop)))');
|
||||
let binary = yield undefined;
|
||||
wasmData.value.data = getWasmModule(binary);
|
||||
|
||||
info("Opening database");
|
||||
|
||||
let request = indexedDB.open(name);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = continueToNextStepSync;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
// upgradeneeded
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
let objectStore = request.result.createObjectStore(objectStoreName);
|
||||
|
||||
info("Creating index");
|
||||
|
||||
objectStore.createIndex(indexData.name, indexData.keyPath, indexData.options);
|
||||
|
||||
yield undefined;
|
||||
|
||||
// success
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
info("Storing wasm");
|
||||
|
||||
objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
request = objectStore.add(wasmData.value, wasmData.key);
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
is(request.result, wasmData.key, "Got correct key");
|
||||
|
||||
info("Getting wasm");
|
||||
|
||||
request = objectStore.index("nameIndex").get("foo");
|
||||
request.addEventListener("error", new ExpectError("UnknownError", true));
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
info("Opening cursor");
|
||||
|
||||
request = objectStore.index("nameIndex").openCursor();
|
||||
request.addEventListener("error", new ExpectError("UnknownError", true));
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
}
|
@ -12,7 +12,7 @@ function* testSteps()
|
||||
|
||||
const objectStoreName = "Wasm";
|
||||
|
||||
const wasmData = { key: 1, wasm: null };
|
||||
const wasmData = { key: 1, value: null };
|
||||
|
||||
if (!isWasmSupported()) {
|
||||
finishTest();
|
||||
@ -21,8 +21,7 @@ function* testSteps()
|
||||
|
||||
getWasmBinary('(module (func (nop)))');
|
||||
let binary = yield undefined;
|
||||
|
||||
wasmData.wasm = getWasmModule(binary);
|
||||
wasmData.value = getWasmModule(binary);
|
||||
|
||||
info("Opening database");
|
||||
|
||||
@ -50,7 +49,7 @@ function* testSteps()
|
||||
|
||||
let objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
request = objectStore.add(wasmData.wasm, wasmData.key);
|
||||
request = objectStore.add(wasmData.value, wasmData.key);
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
@ -62,7 +61,9 @@ function* testSteps()
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
verifyWasmModule(request.result, wasmData.wasm);
|
||||
info("Verifying wasm");
|
||||
|
||||
verifyWasmModule(request.result, wasmData.value);
|
||||
yield undefined;
|
||||
|
||||
info("Getting wasm in new transaction");
|
||||
@ -72,7 +73,9 @@ function* testSteps()
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
verifyWasmModule(request.result, wasmData.wasm);
|
||||
info("Verifying wasm");
|
||||
|
||||
verifyWasmModule(request.result, wasmData.value);
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
|
@ -48,7 +48,12 @@ function testSteps()
|
||||
|
||||
let fileReader = new FileReader();
|
||||
fileReader.onload = continueToNextStepSync;
|
||||
fileReader.readAsArrayBuffer(File.createFromNsIFile(file));
|
||||
|
||||
let domFile;
|
||||
File.createFromNsIFile(file).then(file => { domFile = file; }).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
fileReader.readAsArrayBuffer(domFile);
|
||||
|
||||
yield undefined;
|
||||
|
||||
@ -82,7 +87,11 @@ function testSteps()
|
||||
|
||||
fileReader = new FileReader();
|
||||
fileReader.onload = continueToNextStepSync;
|
||||
fileReader.readAsArrayBuffer(File.createFromNsIFile(file));
|
||||
|
||||
File.createFromNsIFile(file).then(file => { domFile = file; }).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
fileReader.readAsArrayBuffer(domFile);
|
||||
|
||||
yield undefined;
|
||||
|
||||
@ -108,7 +117,11 @@ function testSteps()
|
||||
|
||||
fileReader = new FileReader();
|
||||
fileReader.onload = continueToNextStepSync;
|
||||
fileReader.readAsArrayBuffer(File.createFromNsIFile(file));
|
||||
|
||||
File.createFromNsIFile(file).then(file => { domFile = file; }).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
fileReader.readAsArrayBuffer(domFile);
|
||||
|
||||
yield undefined;
|
||||
|
||||
|
@ -122,16 +122,20 @@ function expectUncaughtException(expecting)
|
||||
// This is dummy for xpcshell test.
|
||||
}
|
||||
|
||||
function ExpectError(name)
|
||||
function ExpectError(name, preventDefault)
|
||||
{
|
||||
this._name = name;
|
||||
this._preventDefault = preventDefault;
|
||||
}
|
||||
ExpectError.prototype = {
|
||||
handleEvent: function(event)
|
||||
{
|
||||
do_check_eq(event.type, "error");
|
||||
do_check_eq(this._name, event.target.error.name);
|
||||
event.preventDefault();
|
||||
if (this._preventDefault) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
grabEventAndContinueHandler(event);
|
||||
}
|
||||
};
|
||||
@ -646,6 +650,7 @@ var SpecialPowers = {
|
||||
this._createdFiles = new Array;
|
||||
}
|
||||
let createdFiles = this._createdFiles;
|
||||
let promises = [];
|
||||
requests.forEach(function(request) {
|
||||
const filePerms = 0o666;
|
||||
let testFile = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
@ -654,20 +659,24 @@ var SpecialPowers = {
|
||||
} else {
|
||||
testFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, filePerms);
|
||||
}
|
||||
let outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
|
||||
outStream.init(testFile, 0x02 | 0x08 | 0x20, // PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE
|
||||
filePerms, 0);
|
||||
if (request.data) {
|
||||
outStream.write(request.data, request.data.length);
|
||||
outStream.close();
|
||||
}
|
||||
filePaths.push(File.createFromFileName(testFile.path, request.options));
|
||||
createdFiles.push(testFile);
|
||||
let outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
|
||||
outStream.init(testFile, 0x02 | 0x08 | 0x20, // PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE
|
||||
filePerms, 0);
|
||||
if (request.data) {
|
||||
outStream.write(request.data, request.data.length);
|
||||
outStream.close();
|
||||
}
|
||||
promises.push(File.createFromFileName(testFile.path, request.options).then(function(file) {
|
||||
filePaths.push(file);
|
||||
}));
|
||||
createdFiles.push(testFile);
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
callback(filePaths);
|
||||
}, 0);
|
||||
Promise.all(promises).then(function() {
|
||||
setTimeout(function () {
|
||||
callback(filePaths);
|
||||
}, 0);
|
||||
});
|
||||
},
|
||||
|
||||
removeFiles: function() {
|
||||
|
@ -64,8 +64,11 @@ skip-if = true
|
||||
# bug 951017: intermittent failure on Android x86 emulator
|
||||
skip-if = os == "android" && processor == "x86"
|
||||
[test_view_put_get_values.js]
|
||||
[test_wasm_cursors.js]
|
||||
[test_wasm_getAll.js]
|
||||
skip-if = coverage # bug 1336727
|
||||
[test_wasm_index_getAllObjects.js]
|
||||
[test_wasm_indexes.js]
|
||||
[test_wasm_put_get_values.js]
|
||||
skip-if = coverage # bug 1336727
|
||||
[test_wasm_recompile.js]
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "mozilla/dom/DataTransfer.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/ExternalHelperAppChild.h"
|
||||
#include "mozilla/dom/FileCreatorHelper.h"
|
||||
#include "mozilla/dom/FlyWebPublishedServerIPC.h"
|
||||
#include "mozilla/dom/GetFilesHelper.h"
|
||||
#include "mozilla/dom/MemoryReportRequest.h"
|
||||
@ -3175,5 +3176,55 @@ ContentChild::GetConstructedEventTarget(const Message& aMsg)
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ContentChild::FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
|
||||
const nsAString& aFullPath,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
const Optional<int64_t>& aLastModified,
|
||||
bool aIsFromNsIFile)
|
||||
{
|
||||
MOZ_ASSERT(aHelper);
|
||||
|
||||
bool lastModifiedPassed = false;
|
||||
int64_t lastModified = 0;
|
||||
if (aLastModified.WasPassed()) {
|
||||
lastModifiedPassed = true;
|
||||
lastModified = aLastModified.Value();
|
||||
}
|
||||
|
||||
Unused << SendFileCreationRequest(aUUID, nsString(aFullPath), nsString(aType),
|
||||
nsString(aName), lastModifiedPassed,
|
||||
lastModified, aIsFromNsIFile);
|
||||
mFileCreationPending.Put(aUUID, aHelper);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvFileCreationResponse(const nsID& aUUID,
|
||||
const FileCreationResult& aResult)
|
||||
{
|
||||
FileCreatorHelper* helper = mFileCreationPending.GetWeak(aUUID);
|
||||
if (!helper) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
if (aResult.type() == FileCreationResult::TFileCreationErrorResult) {
|
||||
helper->ResponseReceived(nullptr,
|
||||
aResult.get_FileCreationErrorResult().errorCode());
|
||||
} else {
|
||||
MOZ_ASSERT(aResult.type() == FileCreationResult::TFileCreationSuccessResult);
|
||||
|
||||
PBlobChild* blobChild =
|
||||
aResult.get_FileCreationSuccessResult().blobChild();
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
RefPtr<BlobImpl> impl = static_cast<BlobChild*>(blobChild)->GetBlobImpl();
|
||||
helper->ResponseReceived(impl, NS_OK);
|
||||
}
|
||||
|
||||
mFileCreationPending.Remove(aUUID);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -49,6 +49,7 @@ class PStorageChild;
|
||||
class ClonedMessageData;
|
||||
class TabChild;
|
||||
class GetFilesHelperChild;
|
||||
class FileCreatorHelper;
|
||||
|
||||
class ContentChild final : public PContentChild
|
||||
, public nsIWindowProvider
|
||||
@ -569,6 +570,10 @@ public:
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvBlobURLUnregistration(const nsCString& aURI) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvFileCreationResponse(const nsID& aUUID,
|
||||
const FileCreationResult& aResult) override;
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvRequestMemoryReport(
|
||||
const uint32_t& generation,
|
||||
@ -615,6 +620,14 @@ public:
|
||||
const char* const aErrorMsg,
|
||||
base::ProcessId aOtherPid);
|
||||
|
||||
// This method is used by FileCreatorHelper for the creation of a BlobImpl.
|
||||
void
|
||||
FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
|
||||
const nsAString& aFullPath, const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
const Optional<int64_t>& aLastModified,
|
||||
bool aIsFromNsIFile);
|
||||
|
||||
private:
|
||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
void StartForceKillTimer();
|
||||
@ -679,6 +692,10 @@ private:
|
||||
// received.
|
||||
nsRefPtrHashtable<nsIDHashKey, GetFilesHelperChild> mGetFilesPendingRequests;
|
||||
|
||||
// Hashtable to keep track of the pending file creation.
|
||||
// These items are removed when RecvFileCreationResponse is received.
|
||||
nsRefPtrHashtable<nsIDHashKey, FileCreatorHelper> mFileCreationPending;
|
||||
|
||||
bool mShuttingDown;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "mozilla/dom/DataTransfer.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileCreatorHelper.h"
|
||||
#include "mozilla/dom/ExternalHelperAppParent.h"
|
||||
#include "mozilla/dom/GetFilesHelper.h"
|
||||
#include "mozilla/dom/GeolocationBinding.h"
|
||||
@ -4961,3 +4962,37 @@ ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables
|
||||
*aRv = uriClassifier->ClassifyLocalWithTables(uri, aTables, *aResults);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvFileCreationRequest(const nsID& aID,
|
||||
const nsString& aFullPath,
|
||||
const nsString& aType,
|
||||
const nsString& aName,
|
||||
const bool& aLastModifiedPassed,
|
||||
const int64_t& aLastModified,
|
||||
const bool& aIsFromNsIFile)
|
||||
{
|
||||
RefPtr<BlobImpl> blobImpl;
|
||||
nsresult rv =
|
||||
FileCreatorHelper::CreateBlobImplForIPC(aFullPath, aType, aName,
|
||||
aLastModifiedPassed,
|
||||
aLastModified, aIsFromNsIFile,
|
||||
getter_AddRefs(blobImpl));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
BlobParent* blobParent = BlobParent::GetOrCreate(this, blobImpl);
|
||||
if (!SendFileCreationResponse(aID,
|
||||
FileCreationSuccessResult(blobParent, nullptr))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -1088,6 +1088,13 @@ private:
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvDeleteGetFilesRequest(const nsID& aID) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvFileCreationRequest(const nsID& aID, const nsString& aFullPath,
|
||||
const nsString& aType, const nsString& aName,
|
||||
const bool& aLastModifiedPassed,
|
||||
const int64_t& aLastModified,
|
||||
const bool& aIsFromNsIFile) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvAccumulateChildHistogram(
|
||||
InfallibleTArray<Accumulation>&& aAccumulations) override;
|
||||
virtual mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistogram(
|
||||
|
@ -314,6 +314,22 @@ union GetFilesResponseResult
|
||||
GetFilesResponseFailure;
|
||||
};
|
||||
|
||||
struct FileCreationSuccessResult
|
||||
{
|
||||
PBlob blob;
|
||||
};
|
||||
|
||||
struct FileCreationErrorResult
|
||||
{
|
||||
nsresult errorCode;
|
||||
};
|
||||
|
||||
union FileCreationResult
|
||||
{
|
||||
FileCreationSuccessResult;
|
||||
FileCreationErrorResult;
|
||||
};
|
||||
|
||||
struct BlobURLRegistrationData
|
||||
{
|
||||
nsCString url;
|
||||
@ -665,6 +681,8 @@ child:
|
||||
|
||||
async GMPsChanged(GMPCapabilityData[] capabilities);
|
||||
|
||||
async FileCreationResponse(nsID aID, FileCreationResult aResult);
|
||||
|
||||
parent:
|
||||
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
|
||||
|
||||
@ -1141,6 +1159,10 @@ parent:
|
||||
async GetFilesRequest(nsID aID, nsString aDirectory, bool aRecursiveFlag);
|
||||
async DeleteGetFilesRequest(nsID aID);
|
||||
|
||||
async FileCreationRequest(nsID aID, nsString aFullPath, nsString aType,
|
||||
nsString aName, bool lastModifiedPassed,
|
||||
int64_t lastModified, bool aIsFromNsIFile);
|
||||
|
||||
async StoreAndBroadcastBlobURLRegistration(nsCString url, PBlob blob,
|
||||
Principal principal);
|
||||
|
||||
|
@ -193,7 +193,7 @@ public:
|
||||
}
|
||||
for (uint32_t i = 0; i < aEvent.mCurveLength; ++i) {
|
||||
if (!IsValid(aEvent.mCurve[i])) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
aRv.Throw(NS_ERROR_TYPE_ERR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -203,11 +203,11 @@ TEST(AudioEventTimeline, InvalidEvents)
|
||||
timeline.SetValueCurveAtTime(nullptr, 0, 1.0, 1.0, rv);
|
||||
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
|
||||
timeline.SetValueCurveAtTime(badCurve1, ArrayLength(badCurve1), 1.0, 1.0, rv);
|
||||
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
|
||||
is(rv, NS_ERROR_TYPE_ERR, "Correct error code returned");
|
||||
timeline.SetValueCurveAtTime(badCurve2, ArrayLength(badCurve2), 1.0, 1.0, rv);
|
||||
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
|
||||
is(rv, NS_ERROR_TYPE_ERR, "Correct error code returned");
|
||||
timeline.SetValueCurveAtTime(badCurve3, ArrayLength(badCurve3), 1.0, 1.0, rv);
|
||||
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
|
||||
is(rv, NS_ERROR_TYPE_ERR, "Correct error code returned");
|
||||
timeline.SetValueCurveAtTime(curve, ArrayLength(curve), NaN, 1.0, rv);
|
||||
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
|
||||
timeline.SetValueCurveAtTime(curve, ArrayLength(curve), Infinity, 1.0, rv);
|
||||
|
@ -189,6 +189,7 @@ skip-if = (toolkit == 'android') || (os == 'mac' && os_version == '10.6')
|
||||
[test_pannerNodeHRTFSymmetry.html]
|
||||
[test_pannerNodeTail.html]
|
||||
[test_pannerNode_maxDistance.html]
|
||||
[test_setValueCurveWithNonFiniteElements.html]
|
||||
[test_stereoPannerNode.html]
|
||||
[test_stereoPannerNodePassThrough.html]
|
||||
[test_periodicWave.html]
|
||||
|
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<meta charset=utf-8>
|
||||
<head>
|
||||
<title>Bug 1308437 - setValueCurve should throw on non-finite elements</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function testInfiniteElement(audioContext, audioParam) {
|
||||
// create value curve with infinite element
|
||||
var arr = new Float32Array(5);
|
||||
arr[0] = 0.5;
|
||||
arr[1] = 1;
|
||||
arr[2] = Infinity;
|
||||
arr[3] = 1;
|
||||
arr[4] = 0.5;
|
||||
|
||||
try {
|
||||
audioParam.setValueCurveAtTime(arr, audioContext.currentTime(), 2);
|
||||
ok(false, "We shouldn't be able to call setValueCurve with Infinity but we can");
|
||||
} catch(e) {
|
||||
ok(e instanceof TypeError, "TypeError is thrown");
|
||||
}
|
||||
};
|
||||
|
||||
function testNanElement(audioContext, audioParam) {
|
||||
// create value curve with infinite element
|
||||
var arr = new Float32Array(5);
|
||||
arr[0] = 0.5;
|
||||
arr[1] = 1;
|
||||
arr[2] = NaN;
|
||||
arr[3] = 1;
|
||||
arr[4] = 0.5;
|
||||
|
||||
try {
|
||||
audioParam.setValueCurveAtTime(arr, audioContext.currentTime(), 2);
|
||||
ok(false, "We shouldn't be able to call setValueCurve with NaN but we can");
|
||||
} catch(e) {
|
||||
ok(e instanceof TypeError, "TypeError is thrown");
|
||||
}
|
||||
};
|
||||
|
||||
addLoadEvent(function() {
|
||||
var audioContext = new AudioContext();
|
||||
var gainNode = audioContext.createGain();
|
||||
|
||||
testInfiniteElement(audioContext, gainNode.gain);
|
||||
testNanElement(audioContext, gainNode.gain);
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -398,6 +398,18 @@
|
||||
is(url.href, "scheme://tmp\\test");
|
||||
</script>
|
||||
|
||||
<script>
|
||||
/** Test for Bug 1275746 **/
|
||||
SimpleTest.doesThrow(() => { var url = new URL("http:"); }, "http: is not a valid URL");
|
||||
SimpleTest.doesThrow(() => { var url = new URL("http:///"); }, "http: is not a valid URL");
|
||||
|
||||
var url = new URL("file:");
|
||||
is(url.href, "file:///", "Parsing file: should work.");
|
||||
|
||||
url = new URL("file:///");
|
||||
is(url.href, "file:///", "Parsing file:/// should work.");
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var url = new URL("scheme:path/to/file?query#hash");
|
||||
is(url.href, "scheme:path/to/file?query#hash");
|
||||
|
@ -48,12 +48,13 @@ partial interface DataTransfer {
|
||||
* @param element drag source to use
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
[Throws]
|
||||
[Throws, UseCounter]
|
||||
void addElement(Element element);
|
||||
|
||||
/**
|
||||
* The number of items being dragged.
|
||||
*/
|
||||
[UseCounter]
|
||||
readonly attribute unsigned long mozItemCount;
|
||||
|
||||
/**
|
||||
@ -68,6 +69,7 @@ partial interface DataTransfer {
|
||||
* Values other than 'default' are indentical to setting mozCursor to
|
||||
* 'auto'.
|
||||
*/
|
||||
[UseCounter]
|
||||
attribute DOMString mozCursor;
|
||||
|
||||
/**
|
||||
@ -75,7 +77,7 @@ partial interface DataTransfer {
|
||||
* at the specified index. If the index is not in the range from 0 to
|
||||
* itemCount - 1, an empty string list is returned.
|
||||
*/
|
||||
[Throws, NeedsCallerType]
|
||||
[Throws, NeedsCallerType, UseCounter]
|
||||
DOMStringList mozTypesAt(unsigned long index);
|
||||
|
||||
/**
|
||||
@ -92,7 +94,7 @@ partial interface DataTransfer {
|
||||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
[Throws, NeedsSubjectPrincipal, UseCounter]
|
||||
void mozClearDataAt(DOMString format, unsigned long index);
|
||||
|
||||
/*
|
||||
@ -116,7 +118,7 @@ partial interface DataTransfer {
|
||||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater than itemCount
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
[Throws, NeedsSubjectPrincipal, UseCounter]
|
||||
void mozSetDataAt(DOMString format, any data, unsigned long index);
|
||||
|
||||
/**
|
||||
@ -128,7 +130,7 @@ partial interface DataTransfer {
|
||||
* @returns the data of the given format, or null if it doesn't exist.
|
||||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
|
||||
*/
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
[Throws, NeedsSubjectPrincipal, UseCounter]
|
||||
any mozGetDataAt(DOMString format, unsigned long index);
|
||||
|
||||
/**
|
||||
@ -144,11 +146,13 @@ partial interface DataTransfer {
|
||||
* false otherwise, including when the drop has been rejected by its target.
|
||||
* This property is only relevant for the dragend event.
|
||||
*/
|
||||
[UseCounter]
|
||||
readonly attribute boolean mozUserCancelled;
|
||||
|
||||
/**
|
||||
* The node that the mouse was pressed over to begin the drag. For external
|
||||
* drags, or if the caller cannot access this node, this will be null.
|
||||
*/
|
||||
[UseCounter]
|
||||
readonly attribute Node? mozSourceNode;
|
||||
};
|
||||
|
@ -40,10 +40,10 @@ partial interface File {
|
||||
readonly attribute DOMString mozFullPath;
|
||||
|
||||
[ChromeOnly, Throws, NeedsCallerType]
|
||||
static File createFromNsIFile(nsIFile file,
|
||||
optional ChromeFilePropertyBag options);
|
||||
static Promise<File> createFromNsIFile(nsIFile file,
|
||||
optional ChromeFilePropertyBag options);
|
||||
|
||||
[ChromeOnly, Throws, NeedsCallerType]
|
||||
static File createFromFileName(USVString fileName,
|
||||
optional ChromeFilePropertyBag options);
|
||||
static Promise<File> createFromFileName(USVString fileName,
|
||||
optional ChromeFilePropertyBag options);
|
||||
};
|
||||
|
@ -1033,7 +1033,7 @@ Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj)
|
||||
}
|
||||
|
||||
if (existing) {
|
||||
js::Wrapper::Renew(cx, existing, obj, wrapper);
|
||||
js::Wrapper::Renew(existing, obj, wrapper);
|
||||
}
|
||||
return js::Wrapper::New(cx, obj, wrapper);
|
||||
}
|
||||
|
@ -17,13 +17,26 @@ function createFileWithData(fileData) {
|
||||
}
|
||||
outStream.write(fileData, fileData.length);
|
||||
outStream.close();
|
||||
var domFile = File.createFromNsIFile(testFile);
|
||||
if (willDelete) {
|
||||
testFile.remove(/* recursive: */ false);
|
||||
}
|
||||
return domFile;
|
||||
|
||||
return File.createFromNsIFile(testFile).then(function(domFile) {
|
||||
if (willDelete) {
|
||||
testFile.remove(/* recursive: */ false);
|
||||
}
|
||||
return domFile;
|
||||
});
|
||||
}
|
||||
|
||||
addMessageListener("files.open", function (message) {
|
||||
sendAsyncMessage("files.opened", message.map(createFileWithData));
|
||||
let promises = [];
|
||||
let list = [];
|
||||
|
||||
for (let fileData of message) {
|
||||
promises.push(createFileWithData(fileData).then(domFile => {
|
||||
list.push(domFile);
|
||||
}));
|
||||
}
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
sendAsyncMessage("files.opened", list);
|
||||
});
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ addMessageListener("file.open", function (e) {
|
||||
tmpFile.append('file.txt');
|
||||
tmpFile.createUnique(Components.interfaces.nsIFile.FILE_TYPE, 0o600);
|
||||
|
||||
sendAsyncMessage("file.opened", {
|
||||
data: File.createFromNsIFile(tmpFile)
|
||||
File.createFromNsIFile(tmpFile).then(function(file) {
|
||||
sendAsyncMessage("file.opened", { data: file });
|
||||
});
|
||||
});
|
||||
|
@ -16,11 +16,13 @@
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/DOMString.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileCreatorHelper.h"
|
||||
#include "mozilla/dom/FetchUtil.h"
|
||||
#include "mozilla/dom/FormData.h"
|
||||
#include "mozilla/dom/MutableBlobStorage.h"
|
||||
#include "mozilla/dom/XMLDocument.h"
|
||||
#include "mozilla/dom/URLSearchParams.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
@ -89,6 +91,12 @@
|
||||
#include "private/pprio.h"
|
||||
#include "XMLHttpRequestUpload.h"
|
||||
|
||||
// Undefine the macro of CreateFile to avoid FileCreatorHelper#CreateFile being
|
||||
// replaced by FileCreatorHelper#CreateFileW.
|
||||
#ifdef CreateFile
|
||||
#undef CreateFile
|
||||
#endif
|
||||
|
||||
using namespace mozilla::net;
|
||||
|
||||
namespace mozilla {
|
||||
@ -295,7 +303,6 @@ XMLHttpRequestMainThread::ResetResponse()
|
||||
mResponseBody.Truncate();
|
||||
TruncateResponseText();
|
||||
mResponseBlob = nullptr;
|
||||
mDOMBlob = nullptr;
|
||||
mBlobStorage = nullptr;
|
||||
mBlobSet = nullptr;
|
||||
mResultArrayBuffer = nullptr;
|
||||
@ -323,7 +330,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XMLHttpRequestMainThread,
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mXMLParserStreamListener)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResponseBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotificationCallbacks)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannelEventSink)
|
||||
@ -344,7 +350,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XMLHttpRequestMainThread,
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mXMLParserStreamListener)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResponseBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNotificationCallbacks)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChannelEventSink)
|
||||
@ -659,19 +664,6 @@ XMLHttpRequestMainThread::CreateResponseParsedJSON(JSContext* aCx)
|
||||
void
|
||||
XMLHttpRequestMainThread::CreatePartialBlob(ErrorResult& aRv)
|
||||
{
|
||||
if (mDOMBlob) {
|
||||
// Use progress info to determine whether load is complete, but use
|
||||
// mDataAvailable to ensure a slice is created based on the uncompressed
|
||||
// data count.
|
||||
if (mState == State::done) {
|
||||
mResponseBlob = mDOMBlob;
|
||||
} else {
|
||||
mResponseBlob = mDOMBlob->CreateSlice(0, mDataAvailable,
|
||||
EmptyString(), aRv);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// mBlobSet can be null if the request has been canceled
|
||||
if (!mBlobSet) {
|
||||
return;
|
||||
@ -1449,7 +1441,7 @@ XMLHttpRequestMainThread::IsSystemXHR() const
|
||||
{
|
||||
return mIsSystem || nsContentUtils::IsSystemPrincipal(mPrincipal);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
XMLHttpRequestMainThread::InUploadPhase() const
|
||||
{
|
||||
@ -1652,17 +1644,13 @@ XMLHttpRequestMainThread::StreamReaderFunc(nsIInputStream* in,
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (xmlHttpRequest->mResponseType == XMLHttpRequestResponseType::Blob) {
|
||||
if (!xmlHttpRequest->mDOMBlob) {
|
||||
xmlHttpRequest->MaybeCreateBlobStorage();
|
||||
rv = xmlHttpRequest->mBlobStorage->Append(fromRawSegment, count);
|
||||
}
|
||||
xmlHttpRequest->MaybeCreateBlobStorage();
|
||||
rv = xmlHttpRequest->mBlobStorage->Append(fromRawSegment, count);
|
||||
} else if (xmlHttpRequest->mResponseType == XMLHttpRequestResponseType::Moz_blob) {
|
||||
if (!xmlHttpRequest->mDOMBlob) {
|
||||
if (!xmlHttpRequest->mBlobSet) {
|
||||
xmlHttpRequest->mBlobSet = new BlobSet();
|
||||
}
|
||||
rv = xmlHttpRequest->mBlobSet->AppendVoidPtr(fromRawSegment, count);
|
||||
if (!xmlHttpRequest->mBlobSet) {
|
||||
xmlHttpRequest->mBlobSet = new BlobSet();
|
||||
}
|
||||
rv = xmlHttpRequest->mBlobSet->AppendVoidPtr(fromRawSegment, count);
|
||||
// Clear the cache so that the blob size is updated.
|
||||
xmlHttpRequest->mResponseBlob = nullptr;
|
||||
} else if ((xmlHttpRequest->mResponseType == XMLHttpRequestResponseType::Arraybuffer &&
|
||||
@ -1723,27 +1711,107 @@ XMLHttpRequestMainThread::StreamReaderFunc(nsIInputStream* in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool XMLHttpRequestMainThread::CreateDOMBlob(nsIRequest *request)
|
||||
namespace {
|
||||
|
||||
nsresult
|
||||
GetLocalFileFromChannel(nsIRequest* aRequest, nsIFile** aFile)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(request);
|
||||
if (fc) {
|
||||
fc->GetFile(getter_AddRefs(file));
|
||||
MOZ_ASSERT(aRequest);
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
*aFile = nullptr;
|
||||
|
||||
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aRequest);
|
||||
if (!fc) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!file)
|
||||
return false;
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = fc->GetFile(getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoCString contentType;
|
||||
mChannel->GetContentType(contentType);
|
||||
file.forget(aFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mDOMBlob = File::CreateFromFile(GetOwner(), file, EmptyString(),
|
||||
NS_ConvertASCIItoUTF16(contentType));
|
||||
nsresult
|
||||
DummyStreamReaderFunc(nsIInputStream* aInputStream,
|
||||
void* aClosure,
|
||||
const char* aFromRawSegment,
|
||||
uint32_t aToOffset,
|
||||
uint32_t aCount,
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
*aWriteCount = aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class FileCreationHandler final : public PromiseNativeHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static void
|
||||
Create(Promise* aPromise, XMLHttpRequestMainThread* aXHR)
|
||||
{
|
||||
MOZ_ASSERT(aPromise);
|
||||
|
||||
RefPtr<FileCreationHandler> handler = new FileCreationHandler(aXHR);
|
||||
aPromise->AppendNativeHandler(handler);
|
||||
}
|
||||
|
||||
void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
|
||||
{
|
||||
if (NS_WARN_IF(!aValue.isObject())) {
|
||||
mXHR->LocalFileToBlobCompleted(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Blob> blob;
|
||||
if (NS_WARN_IF(NS_FAILED(UNWRAP_OBJECT(Blob, &aValue.toObject(), blob)))) {
|
||||
mXHR->LocalFileToBlobCompleted(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
mXHR->LocalFileToBlobCompleted(blob);
|
||||
}
|
||||
|
||||
void
|
||||
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
|
||||
{
|
||||
mXHR->LocalFileToBlobCompleted(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit FileCreationHandler(XMLHttpRequestMainThread* aXHR)
|
||||
: mXHR(aXHR)
|
||||
{
|
||||
MOZ_ASSERT(aXHR);
|
||||
}
|
||||
|
||||
~FileCreationHandler() = default;
|
||||
|
||||
RefPtr<XMLHttpRequestMainThread> mXHR;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS0(FileCreationHandler)
|
||||
|
||||
} // namespace
|
||||
|
||||
void
|
||||
XMLHttpRequestMainThread::LocalFileToBlobCompleted(Blob* aBlob)
|
||||
{
|
||||
MOZ_ASSERT(mState != State::done);
|
||||
|
||||
mResponseBlob = aBlob;
|
||||
mBlobStorage = nullptr;
|
||||
mBlobSet = nullptr;
|
||||
NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
|
||||
return true;
|
||||
|
||||
ChangeStateToDone();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1760,31 +1828,45 @@ XMLHttpRequestMainThread::OnDataAvailable(nsIRequest *request,
|
||||
mProgressSinceLastProgressEvent = true;
|
||||
XMLHttpRequestBinding::ClearCachedResponseTextValue(this);
|
||||
|
||||
bool cancelable = false;
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
if ((mResponseType == XMLHttpRequestResponseType::Blob ||
|
||||
mResponseType == XMLHttpRequestResponseType::Moz_blob) && !mDOMBlob) {
|
||||
cancelable = CreateDOMBlob(request);
|
||||
// The nsIStreamListener contract mandates us
|
||||
// to read from the stream before returning.
|
||||
mResponseType == XMLHttpRequestResponseType::Moz_blob)) {
|
||||
rv = GetLocalFileFromChannel(request, getter_AddRefs(localFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (localFile) {
|
||||
mBlobStorage = nullptr;
|
||||
mBlobSet = nullptr;
|
||||
NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
|
||||
|
||||
// We don't have to read from the local file for the blob response
|
||||
int64_t fileSize;
|
||||
rv = localFile->GetFileSize(&fileSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mDataAvailable = fileSize;
|
||||
|
||||
// The nsIStreamListener contract mandates us to read from the stream
|
||||
// before returning.
|
||||
uint32_t totalRead;
|
||||
rv =
|
||||
inStr->ReadSegments(DummyStreamReaderFunc, nullptr, count, &totalRead);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ChangeState(State::loading);
|
||||
return request->Cancel(NS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t totalRead;
|
||||
nsresult rv = inStr->ReadSegments(XMLHttpRequestMainThread::StreamReaderFunc,
|
||||
(void*)this, count, &totalRead);
|
||||
rv = inStr->ReadSegments(XMLHttpRequestMainThread::StreamReaderFunc,
|
||||
(void*)this, count, &totalRead);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (cancelable) {
|
||||
// We don't have to read from the local file for the blob response
|
||||
ErrorResult error;
|
||||
mDataAvailable = mDOMBlob->GetSize(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
ChangeState(State::loading);
|
||||
return request->Cancel(NS_OK);
|
||||
}
|
||||
|
||||
mDataAvailable += totalRead;
|
||||
|
||||
// Fire the first progress event/loading state change
|
||||
@ -2106,14 +2188,36 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
if (NS_SUCCEEDED(status) &&
|
||||
(mResponseType == XMLHttpRequestResponseType::Blob ||
|
||||
mResponseType == XMLHttpRequestResponseType::Moz_blob)) {
|
||||
ErrorResult rv;
|
||||
if (!mDOMBlob) {
|
||||
CreateDOMBlob(request);
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = GetLocalFileFromChannel(request, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (mDOMBlob) {
|
||||
mResponseBlob = mDOMBlob;
|
||||
mDOMBlob = nullptr;
|
||||
|
||||
if (file) {
|
||||
nsAutoCString contentType;
|
||||
rv = mChannel->GetContentType(contentType);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
ChromeFilePropertyBag bag;
|
||||
bag.mType = NS_ConvertUTF8toUTF16(contentType);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal();
|
||||
|
||||
ErrorResult error;
|
||||
RefPtr<Promise> promise =
|
||||
FileCreatorHelper::CreateFile(global, file, bag, true, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
FileCreationHandler::Create(promise, this);
|
||||
waitingForBlobCreation = true;
|
||||
} else {
|
||||
// No local file.
|
||||
|
||||
// Smaller files may be written in cache map instead of separate files.
|
||||
// Also, no-store response cannot be written in persistent cache.
|
||||
nsAutoCString contentType;
|
||||
@ -2132,15 +2236,16 @@ XMLHttpRequestMainThread::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
mBlobSet = new BlobSet();
|
||||
}
|
||||
|
||||
ErrorResult error;
|
||||
nsTArray<RefPtr<BlobImpl>> subImpls(mBlobSet->GetBlobImpls());
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
MultipartBlobImpl::Create(Move(subImpls),
|
||||
NS_ConvertASCIItoUTF16(contentType),
|
||||
rv);
|
||||
error);
|
||||
mBlobSet = nullptr;
|
||||
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
mResponseBlob = Blob::Create(GetOwner(), blobImpl);
|
||||
|
@ -530,6 +530,9 @@ public:
|
||||
Blob* aBlob,
|
||||
nsresult aResult) override;
|
||||
|
||||
void
|
||||
LocalFileToBlobCompleted(Blob* aBlob);
|
||||
|
||||
protected:
|
||||
// XHR states are meant to mirror the XHR2 spec:
|
||||
// https://xhr.spec.whatwg.org/#states
|
||||
@ -551,7 +554,6 @@ protected:
|
||||
uint32_t *writeCount);
|
||||
nsresult CreateResponseParsedJSON(JSContext* aCx);
|
||||
void CreatePartialBlob(ErrorResult& aRv);
|
||||
bool CreateDOMBlob(nsIRequest *request);
|
||||
// Change the state of the object with this. The broadcast argument
|
||||
// determines if the onreadystatechange listener should be called.
|
||||
nsresult ChangeState(State aState, bool aBroadcast = true);
|
||||
@ -639,14 +641,9 @@ protected:
|
||||
// It is either a cached blob-response from the last call to GetResponse,
|
||||
// but is also explicitly set in OnStopRequest.
|
||||
RefPtr<Blob> mResponseBlob;
|
||||
// Non-null only when we are able to get a os-file representation of the
|
||||
// response, i.e. when loading from a file.
|
||||
RefPtr<Blob> mDOMBlob;
|
||||
// We stream data to mBlobStorage when response type is "blob" and mDOMBlob is
|
||||
// null.
|
||||
// We stream data to mBlobStorage when response type is "blob".
|
||||
RefPtr<MutableBlobStorage> mBlobStorage;
|
||||
// We stream data to mBlobStorage when response type is "moz-blob" and
|
||||
// mDOMBlob is null.
|
||||
// We stream data to mBlobSet when response type is "moz-blob".
|
||||
nsAutoPtr<BlobSet> mBlobSet;
|
||||
|
||||
nsString mOverrideMimeType;
|
||||
|
@ -39,6 +39,8 @@ LOCAL_INCLUDES += [
|
||||
|
||||
MOCHITEST_MANIFESTS += [ 'tests/mochitest.ini' ]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [ 'tests/browser.ini' ]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
4
dom/xhr/tests/browser.ini
Normal file
4
dom/xhr/tests/browser.ini
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
|
||||
[browser_blobFromFile.js]
|
41
dom/xhr/tests/browser_blobFromFile.js
Normal file
41
dom/xhr/tests/browser_blobFromFile.js
Normal file
@ -0,0 +1,41 @@
|
||||
let { classes: Cc, interfaces: Ci } = Components;
|
||||
|
||||
add_task(function* test() {
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIDirectoryService)
|
||||
.QueryInterface(Ci.nsIProperties)
|
||||
.get("ProfD", Ci.nsIFile);
|
||||
|
||||
let fileHandler = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService)
|
||||
.getProtocolHandler("file")
|
||||
.QueryInterface(Ci.nsIFileProtocolHandler);
|
||||
|
||||
let fileURL = fileHandler.getURLSpecFromFile(file);
|
||||
|
||||
info("Opening url: " + fileURL);
|
||||
let tab = gBrowser.addTab(fileURL);
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
let blob = yield ContentTask.spawn(browser, null, function() {
|
||||
return new content.window.Promise(resolve => {
|
||||
let xhr = new content.window.XMLHttpRequest();
|
||||
xhr.responseType = "blob";
|
||||
xhr.open("GET", "prefs.js");
|
||||
xhr.send();
|
||||
xhr.onload = function() {
|
||||
resolve(xhr.response);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ok(blob instanceof File, "We have a file");
|
||||
|
||||
file.append("prefs.js");
|
||||
is(blob.size, file.fileSize, "The size matches");
|
||||
is(blob.name, "prefs.js", "The name is correct");
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
@ -79,23 +79,10 @@ function run_test() {
|
||||
|
||||
cm.removeAll();
|
||||
|
||||
// test that setting an empty or '.' http:// host results in a no-op
|
||||
var uri = NetUtil.newURI("http://baz.com/");
|
||||
var emptyuri = NetUtil.newURI("http:///");
|
||||
var doturi = NetUtil.newURI("http://./");
|
||||
do_check_eq(uri.asciiHost, "baz.com");
|
||||
do_check_eq(emptyuri.asciiHost, "");
|
||||
do_check_eq(doturi.asciiHost, ".");
|
||||
cs.setCookieString(emptyuri, null, "foo2=bar", null);
|
||||
do_check_eq(getCookieCount(), 0);
|
||||
cs.setCookieString(doturi, null, "foo3=bar", null);
|
||||
do_check_eq(getCookieCount(), 0);
|
||||
cs.setCookieString(uri, null, "foo=bar", null);
|
||||
do_check_eq(getCookieCount(), 1);
|
||||
|
||||
do_check_eq(cs.getCookieString(uri, null), "foo=bar");
|
||||
do_check_eq(cs.getCookieString(emptyuri, null), null);
|
||||
do_check_eq(cs.getCookieString(doturi, null), null);
|
||||
|
||||
do_check_eq(cm.countCookiesFromHost(""), 0);
|
||||
do_check_throws(function() {
|
||||
|
@ -213,8 +213,14 @@ ShadowLayerForwarder::~ShadowLayerForwarder()
|
||||
delete mTxn;
|
||||
if (mShadowManager) {
|
||||
mShadowManager->SetForwarder(nullptr);
|
||||
mShadowManager->Destroy();
|
||||
if (NS_IsMainThread()) {
|
||||
mShadowManager->Destroy();
|
||||
} else {
|
||||
NS_DispatchToMainThread(
|
||||
NewRunnableMethod(mShadowManager, &LayerTransactionChild::Destroy));
|
||||
}
|
||||
}
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_DispatchToMainThread(
|
||||
new ReleaseOnMainThreadTask<ActiveResourceTracker>(mActiveResourceTracker));
|
||||
|
@ -779,6 +779,10 @@ imgFrame::GetSourceSurfaceInternal()
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
if (!mRawSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CreateLockedSurface(mRawSurface, mFrameRect.Size(), mFormat);
|
||||
}
|
||||
|
||||
|
@ -140,12 +140,12 @@ ExecuteRegExpImpl(JSContext* cx, RegExpStatics* res, RegExpShared& re, HandleLin
|
||||
|
||||
/* Legacy ExecuteRegExp behavior is baked into the JSAPI. */
|
||||
bool
|
||||
js::ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, RegExpObject& reobj,
|
||||
js::ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, Handle<RegExpObject*> reobj,
|
||||
HandleLinearString input, size_t* lastIndex, bool test,
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
RegExpGuard shared(cx);
|
||||
if (!reobj.getShared(cx, &shared))
|
||||
if (!RegExpObject::getShared(cx, reobj, &shared))
|
||||
return false;
|
||||
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
@ -918,7 +918,7 @@ ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string,
|
||||
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
||||
|
||||
RegExpGuard re(cx);
|
||||
if (!reobj->getShared(cx, &re))
|
||||
if (!RegExpObject::getShared(cx, reobj, &re))
|
||||
return RegExpRunStatus_Error;
|
||||
|
||||
RegExpStatics* res;
|
||||
|
@ -31,7 +31,7 @@ enum RegExpStaticsUpdate { UpdateRegExpStatics, DontUpdateRegExpStatics };
|
||||
* |chars| and |length|.
|
||||
*/
|
||||
MOZ_MUST_USE bool
|
||||
ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, RegExpObject& reobj,
|
||||
ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, Handle<RegExpObject*> reobj,
|
||||
HandleLinearString input, size_t* lastIndex, bool test,
|
||||
MutableHandleValue rval);
|
||||
|
||||
|
@ -978,7 +978,7 @@ AbortGC(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
cx->runtime()->gc.abortGC();
|
||||
JS::AbortIncrementalGC(cx);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
@ -1482,7 +1482,7 @@ OOMTest(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
#ifdef JS_TRACE_LOGGING
|
||||
// Reset the TraceLogger state if enabled.
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
if (logger->enabled()) {
|
||||
while (logger->enabled())
|
||||
logger->disable();
|
||||
@ -2571,7 +2571,7 @@ static bool
|
||||
EnableTraceLogger(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
if (!TraceLoggerEnable(logger, cx))
|
||||
return false;
|
||||
|
||||
@ -2583,7 +2583,7 @@ static bool
|
||||
DisableTraceLogger(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
args.rval().setBoolean(TraceLoggerDisable(logger));
|
||||
|
||||
return true;
|
||||
@ -4166,7 +4166,7 @@ DisRegExp(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!reobj->dumpBytecode(cx, match_only, input))
|
||||
if (!RegExpObject::dumpBytecode(cx, reobj, match_only, input))
|
||||
return false;
|
||||
|
||||
args.rval().setUndefined();
|
||||
|
@ -111,9 +111,8 @@ class MOZ_STACK_CLASS BytecodeCompiler
|
||||
|
||||
AutoCompilationTraceLogger::AutoCompilationTraceLogger(JSContext* cx,
|
||||
const TraceLoggerTextId id, const ReadOnlyCompileOptions& options)
|
||||
: logger(!cx->helperThread() ? TraceLoggerForMainThread(cx->runtime())
|
||||
: TraceLoggerForCurrentThread()),
|
||||
event(logger, TraceLogger_AnnotateScripts, options),
|
||||
: logger(TraceLoggerForCurrentThread(cx)),
|
||||
event(TraceLogger_AnnotateScripts, options),
|
||||
scriptLogger(logger, event),
|
||||
typeLogger(logger, id)
|
||||
{}
|
||||
|
@ -849,6 +849,12 @@ class GCRuntime
|
||||
Finished
|
||||
};
|
||||
|
||||
enum IncrementalResult
|
||||
{
|
||||
Reset = 0,
|
||||
Ok
|
||||
};
|
||||
|
||||
// For ArenaLists::allocateFromArena()
|
||||
friend class ArenaLists;
|
||||
Chunk* pickChunk(const AutoLockGC& lock,
|
||||
@ -883,9 +889,9 @@ class GCRuntime
|
||||
|
||||
void requestMajorGC(JS::gcreason::Reason reason);
|
||||
SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis);
|
||||
void budgetIncrementalGC(JS::gcreason::Reason reason, SliceBudget& budget,
|
||||
AutoLockForExclusiveAccess& lock);
|
||||
void resetIncrementalGC(AbortReason reason, AutoLockForExclusiveAccess& lock);
|
||||
IncrementalResult budgetIncrementalGC(bool nonincrementalByAPI, JS::gcreason::Reason reason,
|
||||
SliceBudget& budget, AutoLockForExclusiveAccess& lock);
|
||||
IncrementalResult resetIncrementalGC(AbortReason reason, AutoLockForExclusiveAccess& lock);
|
||||
|
||||
// Assert if the system state is such that we should never
|
||||
// receive a request to do GC work.
|
||||
@ -897,8 +903,8 @@ class GCRuntime
|
||||
|
||||
gcstats::ZoneGCStats scanZonesBeforeGC();
|
||||
void collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::Reason reason) JS_HAZ_GC_CALL;
|
||||
MOZ_MUST_USE bool gcCycle(bool nonincrementalByAPI, SliceBudget& budget,
|
||||
JS::gcreason::Reason reason);
|
||||
MOZ_MUST_USE IncrementalResult gcCycle(bool nonincrementalByAPI, SliceBudget& budget,
|
||||
JS::gcreason::Reason reason);
|
||||
bool shouldRepeatForDeadZone(JS::gcreason::Reason reason);
|
||||
void incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason,
|
||||
AutoLockForExclusiveAccess& lock);
|
||||
|
@ -268,7 +268,7 @@ Zone::discardJitCode(FreeOp* fop, bool discardBaselineCode)
|
||||
* Defer freeing any allocated blocks until after the next minor GC.
|
||||
*/
|
||||
if (discardBaselineCode) {
|
||||
jitZone()->optimizedStubSpace()->freeAllAfterMinorGC(fop->runtime());
|
||||
jitZone()->optimizedStubSpace()->freeAllAfterMinorGC(this);
|
||||
jitZone()->purgeIonCacheIRStubInfo();
|
||||
}
|
||||
|
||||
|
@ -834,10 +834,6 @@ struct GCManagedDeletePolicy
|
||||
|
||||
namespace JS {
|
||||
|
||||
template <typename T>
|
||||
struct DeletePolicy<js::GCPtr<T>> : public js::GCManagedDeletePolicy<js::GCPtr<T>>
|
||||
{};
|
||||
|
||||
// Scope data that contain GCPtrs must use the correct DeletePolicy.
|
||||
//
|
||||
// This is defined here because vm/Scope.h cannot #include "vm/Runtime.h"
|
||||
|
@ -157,8 +157,10 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
|
||||
// avoid failing repeatedly when the regex code is called from Ion JIT code,
|
||||
// see bug 1208819.
|
||||
Label stack_ok;
|
||||
void* stack_limit = &cx->runtime()->contextFromMainThread()->jitStackLimitNoInterrupt;
|
||||
masm.branchStackPtrRhs(Assembler::Below, AbsoluteAddress(stack_limit), &stack_ok);
|
||||
void* context_addr = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), temp0);
|
||||
Address limit_addr(temp0, offsetof(JSContext, jitStackLimitNoInterrupt));
|
||||
masm.branchStackPtrRhs(Assembler::Below, limit_addr, &stack_ok);
|
||||
|
||||
// Exit with an exception. There is not enough space on the stack
|
||||
// for our working registers.
|
||||
@ -272,8 +274,9 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
|
||||
}
|
||||
|
||||
// Initialize backtrack stack pointer.
|
||||
masm.loadPtr(AbsoluteAddress(cx->runtime()->contextFromMainThread()->regexpStack.ref().addressOfBase()),
|
||||
backtrack_stack_pointer);
|
||||
size_t baseOffset = offsetof(JSContext, regexpStack) + RegExpStack::offsetOfBase();
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), backtrack_stack_pointer);
|
||||
masm.loadPtr(Address(backtrack_stack_pointer, baseOffset), backtrack_stack_pointer);
|
||||
masm.storePtr(backtrack_stack_pointer,
|
||||
Address(masm.getStackPointer(), offsetof(FrameData, backtrackStackBase)));
|
||||
|
||||
@ -463,7 +466,10 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
|
||||
Address backtrackStackBaseAddress(temp2, offsetof(FrameData, backtrackStackBase));
|
||||
masm.subPtr(backtrackStackBaseAddress, backtrack_stack_pointer);
|
||||
|
||||
masm.loadPtr(AbsoluteAddress(cx->runtime()->contextFromMainThread()->regexpStack.ref().addressOfBase()), temp1);
|
||||
void* context_addr = &cx->zone()->group()->context;
|
||||
size_t baseOffset = offsetof(JSContext, regexpStack) + RegExpStack::offsetOfBase();
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), temp1);
|
||||
masm.loadPtr(Address(temp1, baseOffset), temp1);
|
||||
masm.storePtr(temp1, backtrackStackBaseAddress);
|
||||
masm.addPtr(temp1, backtrack_stack_pointer);
|
||||
|
||||
@ -542,8 +548,9 @@ NativeRegExpMacroAssembler::Backtrack()
|
||||
|
||||
// Check for an interrupt.
|
||||
Label noInterrupt;
|
||||
masm.branch32(Assembler::Equal,
|
||||
AbsoluteAddress(&cx->runtime()->contextFromMainThread()->interrupt_), Imm32(0),
|
||||
void* contextAddr = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(contextAddr), temp0);
|
||||
masm.branch32(Assembler::Equal, Address(temp0, offsetof(JSContext, interrupt_)), Imm32(0),
|
||||
&noInterrupt);
|
||||
masm.movePtr(ImmWord(RegExpRunStatus_Error), temp0);
|
||||
masm.jump(&exit_label_);
|
||||
@ -1101,10 +1108,11 @@ NativeRegExpMacroAssembler::CheckBacktrackStackLimit()
|
||||
{
|
||||
JitSpew(SPEW_PREFIX "CheckBacktrackStackLimit");
|
||||
|
||||
const void* limitAddr = cx->runtime()->contextFromMainThread()->regexpStack.ref().addressOfLimit();
|
||||
|
||||
Label no_stack_overflow;
|
||||
masm.branchPtr(Assembler::AboveOrEqual, AbsoluteAddress(limitAddr),
|
||||
void* context_addr = &cx->zone()->group()->context;
|
||||
size_t limitOffset = offsetof(JSContext, regexpStack) + RegExpStack::offsetOfLimit();
|
||||
masm.loadPtr(AbsoluteAddress(context_addr), temp1);
|
||||
masm.branchPtr(Assembler::AboveOrEqual, Address(temp1, limitOffset),
|
||||
backtrack_stack_pointer, &no_stack_overflow);
|
||||
|
||||
// Copy the stack pointer before the call() instruction modifies it.
|
||||
|
@ -79,8 +79,8 @@ class RegExpStack
|
||||
bool grow();
|
||||
|
||||
// Address of allocated memory.
|
||||
const void* addressOfBase() { return &base_; }
|
||||
const void* addressOfLimit() { return &limit_; }
|
||||
static size_t offsetOfBase() { return offsetof(RegExpStack, base_); }
|
||||
static size_t offsetOfLimit() { return offsetof(RegExpStack, limit_); }
|
||||
|
||||
void* base() { return base_; }
|
||||
void* limit() { return limit_; }
|
||||
|
@ -44,7 +44,7 @@ jit::Bailout(BailoutStack* sp, BaselineBailoutInfo** bailoutInfo)
|
||||
MOZ_ASSERT(!iter.ionScript()->invalidated());
|
||||
CommonFrameLayout* currentFramePtr = iter.current();
|
||||
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
TraceLogTimestamp(logger, TraceLogger_Bailout);
|
||||
|
||||
JitSpew(JitSpew_IonBailouts, "Took bailout! Snapshot offset: %d", iter.snapshotOffset());
|
||||
@ -115,7 +115,7 @@ jit::InvalidationBailout(InvalidationBailoutStack* sp, size_t* frameSizeOut,
|
||||
JitFrameIterator iter(jitActivations);
|
||||
CommonFrameLayout* currentFramePtr = iter.current();
|
||||
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
TraceLogTimestamp(logger, TraceLogger_Invalidation);
|
||||
|
||||
JitSpew(JitSpew_IonBailouts, "Took invalidation bailout! Snapshot offset: %d", iter.snapshotOffset());
|
||||
|
@ -1481,7 +1481,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter
|
||||
MOZ_ASSERT(bailoutInfo != nullptr);
|
||||
MOZ_ASSERT(*bailoutInfo == nullptr);
|
||||
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
TraceLogStopEvent(logger, TraceLogger_IonMonkey);
|
||||
TraceLogStartEvent(logger, TraceLogger_Baseline);
|
||||
|
||||
@ -1606,7 +1606,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter
|
||||
// TraceLogger doesn't create entries for inlined frames. But we
|
||||
// see them in Baseline. Here we create the start events of those
|
||||
// entries. So they correspond to what we will see in Baseline.
|
||||
TraceLoggerEvent scriptEvent(logger, TraceLogger_Scripts, scr);
|
||||
TraceLoggerEvent scriptEvent(TraceLogger_Scripts, scr);
|
||||
TraceLogStartEvent(logger, scriptEvent);
|
||||
TraceLogStartEvent(logger, TraceLogger_Baseline);
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ BaselineCompiler::compile()
|
||||
JitSpew(JitSpew_Codegen, "# Emitting baseline code for script %s:%" PRIuSIZE,
|
||||
script->filename(), script->lineno());
|
||||
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerEvent scriptEvent(logger, TraceLogger_AnnotateScripts, script);
|
||||
TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx);
|
||||
TraceLoggerEvent scriptEvent(TraceLogger_AnnotateScripts, script);
|
||||
AutoTraceLog logScript(logger, scriptEvent);
|
||||
AutoTraceLog logCompile(logger, TraceLogger_BaselineCompilation);
|
||||
|
||||
@ -525,7 +525,6 @@ bool
|
||||
BaselineCompiler::emitStackCheck(bool earlyCheck)
|
||||
{
|
||||
Label skipCall;
|
||||
void* limitAddr = &cx->runtime()->contextFromMainThread()->jitStackLimit;
|
||||
uint32_t slotsSize = script->nslots() * sizeof(Value);
|
||||
uint32_t tolerance = earlyCheck ? slotsSize : 0;
|
||||
|
||||
@ -551,7 +550,10 @@ BaselineCompiler::emitStackCheck(bool earlyCheck)
|
||||
&forceCall);
|
||||
}
|
||||
|
||||
masm.branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(limitAddr), R1.scratchReg(),
|
||||
void* contextAddr = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(contextAddr), R0.scratchReg());
|
||||
masm.branchPtr(Assembler::BelowOrEqual,
|
||||
Address(R0.scratchReg(), offsetof(JSContext, jitStackLimit)), R1.scratchReg(),
|
||||
&skipCall);
|
||||
|
||||
if (!earlyCheck && needsEarlyStackCheck())
|
||||
@ -697,8 +699,11 @@ BaselineCompiler::emitInterruptCheck()
|
||||
frame.syncStack(0);
|
||||
|
||||
Label done;
|
||||
void* interrupt = &cx->runtime()->contextFromMainThread()->interrupt_;
|
||||
masm.branch32(Assembler::Equal, AbsoluteAddress(interrupt), Imm32(0), &done);
|
||||
void* context = &cx->zone()->group()->context;
|
||||
masm.loadPtr(AbsoluteAddress(context), R0.scratchReg());
|
||||
masm.branch32(Assembler::Equal,
|
||||
Address(R0.scratchReg(), offsetof(JSContext, interrupt_)), Imm32(0),
|
||||
&done);
|
||||
|
||||
prepareVMCall();
|
||||
if (!callVM(InterruptCheckInfo))
|
||||
@ -838,7 +843,6 @@ BaselineCompiler::emitDebugTrap()
|
||||
bool
|
||||
BaselineCompiler::emitTraceLoggerEnter()
|
||||
{
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
Register loggerReg = regs.takeAnyGeneral();
|
||||
Register scriptReg = regs.takeAnyGeneral();
|
||||
@ -850,7 +854,7 @@ BaselineCompiler::emitTraceLoggerEnter()
|
||||
masm.Push(loggerReg);
|
||||
masm.Push(scriptReg);
|
||||
|
||||
masm.movePtr(ImmPtr(logger), loggerReg);
|
||||
masm.loadTraceLogger(loggerReg);
|
||||
|
||||
// Script start.
|
||||
masm.movePtr(ImmGCPtr(script), scriptReg);
|
||||
@ -873,7 +877,6 @@ BaselineCompiler::emitTraceLoggerEnter()
|
||||
bool
|
||||
BaselineCompiler::emitTraceLoggerExit()
|
||||
{
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
Register loggerReg = regs.takeAnyGeneral();
|
||||
|
||||
@ -882,7 +885,7 @@ BaselineCompiler::emitTraceLoggerExit()
|
||||
return false;
|
||||
|
||||
masm.Push(loggerReg);
|
||||
masm.movePtr(ImmPtr(logger), loggerReg);
|
||||
masm.loadTraceLogger(loggerReg);
|
||||
|
||||
masm.tracelogStopId(loggerReg, TraceLogger_Baseline, /* force = */ true);
|
||||
masm.tracelogStopId(loggerReg, TraceLogger_Scripts, /* force = */ true);
|
||||
@ -904,8 +907,7 @@ BaselineCompiler::emitTraceLoggerResume(Register baselineScript, AllocatableGene
|
||||
if (!traceLoggerToggleOffsets_.append(masm.toggledJump(&noTraceLogger)))
|
||||
return false;
|
||||
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
masm.movePtr(ImmPtr(logger), loggerReg);
|
||||
masm.loadTraceLogger(loggerReg);
|
||||
|
||||
Address scriptEvent(baselineScript, BaselineScript::offsetOfTraceLoggerScriptEvent());
|
||||
masm.computeEffectiveAddress(scriptEvent, scriptId);
|
||||
|
@ -820,8 +820,8 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_
|
||||
bool isTemporarilyUnoptimizable = false;
|
||||
if (!attached && !JitOptions.disableCacheIR) {
|
||||
ICStubEngine engine = ICStubEngine::Baseline;
|
||||
GetPropIRGenerator gen(cx, pc, CacheKind::GetElem, engine, &isTemporarilyUnoptimizable,
|
||||
lhs, rhs, CanAttachGetter::Yes);
|
||||
GetPropIRGenerator gen(cx, script, pc, CacheKind::GetElem, engine,
|
||||
&isTemporarilyUnoptimizable, lhs, rhs, CanAttachGetter::Yes);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
engine, info.outerScript(cx), stub);
|
||||
@ -1110,7 +1110,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
|
||||
if (stub->numOptimizedStubs() < ICSetElem_Fallback::MAX_OPTIMIZED_STUBS &&
|
||||
!JitOptions.disableCacheIR)
|
||||
{
|
||||
SetPropIRGenerator gen(cx, pc, CacheKind::SetElem, &isTemporarilyUnoptimizable,
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetElem, &isTemporarilyUnoptimizable,
|
||||
objv, index, rhs);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
@ -1193,7 +1193,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
|
||||
}
|
||||
|
||||
if (!JitOptions.disableCacheIR) {
|
||||
SetPropIRGenerator gen(cx, pc, CacheKind::SetElem, &isTemporarilyUnoptimizable,
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetElem, &isTemporarilyUnoptimizable,
|
||||
objv, index, rhs);
|
||||
if (gen.tryAttachAddSlotStub(oldGroup, oldShape)) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
@ -1205,6 +1205,8 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
|
||||
newStub->toCacheIR_Updated()->updateStubId() = gen.updateStubId();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
gen.trackNotAttached();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1963,15 +1965,16 @@ DoInFallback(JSContext* cx, BaselineFrame* frame, ICIn_Fallback* stub_,
|
||||
if (stub->numOptimizedStubs() >= ICIn_Fallback::MAX_OPTIMIZED_STUBS)
|
||||
attached = true;
|
||||
|
||||
RootedScript script(cx, frame->script());
|
||||
RootedObject obj(cx, &objValue.toObject());
|
||||
jsbytecode* pc = stub->icEntry()->pc(frame->script());
|
||||
jsbytecode* pc = stub->icEntry()->pc(script);
|
||||
|
||||
if (!attached && !JitOptions.disableCacheIR) {
|
||||
ICStubEngine engine = ICStubEngine::Baseline;
|
||||
InIRGenerator gen(cx, pc, key, obj);
|
||||
InIRGenerator gen(cx, script, pc, key, obj);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
engine, frame->script(), stub);
|
||||
engine, script, stub);
|
||||
if (newStub) {
|
||||
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
|
||||
attached = true;
|
||||
@ -2039,7 +2042,7 @@ DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub_
|
||||
|
||||
if (!attached && !JitOptions.disableCacheIR) {
|
||||
ICStubEngine engine = ICStubEngine::Baseline;
|
||||
GetNameIRGenerator gen(cx, pc, script, envChain, name);
|
||||
GetNameIRGenerator gen(cx, script, pc, envChain, name);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
engine, info.outerScript(cx), stub);
|
||||
@ -2271,7 +2274,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
|
||||
!JitOptions.disableCacheIR)
|
||||
{
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
SetPropIRGenerator gen(cx, pc, CacheKind::SetProp, &isTemporarilyUnoptimizable,
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetProp, &isTemporarilyUnoptimizable,
|
||||
lhs, idVal, rhs);
|
||||
if (gen.tryAttachStub()) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
@ -2340,7 +2343,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
|
||||
!JitOptions.disableCacheIR)
|
||||
{
|
||||
RootedValue idVal(cx, StringValue(name));
|
||||
SetPropIRGenerator gen(cx, pc, CacheKind::SetProp, &isTemporarilyUnoptimizable,
|
||||
SetPropIRGenerator gen(cx, script, pc, CacheKind::SetProp, &isTemporarilyUnoptimizable,
|
||||
lhs, idVal, rhs);
|
||||
if (gen.tryAttachAddSlotStub(oldGroup, oldShape)) {
|
||||
ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(),
|
||||
@ -2351,6 +2354,8 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
|
||||
newStub->toCacheIR_Updated()->updateStubGroup() = gen.updateStubGroup();
|
||||
newStub->toCacheIR_Updated()->updateStubId() = gen.updateStubId();
|
||||
}
|
||||
} else {
|
||||
gen.trackNotAttached();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4121,7 +4126,7 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
EmitBaselineCreateStubFrameDescriptor(masm, scratch, ExitFrameLayout::Size());
|
||||
masm.push(scratch);
|
||||
masm.push(ICTailCallReg);
|
||||
masm.enterFakeExitFrameForNative(isConstructing_);
|
||||
masm.enterFakeExitFrameForNative(scratch, isConstructing_);
|
||||
|
||||
// Execute call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
@ -4213,7 +4218,7 @@ ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
EmitBaselineCreateStubFrameDescriptor(masm, scratch, ExitFrameLayout::Size());
|
||||
masm.push(scratch);
|
||||
masm.push(ICTailCallReg);
|
||||
masm.enterFakeExitFrameForNative(isConstructing_);
|
||||
masm.enterFakeExitFrameForNative(scratch, isConstructing_);
|
||||
|
||||
// Execute call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user