mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
38abc51ffe
@ -389,8 +389,10 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
childDoc->SetIPCDoc(ipcDoc);
|
||||
nsCOMPtr<nsITabChild> tabChild =
|
||||
do_GetInterface(mDocument->DocumentNode()->GetDocShell());
|
||||
static_cast<TabChild*>(tabChild.get())->
|
||||
SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
|
||||
if (tabChild) {
|
||||
static_cast<TabChild*>(tabChild.get())->
|
||||
SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,7 +763,9 @@
|
||||
}
|
||||
|
||||
// If the browser was playing audio, we should remove the playing state.
|
||||
if (this.mTab.hasAttribute("soundplaying") && this.mBrowser.lastURI != aLocation) {
|
||||
if (this.mTab.hasAttribute("soundplaying") &&
|
||||
(!this.mBrowser.lastURI ||
|
||||
this.mBrowser.lastURI.spec != aLocation.spec)) {
|
||||
this.mTab.removeAttribute("soundplaying");
|
||||
this.mTabBrowser._tabAttrModified(this.mTab, ["soundplaying"]);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ support-files =
|
||||
file_disableScript.html
|
||||
|
||||
[test_app_principal_equality.html]
|
||||
skip-if = e10s
|
||||
[test_bug246699.html]
|
||||
[test_bug292789.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
|
||||
|
@ -13,25 +13,47 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=777467
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=777467">Mozilla Bug 777467</a>
|
||||
<p id="display"></p>
|
||||
<script>
|
||||
// Initialization.
|
||||
SpecialPowers.addPermission("browser", true, document);
|
||||
SpecialPowers.addPermission("embed-apps", true, document);
|
||||
|
||||
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', true);
|
||||
SpecialPowers.setBoolPref("dom.ipc.browser_frames.oop_by_default", false);
|
||||
</script>
|
||||
<div id="content" style="display: none;">
|
||||
<iframe src="error404"></iframe>
|
||||
<iframe mozbrowser src="error404"></iframe>
|
||||
<iframe mozapp="http://example.org/manifest.webapp" mozbrowser src="error404"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for app principal's equality **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var permissions = new Promise(resolve => {
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ type: "browser", allow: true, context: document },
|
||||
{ type: "embed-apps", allow: true, context: document }],
|
||||
resolve);
|
||||
});
|
||||
|
||||
permissions.then(() => {
|
||||
$('content').innerHTML =
|
||||
'<iframe src="error404"></iframe>\n' +
|
||||
'<iframe mozbrowser src="error404"></iframe>\n' +
|
||||
'<iframe mozapp="http://example.org/manifest.webapp" mozbrowser src="error404"></iframe>';
|
||||
|
||||
var iframes = document.getElementsByTagName("iframe");
|
||||
var promises = []
|
||||
for (var i = 0; i < promises.length; ++i) {
|
||||
promises.push(new Promise(resolve => {
|
||||
iframes[i].addEventListener("load", resolve);
|
||||
}));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
});
|
||||
|
||||
var prefs = new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ set: [[ "dom.mozBrowserFramesEnabled", true ],
|
||||
[ "dom.ipc.browser_frames.oop_by_default", false ]] },
|
||||
resolve);
|
||||
});
|
||||
</script>
|
||||
<div id="content" style="display: none;">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
function canAccessDocument(win) {
|
||||
var result = true;
|
||||
try {
|
||||
@ -42,7 +64,11 @@ function canAccessDocument(win) {
|
||||
return result;
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
var loaded = new Promise(resolve => addLoadEvent(resolve));
|
||||
|
||||
Promise.all([ permissions, prefs, loaded ]).then(runTest);
|
||||
|
||||
function runTest() {
|
||||
// Test the witness frame (we can access same-origin frame).
|
||||
is(canAccessDocument(frames[0]), true,
|
||||
"should be able to access the first frame");
|
||||
@ -53,14 +79,8 @@ addLoadEvent(function() {
|
||||
"should not be able to access the other frames");
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
SpecialPowers.clearUserPref('dom.mozBrowserFramesEnabled');
|
||||
SpecialPowers.clearUserPref('dom.ipc.browser_frames.oop_by_default');
|
||||
SpecialPowers.removePermission("browser", window.document);
|
||||
SpecialPowers.removePermission("embed-apps", window.document);
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -1448,7 +1448,7 @@ if test "$GNU_CC"; then
|
||||
|
||||
# -Wall - lots of useful warnings
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Wignored-qualifiers - catches returns types with qualifiers like const
|
||||
# -Wignored-qualifiers - catches return types with qualifiers like const
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall"
|
||||
@ -1530,11 +1530,13 @@ if test "$GNU_CXX"; then
|
||||
|
||||
# -Wall - lots of useful warnings
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Wignored-qualifiers - catches return types with qualifiers like const
|
||||
# -Woverloaded-virtual - function declaration hides virtual function from base class
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wempty-body"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wignored-qualifiers"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Woverloaded-virtual"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wpointer-arith"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
|
||||
|
@ -30,7 +30,6 @@ DevToolsModules(
|
||||
'inplace-editor.js',
|
||||
'Jsbeautify.jsm',
|
||||
'node-attribute-parser.js',
|
||||
'observable-object.js',
|
||||
'options-view.js',
|
||||
'output-parser.js',
|
||||
'poller.js',
|
||||
|
@ -1,131 +0,0 @@
|
||||
/* this source code form is subject to the terms of the mozilla public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* ObservableObject
|
||||
*
|
||||
* An observable object is a JSON-like object that throws
|
||||
* events when its direct properties or properties of any
|
||||
* contained objects, are getting accessed or set.
|
||||
*
|
||||
* Inherits from EventEmitter.
|
||||
*
|
||||
* Properties:
|
||||
* ⬩ object: JSON-like object
|
||||
*
|
||||
* Events:
|
||||
* ⬩ "get" / path (array of property names)
|
||||
* ⬩ "set" / path / new value
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* let emitter = new ObservableObject({ x: { y: [10] } });
|
||||
* emitter.on("set", console.log);
|
||||
* emitter.on("get", console.log);
|
||||
* let obj = emitter.object;
|
||||
* obj.x.y[0] = 50;
|
||||
*
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
|
||||
function ObservableObject(object = {}) {
|
||||
EventEmitter.decorate(this);
|
||||
let handler = new Handler(this);
|
||||
this.object = new Proxy(object, handler);
|
||||
handler._wrappers.set(this.object, object);
|
||||
handler._paths.set(object, []);
|
||||
}
|
||||
|
||||
module.exports = ObservableObject;
|
||||
|
||||
function isObject(x) {
|
||||
if (typeof x === "object")
|
||||
return x !== null;
|
||||
return typeof x === "function";
|
||||
}
|
||||
|
||||
function Handler(emitter) {
|
||||
this._emitter = emitter;
|
||||
this._wrappers = new WeakMap();
|
||||
this._values = new WeakMap();
|
||||
this._paths = new WeakMap();
|
||||
}
|
||||
|
||||
Handler.prototype = {
|
||||
wrap: function(target, key, value) {
|
||||
let path;
|
||||
if (!isObject(value)) {
|
||||
path = this._paths.get(target).concat(key);
|
||||
} else if (this._wrappers.has(value)) {
|
||||
path = this._paths.get(value);
|
||||
} else if (this._paths.has(value)) {
|
||||
path = this._paths.get(value);
|
||||
value = this._values.get(value);
|
||||
} else {
|
||||
path = this._paths.get(target).concat(key);
|
||||
this._paths.set(value, path);
|
||||
let wrapper = new Proxy(value, this);
|
||||
this._wrappers.set(wrapper, value);
|
||||
this._values.set(value, wrapper);
|
||||
value = wrapper;
|
||||
}
|
||||
return [value, path];
|
||||
},
|
||||
unwrap: function(target, key, value) {
|
||||
if (!isObject(value) || !this._wrappers.has(value)) {
|
||||
return [value, this._paths.get(target).concat(key)];
|
||||
}
|
||||
return [this._wrappers.get(value), this._paths.get(target).concat(key)];
|
||||
},
|
||||
get: function(target, key) {
|
||||
let value = target[key];
|
||||
let [wrapped, path] = this.wrap(target, key, value);
|
||||
this._emitter.emit("get", path, value);
|
||||
return wrapped;
|
||||
},
|
||||
set: function(target, key, value) {
|
||||
let [wrapped, path] = this.unwrap(target, key, value);
|
||||
target[key] = value;
|
||||
this._emitter.emit("set", path, value);
|
||||
return true;
|
||||
},
|
||||
getOwnPropertyDescriptor: function(target, key) {
|
||||
let desc = Object.getOwnPropertyDescriptor(target, key);
|
||||
if (desc) {
|
||||
if ("value" in desc) {
|
||||
let [wrapped, path] = this.wrap(target, key, desc.value);
|
||||
desc.value = wrapped;
|
||||
this._emitter.emit("get", path, desc.value);
|
||||
} else {
|
||||
if ("get" in desc) {
|
||||
[desc.get] = this.wrap(target, "get "+key, desc.get);
|
||||
}
|
||||
if ("set" in desc) {
|
||||
[desc.set] = this.wrap(target, "set "+key, desc.set);
|
||||
}
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
},
|
||||
defineProperty: function(target, key, desc) {
|
||||
if ("value" in desc) {
|
||||
let [unwrapped, path] = this.unwrap(target, key, desc.value);
|
||||
desc.value = unwrapped;
|
||||
Object.defineProperty(target, key, desc);
|
||||
this._emitter.emit("set", path, desc.value);
|
||||
} else {
|
||||
if ("get" in desc) {
|
||||
[desc.get] = this.unwrap(target, "get "+key, desc.get);
|
||||
}
|
||||
if ("set" in desc) {
|
||||
[desc.set] = this.unwrap(target, "set "+key, desc.set);
|
||||
}
|
||||
Object.defineProperty(target, key, desc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
@ -118,7 +118,6 @@ skip-if = e10s # Layouthelpers test should not run in a content page.
|
||||
[browser_mdn-docs-02.js]
|
||||
[browser_mdn-docs-03.js]
|
||||
[browser_num-l10n.js]
|
||||
[browser_observableobject.js]
|
||||
[browser_options-view-01.js]
|
||||
[browser_outputparser.js]
|
||||
skip-if = e10s # Test intermittently fails with e10s. Bug 1124162.
|
||||
|
@ -1,85 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let ObservableObject = require("devtools/client/shared/observable-object");
|
||||
|
||||
let rawObject = {};
|
||||
let oe = new ObservableObject(rawObject);
|
||||
|
||||
function str(o) {
|
||||
return JSON.stringify(o);
|
||||
}
|
||||
|
||||
function areObjectsSynced() {
|
||||
is(str(rawObject), str(oe.object), "Objects are synced");
|
||||
}
|
||||
|
||||
areObjectsSynced();
|
||||
|
||||
let index = 0;
|
||||
let expected = [
|
||||
{type: "set", path: "foo", value: 4},
|
||||
{type: "get", path: "foo", value: 4},
|
||||
{type: "get", path: "foo", value: 4},
|
||||
{type: "get", path: "bar", value: undefined},
|
||||
{type: "get", path: "bar", value: undefined},
|
||||
{type: "set", path: "bar", value: {}},
|
||||
{type: "get", path: "bar", value: {}},
|
||||
{type: "get", path: "bar", value: {}},
|
||||
{type: "set", path: "bar.a", value: [1,2,3,4]},
|
||||
{type: "get", path: "bar", value: {a:[1,2,3,4]}},
|
||||
{type: "set", path: "bar.mop", value: 1},
|
||||
{type: "set", path: "bar", value: {}},
|
||||
{type: "set", path: "foo", value: [{a:42}]},
|
||||
{type: "get", path: "foo", value: [{a:42}]},
|
||||
{type: "get", path: "foo.0", value: {a:42}},
|
||||
{type: "get", path: "foo.0.a", value: 42},
|
||||
{type: "get", path: "foo", value: [{a:42}]},
|
||||
{type: "get", path: "foo.0", value: {a:42}},
|
||||
{type: "set", path: "foo.0.a", value: 2},
|
||||
{type: "get", path: "foo", value: [{a:2}]},
|
||||
{type: "get", path: "bar", value: {}},
|
||||
{type: "set", path: "foo.1", value: {}},
|
||||
];
|
||||
|
||||
function callback(event, path, value) {
|
||||
oe.off("get", callback);
|
||||
ok(event, "event defined");
|
||||
ok(path, "path defined");
|
||||
if (index >= expected.length) {
|
||||
return;
|
||||
}
|
||||
let e = expected[index];
|
||||
is(event, e.type, "[" + index + "] Right event received");
|
||||
is(path.join("."), e.path, "[" + index + "] Path valid");
|
||||
is(str(value), str(e.value), "[" + index + "] Value valid");
|
||||
index++;
|
||||
areObjectsSynced();
|
||||
oe.on("get", callback);
|
||||
}
|
||||
|
||||
oe.on("set", callback);
|
||||
oe.on("get", callback);
|
||||
|
||||
oe.object.foo = 4;
|
||||
oe.object.foo;
|
||||
Object.getOwnPropertyDescriptor(oe.object, "foo")
|
||||
oe.object["bar"];
|
||||
oe.object.bar;
|
||||
oe.object.bar = {};
|
||||
oe.object.bar;
|
||||
oe.object.bar.a = [1,2,3,4];
|
||||
Object.defineProperty(oe.object.bar, "mop", {value:1});
|
||||
oe.object.bar = {};
|
||||
oe.object.foo = [{a:42}];
|
||||
oe.object.foo[0].a;
|
||||
oe.object.foo[0].a = 2;
|
||||
oe.object.foo[1] = oe.object.bar;
|
||||
|
||||
is(index, expected.length, "Event count is right");
|
||||
is(oe.object.bar, oe.object.bar, "Object attributes are wrapped only once");
|
||||
|
||||
finish();
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const {Cc,Ci,Cu,Cr} = require("chrome");
|
||||
const ObservableObject = require("devtools/client/shared/observable-object");
|
||||
const promise = require("promise");
|
||||
|
||||
const {EventEmitter} = Cu.import("resource://devtools/shared/event-emitter.js", {});
|
||||
@ -38,7 +37,7 @@ const IDB = {
|
||||
request.onsuccess = function() {
|
||||
let db = IDB._db = request.result;
|
||||
let objectStore = db.transaction("projects").objectStore("projects");
|
||||
let projects = []
|
||||
let projects = [];
|
||||
let toRemove = [];
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
@ -88,8 +87,6 @@ const IDB = {
|
||||
add: function(project) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
project = JSON.parse(JSON.stringify(project));
|
||||
|
||||
if (!project.location) {
|
||||
// We need to make sure this object has a `.location` property.
|
||||
deferred.reject("Missing location property on project object.");
|
||||
@ -112,12 +109,6 @@ const IDB = {
|
||||
update: function(project) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Clone object to make it storable by IndexedDB.
|
||||
// Projects are proxified objects (for the template
|
||||
// mechanismn in the first version of the App Manager).
|
||||
// This will change in the future.
|
||||
project = JSON.parse(JSON.stringify(project));
|
||||
|
||||
var transaction = IDB._db.transaction(["projects"], "readwrite");
|
||||
var objectStore = transaction.objectStore("projects");
|
||||
var request = objectStore.put(project);
|
||||
@ -150,13 +141,11 @@ const IDB = {
|
||||
}
|
||||
};
|
||||
|
||||
const store = new ObservableObject({ projects:[] });
|
||||
|
||||
var loadDeferred = promise.defer();
|
||||
|
||||
loadDeferred.resolve(IDB.open().then(function (projects) {
|
||||
store.object.projects = projects;
|
||||
AppProjects.emit("ready", store.object.projects);
|
||||
AppProjects.projects = projects;
|
||||
AppProjects.emit("ready", projects);
|
||||
}));
|
||||
|
||||
const AppProjects = {
|
||||
@ -185,10 +174,9 @@ const AppProjects = {
|
||||
// we will override this random UUID on app install.
|
||||
packagedAppOrigin: generateUUID().toString().slice(1, -1)
|
||||
};
|
||||
return IDB.add(project).then(function () {
|
||||
store.object.projects.push(project);
|
||||
// return the added objects (proxified)
|
||||
return store.object.projects[store.object.projects.length - 1];
|
||||
return IDB.add(project).then(() => {
|
||||
this.projects.push(project);
|
||||
return project;
|
||||
});
|
||||
},
|
||||
|
||||
@ -201,10 +189,9 @@ const AppProjects = {
|
||||
type: "hosted",
|
||||
location: manifestURL
|
||||
};
|
||||
return IDB.add(project).then(function () {
|
||||
store.object.projects.push(project);
|
||||
// return the added objects (proxified)
|
||||
return store.object.projects[store.object.projects.length - 1];
|
||||
return IDB.add(project).then(() => {
|
||||
this.projects.push(project);
|
||||
return project;
|
||||
});
|
||||
},
|
||||
|
||||
@ -221,11 +208,10 @@ const AppProjects = {
|
||||
},
|
||||
|
||||
remove: function(location) {
|
||||
return IDB.remove(location).then(function () {
|
||||
let projects = store.object.projects;
|
||||
for (let i = 0; i < projects.length; i++) {
|
||||
if (projects[i].location == location) {
|
||||
projects.splice(i, 1);
|
||||
return IDB.remove(location).then(() => {
|
||||
for (let i = 0; i < this.projects.length; i++) {
|
||||
if (this.projects[i].location == location) {
|
||||
this.projects.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -234,16 +220,15 @@ const AppProjects = {
|
||||
},
|
||||
|
||||
get: function(location) {
|
||||
let projects = store.object.projects;
|
||||
for (let i = 0; i < projects.length; i++) {
|
||||
if (projects[i].location == location) {
|
||||
return projects[i];
|
||||
for (let i = 0; i < this.projects.length; i++) {
|
||||
if (this.projects[i].location == location) {
|
||||
return this.projects[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
store: store
|
||||
projects: []
|
||||
};
|
||||
|
||||
EventEmitter.decorate(AppProjects);
|
||||
|
@ -315,7 +315,7 @@ ProjectList.prototype = {
|
||||
}
|
||||
|
||||
AppProjects.load().then(() => {
|
||||
let projects = AppProjects.store.object.projects;
|
||||
let projects = AppProjects.projects;
|
||||
for (let i = 0; i < projects.length; i++) {
|
||||
let project = projects[i];
|
||||
let panelItemNode = doc.createElement(this._panelNodeEl);
|
||||
|
@ -94,7 +94,7 @@ function removeAllProjects() {
|
||||
yield AppProjects.load();
|
||||
// use a new array so we're not iterating over the same
|
||||
// underlying array that's being modified by AppProjects
|
||||
let projects = AppProjects.store.object.projects.map(p => p.location);
|
||||
let projects = AppProjects.projects.map(p => p.location);
|
||||
for (let i = 0; i < projects.length; i++) {
|
||||
yield AppProjects.remove(projects[i]);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
let hostedAppManifest = TEST_BASE + "hosted_app.manifest";
|
||||
|
||||
yield win.AppProjects.load();
|
||||
is(win.AppProjects.store.object.projects.length, 0, "IDB is empty");
|
||||
is(win.AppProjects.projects.length, 0, "IDB is empty");
|
||||
|
||||
info("to call importPackagedApp(" + packagedAppLocation + ")");
|
||||
yield winProject.projectList.importPackagedApp(packagedAppLocation);
|
||||
|
@ -24,7 +24,7 @@
|
||||
let packagedAppLocation = getTestFilePath("app");
|
||||
|
||||
yield win.AppProjects.load();
|
||||
is(win.AppProjects.store.object.projects.length, 0, "IDB is empty");
|
||||
is(win.AppProjects.projects.length, 0, "IDB is empty");
|
||||
|
||||
info("to call importPackagedApp(" + packagedAppLocation + ")");
|
||||
ok(!win.UI._busyPromise, "UI is not busy");
|
||||
|
@ -49,8 +49,8 @@ public:
|
||||
DOMHighResTimeStamp GetTime() const { return mTime; }
|
||||
MarkerTracingType GetTracingType() const { return mTracingType; }
|
||||
|
||||
const uint8_t GetProcessType() const { return mProcessType; };
|
||||
const bool IsOffMainThread() const { return mIsOffMainThread; };
|
||||
uint8_t GetProcessType() const { return mProcessType; };
|
||||
bool IsOffMainThread() const { return mIsOffMainThread; };
|
||||
|
||||
private:
|
||||
const char* mName;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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 "nsFormData.h"
|
||||
#include "FormData.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
@ -15,7 +15,7 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsFormData::nsFormData(nsISupports* aOwner)
|
||||
FormData::FormData(nsISupports* aOwner)
|
||||
: nsFormSubmission(NS_LITERAL_CSTRING("UTF-8"), nullptr)
|
||||
, mOwner(aOwner)
|
||||
{
|
||||
@ -61,9 +61,9 @@ CreateNewFileInstance(Blob& aBlob, const Optional<nsAString>& aFilename,
|
||||
// -------------------------------------------------------------------------
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(FormData)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
|
||||
|
||||
for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
|
||||
@ -73,7 +73,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
|
||||
|
||||
for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
|
||||
@ -84,12 +84,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FormData)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFormData)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(FormData)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(FormData)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFormData)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FormData)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFormData)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
|
||||
@ -99,23 +99,23 @@ NS_INTERFACE_MAP_END
|
||||
// -------------------------------------------------------------------------
|
||||
// nsFormSubmission
|
||||
nsresult
|
||||
nsFormData::GetEncodedSubmission(nsIURI* aURI,
|
||||
nsIInputStream** aPostDataStream)
|
||||
FormData::GetEncodedSubmission(nsIURI* aURI,
|
||||
nsIInputStream** aPostDataStream)
|
||||
{
|
||||
NS_NOTREACHED("Shouldn't call nsFormData::GetEncodedSubmission");
|
||||
NS_NOTREACHED("Shouldn't call FormData::GetEncodedSubmission");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Append(const nsAString& aName, const nsAString& aValue,
|
||||
ErrorResult& aRv)
|
||||
FormData::Append(const nsAString& aName, const nsAString& aValue,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
AddNameValuePair(aName, aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Append(const nsAString& aName, Blob& aBlob,
|
||||
const Optional<nsAString>& aFilename,
|
||||
FormData::Append(const nsAString& aName, Blob& aBlob,
|
||||
const Optional<nsAString>& aFilename,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<File> file = CreateNewFileInstance(aBlob, aFilename, aRv);
|
||||
@ -127,7 +127,7 @@ nsFormData::Append(const nsAString& aName, Blob& aBlob,
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Delete(const nsAString& aName)
|
||||
FormData::Delete(const nsAString& aName)
|
||||
{
|
||||
// We have to use this slightly awkward for loop since uint32_t >= 0 is an
|
||||
// error for being always true.
|
||||
@ -139,8 +139,8 @@ nsFormData::Delete(const nsAString& aName)
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Get(const nsAString& aName,
|
||||
Nullable<OwningFileOrUSVString>& aOutValue)
|
||||
FormData::Get(const nsAString& aName,
|
||||
Nullable<OwningFileOrUSVString>& aOutValue)
|
||||
{
|
||||
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
||||
if (aName.Equals(mFormData[i].name)) {
|
||||
@ -153,8 +153,8 @@ nsFormData::Get(const nsAString& aName,
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::GetAll(const nsAString& aName,
|
||||
nsTArray<OwningFileOrUSVString>& aValues)
|
||||
FormData::GetAll(const nsAString& aName,
|
||||
nsTArray<OwningFileOrUSVString>& aValues)
|
||||
{
|
||||
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
||||
if (aName.Equals(mFormData[i].name)) {
|
||||
@ -165,7 +165,7 @@ nsFormData::GetAll(const nsAString& aName,
|
||||
}
|
||||
|
||||
bool
|
||||
nsFormData::Has(const nsAString& aName)
|
||||
FormData::Has(const nsAString& aName)
|
||||
{
|
||||
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
||||
if (aName.Equals(mFormData[i].name)) {
|
||||
@ -177,15 +177,15 @@ nsFormData::Has(const nsAString& aName)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormData::AddNameFilePair(const nsAString& aName, File* aFile)
|
||||
FormData::AddNameFilePair(const nsAString& aName, File* aFile)
|
||||
{
|
||||
FormDataTuple* data = mFormData.AppendElement();
|
||||
SetNameFilePair(data, aName, aFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsFormData::FormDataTuple*
|
||||
nsFormData::RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName)
|
||||
FormData::FormDataTuple*
|
||||
FormData::RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName)
|
||||
{
|
||||
FormDataTuple* lastFoundTuple = nullptr;
|
||||
uint32_t lastFoundIndex = mFormData.Length();
|
||||
@ -207,9 +207,9 @@ nsFormData::RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName)
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Set(const nsAString& aName, Blob& aBlob,
|
||||
const Optional<nsAString>& aFilename,
|
||||
ErrorResult& aRv)
|
||||
FormData::Set(const nsAString& aName, Blob& aBlob,
|
||||
const Optional<nsAString>& aFilename,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
FormDataTuple* tuple = RemoveAllOthersAndGetFirstFormDataTuple(aName);
|
||||
if (tuple) {
|
||||
@ -225,8 +225,8 @@ nsFormData::Set(const nsAString& aName, Blob& aBlob,
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Set(const nsAString& aName, const nsAString& aValue,
|
||||
ErrorResult& aRv)
|
||||
FormData::Set(const nsAString& aName, const nsAString& aValue,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
FormDataTuple* tuple = RemoveAllOthersAndGetFirstFormDataTuple(aName);
|
||||
if (tuple) {
|
||||
@ -237,29 +237,29 @@ nsFormData::Set(const nsAString& aName, const nsAString& aValue,
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsFormData::GetIterableLength() const
|
||||
FormData::GetIterableLength() const
|
||||
{
|
||||
return mFormData.Length();
|
||||
}
|
||||
|
||||
const nsAString&
|
||||
nsFormData::GetKeyAtIndex(uint32_t aIndex) const
|
||||
FormData::GetKeyAtIndex(uint32_t aIndex) const
|
||||
{
|
||||
MOZ_ASSERT(aIndex < mFormData.Length());
|
||||
return mFormData[aIndex].name;
|
||||
}
|
||||
|
||||
const OwningFileOrUSVString&
|
||||
nsFormData::GetValueAtIndex(uint32_t aIndex) const
|
||||
FormData::GetValueAtIndex(uint32_t aIndex) const
|
||||
{
|
||||
MOZ_ASSERT(aIndex < mFormData.Length());
|
||||
return mFormData[aIndex].value;
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::SetNameValuePair(FormDataTuple* aData,
|
||||
const nsAString& aName,
|
||||
const nsAString& aValue)
|
||||
FormData::SetNameValuePair(FormDataTuple* aData,
|
||||
const nsAString& aName,
|
||||
const nsAString& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
aData->name = aName;
|
||||
@ -267,9 +267,9 @@ nsFormData::SetNameValuePair(FormDataTuple* aData,
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::SetNameFilePair(FormDataTuple* aData,
|
||||
const nsAString& aName,
|
||||
File* aFile)
|
||||
FormData::SetNameFilePair(FormDataTuple* aData,
|
||||
const nsAString& aName,
|
||||
File* aFile)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
aData->name = aName;
|
||||
@ -284,7 +284,7 @@ nsFormData::SetNameFilePair(FormDataTuple* aData,
|
||||
// nsIDOMFormData
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormData::Append(const nsAString& aName, nsIVariant* aValue)
|
||||
FormData::Append(const nsAString& aName, nsIVariant* aValue)
|
||||
{
|
||||
uint16_t dataType;
|
||||
nsresult rv = aValue->GetDataType(&dataType);
|
||||
@ -331,17 +331,17 @@ nsFormData::Append(const nsAString& aName, nsIVariant* aValue)
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
nsFormData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
FormData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return FormDataBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsFormData>
|
||||
nsFormData::Constructor(const GlobalObject& aGlobal,
|
||||
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
||||
ErrorResult& aRv)
|
||||
/* static */ already_AddRefed<FormData>
|
||||
FormData::Constructor(const GlobalObject& aGlobal,
|
||||
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<nsFormData> formData = new nsFormData(aGlobal.GetAsSupports());
|
||||
RefPtr<FormData> formData = new FormData(aGlobal.GetAsSupports());
|
||||
if (aFormElement.WasPassed()) {
|
||||
aRv = aFormElement.Value().WalkFormElements(formData);
|
||||
}
|
||||
@ -352,8 +352,8 @@ nsFormData::Constructor(const GlobalObject& aGlobal,
|
||||
// nsIXHRSendable
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
||||
nsACString& aContentType, nsACString& aCharset)
|
||||
FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
||||
nsACString& aContentType, nsACString& aCharset)
|
||||
{
|
||||
nsFSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nullptr);
|
||||
|
@ -4,40 +4,33 @@
|
||||
* 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 nsFormData_h__
|
||||
#define nsFormData_h__
|
||||
#ifndef mozilla_dom_FormData_h
|
||||
#define mozilla_dom_FormData_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIDOMFormData.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsFormSubmission.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FormDataBinding.h"
|
||||
#include "nsIDOMFormData.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsFormSubmission.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class HTMLFormElement;
|
||||
class GlobalObject;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
class nsFormData final : public nsIDOMFormData,
|
||||
public nsIXHRSendable,
|
||||
public nsFormSubmission,
|
||||
public nsWrapperCache
|
||||
class FormData final : public nsIDOMFormData,
|
||||
public nsIXHRSendable,
|
||||
public nsFormSubmission,
|
||||
public nsWrapperCache
|
||||
{
|
||||
private:
|
||||
~nsFormData() {}
|
||||
|
||||
typedef mozilla::dom::Blob Blob;
|
||||
typedef mozilla::dom::File File;
|
||||
typedef mozilla::dom::OwningFileOrUSVString OwningFileOrUSVString;
|
||||
~FormData() {}
|
||||
|
||||
struct FormDataTuple
|
||||
{
|
||||
@ -59,10 +52,10 @@ private:
|
||||
File* aFile);
|
||||
|
||||
public:
|
||||
explicit nsFormData(nsISupports* aOwner = nullptr);
|
||||
explicit FormData(nsISupports* aOwner = nullptr);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFormData,
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(FormData,
|
||||
nsIDOMFormData)
|
||||
|
||||
NS_DECL_NSIDOMFORMDATA
|
||||
@ -77,32 +70,42 @@ public:
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
static already_AddRefed<nsFormData>
|
||||
Constructor(const mozilla::dom::GlobalObject& aGlobal,
|
||||
const mozilla::dom::Optional<mozilla::dom::NonNull<mozilla::dom::HTMLFormElement> >& aFormElement,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<FormData>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const Optional<NonNull<HTMLFormElement> >& aFormElement,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Append(const nsAString& aName, const nsAString& aValue,
|
||||
mozilla::ErrorResult& aRv);
|
||||
ErrorResult& aRv);
|
||||
void Append(const nsAString& aName, Blob& aBlob,
|
||||
const mozilla::dom::Optional<nsAString>& aFilename,
|
||||
mozilla::ErrorResult& aRv);
|
||||
const Optional<nsAString>& aFilename,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Delete(const nsAString& aName);
|
||||
void Get(const nsAString& aName, mozilla::dom::Nullable<OwningFileOrUSVString>& aOutValue);
|
||||
|
||||
void Get(const nsAString& aName, Nullable<OwningFileOrUSVString>& aOutValue);
|
||||
|
||||
void GetAll(const nsAString& aName, nsTArray<OwningFileOrUSVString>& aValues);
|
||||
|
||||
bool Has(const nsAString& aName);
|
||||
|
||||
void Set(const nsAString& aName, Blob& aBlob,
|
||||
const mozilla::dom::Optional<nsAString>& aFilename,
|
||||
mozilla::ErrorResult& aRv);
|
||||
const Optional<nsAString>& aFilename,
|
||||
ErrorResult& aRv);
|
||||
void Set(const nsAString& aName, const nsAString& aValue,
|
||||
mozilla::ErrorResult& aRv);
|
||||
ErrorResult& aRv);
|
||||
|
||||
uint32_t GetIterableLength() const;
|
||||
|
||||
const nsAString& GetKeyAtIndex(uint32_t aIndex) const;
|
||||
|
||||
const OwningFileOrUSVString& GetValueAtIndex(uint32_t aIndex) const;
|
||||
|
||||
// nsFormSubmission
|
||||
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
|
||||
nsIInputStream** aPostDataStream) override;
|
||||
virtual nsresult
|
||||
GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream) override;
|
||||
|
||||
virtual nsresult AddNameValuePair(const nsAString& aName,
|
||||
const nsAString& aValue) override
|
||||
{
|
||||
@ -110,6 +113,7 @@ public:
|
||||
SetNameValuePair(data, aName, aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual nsresult AddNameFilePair(const nsAString& aName,
|
||||
File* aFile) override;
|
||||
|
||||
@ -144,4 +148,7 @@ private:
|
||||
nsTArray<FormDataTuple> mFormData;
|
||||
};
|
||||
|
||||
#endif // nsFormData_h__
|
||||
} // dom namespace
|
||||
} // mozilla namepsace
|
||||
|
||||
#endif // mozilla_dom_FormData_h
|
@ -106,7 +106,7 @@
|
||||
#include "mozilla/dom/Promise.h"
|
||||
|
||||
#include "nsIUploadChannel2.h"
|
||||
#include "nsFormData.h"
|
||||
#include "mozilla/dom/FormData.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
#include "WorkerPrivate.h"
|
||||
@ -1292,7 +1292,7 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||
mimeType = NS_ConvertUTF16toUTF8(type);
|
||||
|
||||
} else if (aData.Value().IsFormData()) {
|
||||
nsFormData& form = aData.Value().GetAsFormData();
|
||||
FormData& form = aData.Value().GetAsFormData();
|
||||
uint64_t len;
|
||||
nsAutoCString charset;
|
||||
form.GetSendInfo(getter_AddRefs(in),
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileList.h"
|
||||
#include "mozilla/dom/FileListBinding.h"
|
||||
#include "mozilla/dom/FormData.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
@ -33,7 +34,6 @@
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "MultipartBlobImpl.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsIRemoteBlob.h"
|
||||
#include "nsQueryObject.h"
|
||||
|
||||
@ -816,8 +816,8 @@ ReadFormData(JSContext* aCx,
|
||||
// See the serialization of the FormData for the format.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
RefPtr<nsFormData> formData =
|
||||
new nsFormData(aHolder->ParentDuringRead());
|
||||
RefPtr<FormData> formData =
|
||||
new FormData(aHolder->ParentDuringRead());
|
||||
|
||||
Optional<nsAString> thirdArg;
|
||||
for (uint32_t i = 0; i < aCount; ++i) {
|
||||
@ -887,7 +887,7 @@ ReadFormData(JSContext* aCx,
|
||||
// - value string
|
||||
bool
|
||||
WriteFormData(JSStructuredCloneWriter* aWriter,
|
||||
nsFormData* aFormData,
|
||||
FormData* aFormData,
|
||||
StructuredCloneHolder* aHolder)
|
||||
{
|
||||
MOZ_ASSERT(aWriter);
|
||||
@ -1010,7 +1010,7 @@ StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
||||
|
||||
// See if this is a FormData object.
|
||||
{
|
||||
nsFormData* formData = nullptr;
|
||||
FormData* formData = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FormData, aObj, formData))) {
|
||||
return WriteFormData(aWriter, formData, this);
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ EXPORTS += [
|
||||
'nsDOMNavigationTiming.h',
|
||||
'nsDOMString.h',
|
||||
'nsFocusManager.h',
|
||||
'nsFormData.h',
|
||||
'nsFrameMessageManager.h',
|
||||
'nsGenericDOMDataNode.h',
|
||||
'nsGkAtomList.h',
|
||||
@ -180,6 +179,7 @@ EXPORTS.mozilla.dom += [
|
||||
'File.h',
|
||||
'FileList.h',
|
||||
'FileReader.h',
|
||||
'FormData.h',
|
||||
'FragmentOrElement.h',
|
||||
'FromParser.h',
|
||||
'ImageEncoder.h',
|
||||
@ -246,6 +246,7 @@ UNIFIED_SOURCES += [
|
||||
'File.cpp',
|
||||
'FileList.cpp',
|
||||
'FileReader.cpp',
|
||||
'FormData.cpp',
|
||||
'FragmentOrElement.cpp',
|
||||
'ImageEncoder.cpp',
|
||||
'ImportManager.cpp',
|
||||
@ -280,7 +281,6 @@ UNIFIED_SOURCES += [
|
||||
'nsDOMTokenList.cpp',
|
||||
'nsDOMWindowList.cpp',
|
||||
'nsFocusManager.cpp',
|
||||
'nsFormData.cpp',
|
||||
'nsFrameLoader.cpp',
|
||||
'nsGenConImageContent.cpp',
|
||||
'nsGenericDOMDataNode.cpp',
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "mozilla/dom/BlobSet.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FetchUtil.h"
|
||||
#include "mozilla/dom/FormData.h"
|
||||
#include "mozilla/dom/XMLHttpRequestUploadBinding.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
@ -73,7 +74,6 @@
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIClassOfService.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsStreamListenerWrapper.h"
|
||||
#include "xpcjsid.h"
|
||||
#include "nsITimedChannel.h"
|
||||
|
@ -41,7 +41,6 @@
|
||||
#undef Status
|
||||
#endif
|
||||
|
||||
class nsFormData;
|
||||
class nsIJARChannel;
|
||||
class nsILoadGroup;
|
||||
class nsIUnicodeDecoder;
|
||||
@ -52,6 +51,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
class Blob;
|
||||
class BlobSet;
|
||||
class FormData;
|
||||
} // namespace dom
|
||||
|
||||
// A helper for building up an ArrayBuffer object's data
|
||||
@ -363,7 +363,7 @@ private:
|
||||
{
|
||||
mValue.mString = &aString;
|
||||
}
|
||||
explicit RequestBody(nsFormData& aFormData) : mType(FormData)
|
||||
explicit RequestBody(mozilla::dom::FormData& aFormData) : mType(FormData)
|
||||
{
|
||||
mValue.mFormData = &aFormData;
|
||||
}
|
||||
@ -388,7 +388,7 @@ private:
|
||||
mozilla::dom::Blob* mBlob;
|
||||
nsIDocument* mDocument;
|
||||
const nsAString* mString;
|
||||
nsFormData* mFormData;
|
||||
mozilla::dom::FormData* mFormData;
|
||||
nsIInputStream* mStream;
|
||||
};
|
||||
|
||||
@ -467,7 +467,8 @@ public:
|
||||
aRv = Send(RequestBody(aString));
|
||||
}
|
||||
}
|
||||
void Send(JSContext* /*aCx*/, nsFormData& aFormData, ErrorResult& aRv)
|
||||
void Send(JSContext* /*aCx*/, mozilla::dom::FormData& aFormData,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv = Send(RequestBody(aFormData));
|
||||
}
|
||||
|
@ -529,10 +529,6 @@ DOMInterfaces = {
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'FormData': {
|
||||
'nativeType': 'nsFormData'
|
||||
},
|
||||
|
||||
'Geolocation': {
|
||||
'headerFile': 'nsGeolocation.h'
|
||||
},
|
||||
@ -1405,6 +1401,11 @@ DOMInterfaces = {
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
},
|
||||
|
||||
'WEBGL_compressed_texture_es3': {
|
||||
'nativeType': 'mozilla::WebGLExtensionCompressedTextureES3',
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
},
|
||||
|
||||
'WEBGL_compressed_texture_pvrtc': {
|
||||
'nativeType': 'mozilla::WebGLExtensionCompressedTexturePVRTC',
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
|
@ -190,6 +190,7 @@ class WebGLContext
|
||||
friend class WebGL2Context;
|
||||
friend class WebGLContextUserData;
|
||||
friend class WebGLExtensionCompressedTextureATC;
|
||||
friend class WebGLExtensionCompressedTextureES3;
|
||||
friend class WebGLExtensionCompressedTextureETC1;
|
||||
friend class WebGLExtensionCompressedTexturePVRTC;
|
||||
friend class WebGLExtensionCompressedTextureS3TC;
|
||||
|
@ -47,6 +47,7 @@ WebGLContext::GetExtensionString(WebGLExtensionID ext)
|
||||
WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object)
|
||||
WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float)
|
||||
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_atc)
|
||||
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_es3)
|
||||
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc1)
|
||||
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_pvrtc)
|
||||
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc)
|
||||
@ -199,6 +200,8 @@ WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
|
||||
switch (ext) {
|
||||
case WebGLExtensionID::EXT_disjoint_timer_query:
|
||||
return WebGLExtensionDisjointTimerQuery::IsSupported(this);
|
||||
case WebGLExtensionID::WEBGL_compressed_texture_es3:
|
||||
return gl->IsExtensionSupported(gl::GLContext::ARB_ES3_compatibility);
|
||||
|
||||
default:
|
||||
// For warnings-as-errors.
|
||||
@ -377,6 +380,9 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
|
||||
case WebGLExtensionID::WEBGL_compressed_texture_atc:
|
||||
obj = new WebGLExtensionCompressedTextureATC(this);
|
||||
break;
|
||||
case WebGLExtensionID::WEBGL_compressed_texture_es3:
|
||||
obj = new WebGLExtensionCompressedTextureES3(this);
|
||||
break;
|
||||
case WebGLExtensionID::WEBGL_compressed_texture_etc1:
|
||||
obj = new WebGLExtensionCompressedTextureETC1(this);
|
||||
break;
|
||||
|
55
dom/canvas/WebGLExtensionCompressedTextureES3.cpp
Normal file
55
dom/canvas/WebGLExtensionCompressedTextureES3.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/* 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 "WebGLExtensions.h"
|
||||
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#ifdef FOO
|
||||
#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
WebGLExtensionCompressedTextureES3::WebGLExtensionCompressedTextureES3(WebGLContext* webgl)
|
||||
: WebGLExtensionBase(webgl)
|
||||
{
|
||||
RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275
|
||||
const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) {
|
||||
auto& fua = webgl_->mFormatUsage;
|
||||
|
||||
auto usage = fua->EditUsage(effFormat);
|
||||
usage->isFilterable = true;
|
||||
fua->AllowSizedTexFormat(sizedFormat, usage);
|
||||
|
||||
webgl_->mCompressedTextureFormats.AppendElement(sizedFormat);
|
||||
};
|
||||
|
||||
#define FOO(x) LOCAL_GL_ ## x, webgl::EffectiveFormat::x
|
||||
|
||||
fnAdd(FOO(COMPRESSED_R11_EAC));
|
||||
fnAdd(FOO(COMPRESSED_SIGNED_R11_EAC));
|
||||
fnAdd(FOO(COMPRESSED_RG11_EAC));
|
||||
fnAdd(FOO(COMPRESSED_SIGNED_RG11_EAC));
|
||||
fnAdd(FOO(COMPRESSED_RGB8_ETC2));
|
||||
fnAdd(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2));
|
||||
fnAdd(FOO(COMPRESSED_RGBA8_ETC2_EAC));
|
||||
|
||||
// sRGB support is manadatory in GL 4.3 and GL ES 3.0, which are the only
|
||||
// versions to support ETC2.
|
||||
fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC));
|
||||
fnAdd(FOO(COMPRESSED_SRGB8_ETC2));
|
||||
fnAdd(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2));
|
||||
|
||||
#undef FOO
|
||||
}
|
||||
|
||||
WebGLExtensionCompressedTextureES3::~WebGLExtensionCompressedTextureES3()
|
||||
{
|
||||
}
|
||||
|
||||
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureES3, WEBGL_compressed_texture_es3)
|
||||
|
||||
} // namespace mozilla
|
@ -71,6 +71,16 @@ public:
|
||||
DECL_WEBGL_EXTENSION_GOOP
|
||||
};
|
||||
|
||||
class WebGLExtensionCompressedTextureES3
|
||||
: public WebGLExtensionBase
|
||||
{
|
||||
public:
|
||||
explicit WebGLExtensionCompressedTextureES3(WebGLContext*);
|
||||
virtual ~WebGLExtensionCompressedTextureES3();
|
||||
|
||||
DECL_WEBGL_EXTENSION_GOOP
|
||||
};
|
||||
|
||||
class WebGLExtensionCompressedTextureETC1
|
||||
: public WebGLExtensionBase
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
@ -154,6 +154,7 @@ enum class WebGLExtensionID : uint8_t {
|
||||
OES_vertex_array_object,
|
||||
WEBGL_color_buffer_float,
|
||||
WEBGL_compressed_texture_atc,
|
||||
WEBGL_compressed_texture_es3,
|
||||
WEBGL_compressed_texture_etc1,
|
||||
WEBGL_compressed_texture_pvrtc,
|
||||
WEBGL_compressed_texture_s3tc,
|
||||
|
@ -101,6 +101,7 @@ UNIFIED_SOURCES += [
|
||||
'WebGLExtensionColorBufferFloat.cpp',
|
||||
'WebGLExtensionColorBufferHalfFloat.cpp',
|
||||
'WebGLExtensionCompressedTextureATC.cpp',
|
||||
'WebGLExtensionCompressedTextureES3.cpp',
|
||||
'WebGLExtensionCompressedTextureETC1.cpp',
|
||||
'WebGLExtensionCompressedTexturePVRTC.cpp',
|
||||
'WebGLExtensionCompressedTextureS3TC.cpp',
|
||||
|
@ -4,6 +4,7 @@ skip-if = ((os == 'linux') && (buildapp == 'b2g'))
|
||||
|
||||
support-files =
|
||||
webgl-mochitest/driver-info.js
|
||||
webgl-mochitest/es3-data.js
|
||||
webgl-mochitest/webgl-util.js
|
||||
|
||||
[webgl-mochitest/test_backbuffer_channels.html]
|
||||
@ -34,6 +35,7 @@ skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests
|
||||
# We haven't cleaned up the Try results yet, but let's get this on the books first.
|
||||
[webgl-mochitest/test_webgl_conformance.html]
|
||||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
[webgl-mochitest/test_webgl_compressed_texture_es3.html]
|
||||
[webgl-mochitest/test_webgl_disjoint_timer_query.html]
|
||||
[webgl-mochitest/test_webgl_request_context.html]
|
||||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
|
4719
dom/canvas/test/webgl-mochitest/es3-data.js
Normal file
4719
dom/canvas/test/webgl-mochitest/es3-data.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,753 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<script src="webgl-util.js"></script>
|
||||
<script src="es3-data.js"></script>
|
||||
<title>WebGL test: test WEBGL_compressed_texture_es3 extension</title>
|
||||
<style>
|
||||
img {
|
||||
border: 1px solid black;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.testimages {
|
||||
}
|
||||
|
||||
.testimages br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.testimages > div {
|
||||
float: left;
|
||||
margin: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" width="8" height="8"></canvas>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
attribute vec2 texCoord0;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
texCoord = texCoord0;
|
||||
}
|
||||
</script>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform sampler2D tex;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
gl_FragData[0] = texture2D(tex, texCoord);
|
||||
}
|
||||
</script>
|
||||
<script id="fshader-r" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform sampler2D tex;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
vec4 pixel = (texture2D(tex, texCoord));
|
||||
pixel.r = (pixel.r + 1.0) / 2.0;
|
||||
gl_FragData[0] = pixel;
|
||||
}
|
||||
</script>
|
||||
<script id="fshader-rg" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform sampler2D tex;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
vec4 pixel = (texture2D(tex, texCoord));
|
||||
pixel.rg = (pixel.rg + 1.0) / 2.0;
|
||||
gl_FragData[0] = pixel;
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
var ext = null;
|
||||
var vao = null;
|
||||
var gl = null;
|
||||
var validFormats = {
|
||||
COMPRESSED_R11_EAC : 0x9270,
|
||||
COMPRESSED_SIGNED_R11_EAC : 0x9271,
|
||||
COMPRESSED_RG11_EAC : 0x9272,
|
||||
COMPRESSED_SIGNED_RG11_EAC : 0x9273,
|
||||
COMPRESSED_RGB8_ETC2 : 0x9274,
|
||||
COMPRESSED_SRGB8_ETC2 : 0x9275,
|
||||
COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9276,
|
||||
COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9277,
|
||||
COMPRESSED_RGBA8_ETC2_EAC : 0x9278,
|
||||
COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : 0x9279,
|
||||
};
|
||||
var name;
|
||||
var supportedFormats;
|
||||
|
||||
function setupUnitQuad() {
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, -1.0, 0.0]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
1.0, 1.0,
|
||||
0.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(1);
|
||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
gl = WebGLUtil.getWebGL("canvas", false, {antialias: false});
|
||||
if (!gl) {
|
||||
ok(false, "WebGL context does not exist");
|
||||
} else {
|
||||
ok(true, "WebGL context exists");
|
||||
setupUnitQuad();
|
||||
|
||||
// Run tests with extension disabled
|
||||
runTestDisabled();
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("WEBGL_compressed_texture_es3");
|
||||
if (!ext) {
|
||||
ok(true, "No WEBGL_compressed_texture_es3 support -- this is legal");
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
ok(true, "Successfully enabled WEBGL_compressed_texture_es3 extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
runTestExtension();
|
||||
}
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("WEBGL_compressed_texture_es3") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
ok(true, "WEBGL_compressed_texture_es3 listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
ok(false, "WEBGL_compressed_texture_es3 listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
ok(false, "WEBGL_compressed_texture_es3 not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
ok(true, "WEBGL_compressed_texture_es3 not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runTestDisabled() {
|
||||
is(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS).length, 0,
|
||||
"Should be no compressed texture formats");
|
||||
}
|
||||
|
||||
function formatExists(format, supportedFormats) {
|
||||
for (var ii = 0; ii < supportedFormats.length; ++ii) {
|
||||
if (format == supportedFormats[ii]) {
|
||||
ok(true, "supported format " + formatToString(format) + " is exists");
|
||||
return;
|
||||
}
|
||||
}
|
||||
ok(false, "supported format " + formatToString(format) + " does not exist");
|
||||
}
|
||||
|
||||
function formatToString(format) {
|
||||
for (var p in ext) {
|
||||
if (ext[p] == format) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return "0x" + format.toString(16);
|
||||
}
|
||||
|
||||
function runTestExtension() {
|
||||
// check that all format enums exist.
|
||||
for (name in validFormats) {
|
||||
is(ext[name], validFormats[name], "format is match");
|
||||
}
|
||||
|
||||
supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
|
||||
// There should be exactly 10 formats
|
||||
is(supportedFormats.length, 10, "Should be exactly 10 formats");
|
||||
|
||||
// check that all 10 formats exist
|
||||
for (var name in validFormats.length) {
|
||||
formatExists(validFormats[name], supportedFormats);
|
||||
}
|
||||
|
||||
// Test each format
|
||||
testETC2_RGB();
|
||||
}
|
||||
|
||||
function testETC2_RGB() {
|
||||
var tests = [
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 1,
|
||||
data: img_4x4_r11_eac,
|
||||
format: ext.COMPRESSED_R11_EAC
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 1,
|
||||
data: img_4x4_signed_r11_eac,
|
||||
format: ext.COMPRESSED_SIGNED_R11_EAC
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 2,
|
||||
data: img_4x4_rg11_eac,
|
||||
format: ext.COMPRESSED_RG11_EAC
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 2,
|
||||
data: img_4x4_signed_rg11_eac,
|
||||
format: ext.COMPRESSED_SIGNED_RG11_EAC
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 3,
|
||||
data: img_4x4_rgb_etc2,
|
||||
format: ext.COMPRESSED_RGB8_ETC2
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 3,
|
||||
data: img_4x4_rgb_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_ETC2
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 4,
|
||||
data: img_4x4_rgb_punchthrough_etc2,
|
||||
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 4,
|
||||
data: img_4x4_rgb_punchthrough_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 4,
|
||||
data: img_4x4_rgba_etc2,
|
||||
format: ext.COMPRESSED_RGBA8_ETC2_EAC
|
||||
},
|
||||
{
|
||||
width: 4,
|
||||
height: 4,
|
||||
channels: 4,
|
||||
data: img_4x4_rgba_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 1,
|
||||
data: img_8x8_r11_eac,
|
||||
format: ext.COMPRESSED_R11_EAC
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 1,
|
||||
data: img_8x8_signed_r11_eac,
|
||||
format: ext.COMPRESSED_SIGNED_R11_EAC
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 2,
|
||||
data: img_8x8_rg11_eac,
|
||||
format: ext.COMPRESSED_RG11_EAC
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 2,
|
||||
data: img_8x8_signed_rg11_eac,
|
||||
format: ext.COMPRESSED_SIGNED_RG11_EAC
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 3,
|
||||
data: img_8x8_rgb_etc2,
|
||||
format: ext.COMPRESSED_RGB8_ETC2
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 3,
|
||||
data: img_8x8_rgb_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_ETC2
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgb_punchthrough_etc2,
|
||||
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgb_punchthrough_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgba_etc2,
|
||||
format: ext.COMPRESSED_RGBA8_ETC2_EAC
|
||||
},
|
||||
{
|
||||
width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgba_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 1,
|
||||
data: img_32x32_r11_eac,
|
||||
format: ext.COMPRESSED_R11_EAC
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 1,
|
||||
data: img_32x32_signed_r11_eac,
|
||||
format: ext.COMPRESSED_SIGNED_R11_EAC
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 2,
|
||||
data: img_32x32_rg11_eac,
|
||||
format: ext.COMPRESSED_RG11_EAC
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 2,
|
||||
data: img_32x32_signed_rg11_eac,
|
||||
format: ext.COMPRESSED_SIGNED_RG11_EAC
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 3,
|
||||
data: img_32x32_rgb_etc2,
|
||||
format: ext.COMPRESSED_RGB8_ETC2
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 3,
|
||||
data: img_32x32_rgb_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_ETC2
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 4,
|
||||
data: img_32x32_rgb_punchthrough_etc2,
|
||||
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 4,
|
||||
data: img_32x32_rgb_punchthrough_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 4,
|
||||
data: img_32x32_rgba_etc2,
|
||||
format: ext.COMPRESSED_RGBA8_ETC2_EAC
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 32,
|
||||
channels: 4,
|
||||
data: img_32x32_rgba_etc2,
|
||||
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
|
||||
},
|
||||
];
|
||||
testETCTextures(tests);
|
||||
}
|
||||
|
||||
function testETCTextures(tests) {
|
||||
for (var ii = 0; ii < tests.length; ++ii) {
|
||||
testETCTexture(tests[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the size of block in bytes */
|
||||
function getBlockSize(format) {
|
||||
switch (format) {
|
||||
case ext.COMPRESSED_R11_EAC:
|
||||
case ext.COMPRESSED_SIGNED_R11_EAC:
|
||||
case ext.COMPRESSED_RGB8_ETC2:
|
||||
case ext.COMPRESSED_SRGB8_ETC2:
|
||||
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||||
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||||
return 8;
|
||||
case ext.COMPRESSED_RG11_EAC:
|
||||
case ext.COMPRESSED_SIGNED_RG11_EAC:
|
||||
case ext.COMPRESSED_RGBA8_ETC2_EAC:
|
||||
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||||
return 16
|
||||
}
|
||||
}
|
||||
|
||||
function copyRect(data, srcX, srcY, dstX, dstY, width, height, stride) {
|
||||
var bytesPerLine = width * 4;
|
||||
var srcOffset = srcX * 4 + srcY * stride;
|
||||
var dstOffset = dstX * 4 + dstY * stride;
|
||||
for (var jj = height; jj > 0; --jj) {
|
||||
for (var ii = 0; ii < bytesPerLine; ++ii) {
|
||||
data[dstOffset + ii] = data[srcOffset + ii];
|
||||
}
|
||||
srcOffset += stride;
|
||||
dstOffset += stride;
|
||||
}
|
||||
}
|
||||
|
||||
function testETCTexture(test) {
|
||||
var data = new Uint8Array(test.data.compressed);
|
||||
var width = test.width;
|
||||
var height = test.height;
|
||||
var format = test.format;
|
||||
|
||||
var uncompressedData = new Uint8Array(test.data.decompressed);
|
||||
var glErrorShouldBe = (gl, glError, msg) => {
|
||||
msg = msg || "";
|
||||
var err = gl.getError();
|
||||
var getGLErrorAsString = err => {
|
||||
if (err === gl.NO_ERROR) {
|
||||
return "NO_ERROR";
|
||||
}
|
||||
for (var name in gl) {
|
||||
if (gl[name] === err) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return err.toString();
|
||||
}
|
||||
|
||||
if (err != glError) {
|
||||
ok(false, "getError expected: " + getGLErrorAsString(glError) +
|
||||
". Was " + getGLErrorAsString(err) + " : " + msg);
|
||||
} else {
|
||||
ok(true, "getError was expected value: " +
|
||||
getGLErrorAsString(glError) + " : " + msg);
|
||||
}
|
||||
};
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
gl.viewport(0, 0, width, height);
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||||
gl.generateMipmap(gl.TEXTURE_2D);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
|
||||
if (format == ext.COMPRESSED_SIGNED_R11_EAC) {
|
||||
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-r');
|
||||
} else if (format == ext.COMPRESSED_SIGNED_RG11_EAC) {
|
||||
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-rg');
|
||||
} else {
|
||||
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader');
|
||||
}
|
||||
gl.bindAttribLocation(program, 0, 'vPosition');
|
||||
gl.bindAttribLocation(program, 1, 'texCoord0');
|
||||
gl.useProgram(program);
|
||||
|
||||
gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
|
||||
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border");
|
||||
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width + 4, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height + 4, 0, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 4, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 4, 0, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||||
|
||||
if (width == 4) {
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||||
}
|
||||
if (height == 4) {
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||||
}
|
||||
|
||||
// pick a wrong format that uses the same amount of data.
|
||||
var wrongFormat;
|
||||
switch (format) {
|
||||
case ext.COMPRESSED_R11_EAC:
|
||||
wrongFormat = ext.COMPRESSED_SIGNED_R11_EAC;
|
||||
break;
|
||||
case ext.COMPRESSED_SIGNED_R11_EAC:
|
||||
wrongFormat = ext.COMPRESSED_R11_EAC;
|
||||
break;
|
||||
case ext.COMPRESSED_RG11_EAC:
|
||||
wrongFormat = ext.COMPRESSED_SIGNED_RG11_EAC;
|
||||
break;
|
||||
case ext.COMPRESSED_SIGNED_RG11_EAC:
|
||||
wrongFormat = ext.COMPRESSED_RG11_EAC;
|
||||
break;
|
||||
case ext.COMPRESSED_RGB8_ETC2:
|
||||
wrongFormat = ext.COMPRESSED_SRGB8_ETC2;
|
||||
break;
|
||||
case ext.COMPRESSED_SRGB8_ETC2:
|
||||
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
|
||||
break;
|
||||
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||||
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
|
||||
break;
|
||||
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||||
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
|
||||
break;
|
||||
case ext.COMPRESSED_RGBA8_ETC2_EAC:
|
||||
wrongFormat = ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
|
||||
break;
|
||||
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||||
wrongFormat = ext.COMPRESSED_RGBA8_ETC2_EAC;
|
||||
break;
|
||||
}
|
||||
|
||||
// Restore original texture.
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||||
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "format does not match");
|
||||
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width + 4, height, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height + 4, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 4, height, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 4, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||||
|
||||
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 1, height, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 2, height, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 1, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 2, format, data);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||||
|
||||
var subData = new Uint8Array(data.buffer, 0, getBlockSize(format));
|
||||
|
||||
if (width == 8 && height == 8) {
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 0, 4, 4, format, subData);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 4, 4, format, subData);
|
||||
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
|
||||
}
|
||||
|
||||
if (width < 32 && height < 32) {
|
||||
var stride = width * 4;
|
||||
for (var yoff = 0; yoff < height; yoff += 4) {
|
||||
for (var xoff = 0; xoff < width; xoff += 4) {
|
||||
copyRect(uncompressedData, 0, 0, xoff, yoff, 4, 4, stride);
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, xoff, yoff, 4, 4, format, subData);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||||
gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function insertImg(element, caption, img) {
|
||||
var div = document.createElement("div");
|
||||
div.appendChild(img);
|
||||
var label = document.createElement("div");
|
||||
label.appendChild(document.createTextNode(caption));
|
||||
div.appendChild(label);
|
||||
element.appendChild(div);
|
||||
}
|
||||
|
||||
function convertToSRGB(val) {
|
||||
var norm = val / 255.0;
|
||||
var res = 0;
|
||||
if (norm <= 0.04045) {
|
||||
res = norm / 12.92;
|
||||
} else {
|
||||
res = Math.pow(((norm + 0.055)/1.055), 2.4);
|
||||
}
|
||||
|
||||
return res * 255.0;
|
||||
}
|
||||
|
||||
function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) {
|
||||
var scale = 8;
|
||||
var c = document.createElement("canvas");
|
||||
c.width = imageWidth * scale;
|
||||
c.height = imageHeight * scale;
|
||||
var ctx = c.getContext("2d");
|
||||
for (var yy = 0; yy < imageHeight; ++yy) {
|
||||
for (var xx = 0; xx < imageWidth; ++xx) {
|
||||
var offset = (yy * dataWidth + xx) * 4;
|
||||
ctx.fillStyle = "rgba(" +
|
||||
data[offset + 0] + "," +
|
||||
data[offset + 1] + "," +
|
||||
data[offset + 2] + "," +
|
||||
(alpha ? data[offset + 3] / 255 : 1) + ")";
|
||||
ctx.fillRect(xx * scale, yy * scale, scale, scale);
|
||||
}
|
||||
}
|
||||
var img = document.createElement("img");
|
||||
img.src = c.toDataURL();
|
||||
return img;
|
||||
}
|
||||
|
||||
function compareRect(actualWidth, actualHeight, actualChannels,
|
||||
dataWidth, dataHeight, expectedData,
|
||||
testData, testFormat)
|
||||
{
|
||||
var actual = new Uint8Array(actualWidth * actualHeight * 4);
|
||||
gl.readPixels(
|
||||
0, 0, actualWidth, actualHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
|
||||
|
||||
var div = document.createElement("div");
|
||||
div.className = "testimages";
|
||||
var hasAlpha = actualChannels == 4;
|
||||
var imgExpected = makeImage(actualWidth, actualHeight, dataWidth, expectedData, hasAlpha);
|
||||
var imgActual = makeImage(actualWidth, actualHeight, actualWidth, actual, hasAlpha);
|
||||
insertImg(div, "expected", imgExpected);
|
||||
insertImg(div, "actual", imgActual);
|
||||
div.appendChild(document.createElement('br'));
|
||||
document.getElementById("console").appendChild(div);
|
||||
|
||||
var failed = false;
|
||||
for (var yy = 0; yy < actualHeight; ++yy) {
|
||||
for (var xx = 0; xx < actualWidth; ++xx) {
|
||||
var actualOffset = (yy * actualWidth + xx) * 4;
|
||||
var expectedOffset = (yy * dataWidth + xx) * 4;
|
||||
var expected = expectedData.slice(expectedOffset, expectedOffset + 4);
|
||||
|
||||
var maxDiffPixel = 0;
|
||||
switch (testFormat) {
|
||||
case ext.COMPRESSED_SRGB8_ETC2:
|
||||
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||||
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||||
|
||||
// Alpha shouldn't do conversion.
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
expected[i] = convertToSRGB(expected[i]);
|
||||
}
|
||||
//fallthrough
|
||||
case ext.COMPRESSED_R11_EAC:
|
||||
case ext.COMPRESSED_RG11_EAC:
|
||||
case ext.COMPRESSED_SIGNED_R11_EAC:
|
||||
case ext.COMPRESSED_SIGNED_RG11_EAC:
|
||||
// Due to floating round error, we need fuzzy test here.
|
||||
var maxDiffPixel = 1;
|
||||
break;
|
||||
default:
|
||||
var maxDiffPixel = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (var channel = 0; channel < actualChannels; ++channel) {
|
||||
var diff = Math.abs(expected[channel] - actual[actualOffset + channel]);
|
||||
|
||||
if (diff > maxDiffPixel) {
|
||||
failed = true;
|
||||
var was = actual.slice(actualOffset, actualOffset + 4).join();
|
||||
ok(false, 'at (' + xx + ', ' + yy +
|
||||
') expected: ' + expected.join() + ' was ' + was);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!failed) {
|
||||
ok(true, "texture rendered correctly");
|
||||
}
|
||||
}
|
||||
|
||||
var prefArrArr = [
|
||||
['webgl.enable-draft-extensions', true],
|
||||
];
|
||||
var prefEnv = {'set': prefArrArr};
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(prefEnv, runTest);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -3167,10 +3167,15 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
if (pluginFrame) {
|
||||
MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
|
||||
action = WheelPrefs::ACTION_SEND_TO_PLUGIN;
|
||||
} else if (nsLayoutUtils::IsScrollFrameWithSnapping(frameToScroll)) {
|
||||
} else if (!wheelEvent->mayHaveMomentum &&
|
||||
nsLayoutUtils::IsScrollFrameWithSnapping(frameToScroll)) {
|
||||
// If the target has scroll-snapping points then we want to handle
|
||||
// the wheel event on the main thread even if we have APZ enabled. Do
|
||||
// so and let the APZ know that it should ignore this event.
|
||||
// so and let the APZ know that it should ignore this event. However,
|
||||
// if the wheel event is synthesized from a Mac trackpad or other device
|
||||
// that can generate additional momentum events, then we should allow
|
||||
// APZ to handle it, because it will track the velocity and predicted
|
||||
// destination from the momentum.
|
||||
if (wheelEvent->mFlags.mHandledByAPZ) {
|
||||
wheelEvent->mFlags.mDefaultPrevented = true;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
#include "mozilla/dom/FetchDriver.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FormData.h"
|
||||
#include "mozilla/dom/Headers.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/PromiseWorkerProxy.h"
|
||||
@ -37,7 +38,6 @@
|
||||
#include "InternalRequest.h"
|
||||
#include "InternalResponse.h"
|
||||
|
||||
#include "nsFormData.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "WorkerScope.h"
|
||||
@ -393,7 +393,7 @@ ExtractFromBlob(const Blob& aBlob, nsIInputStream** aStream,
|
||||
}
|
||||
|
||||
nsresult
|
||||
ExtractFromFormData(nsFormData& aFormData, nsIInputStream** aStream,
|
||||
ExtractFromFormData(FormData& aFormData, nsIInputStream** aStream,
|
||||
nsCString& aContentType)
|
||||
{
|
||||
uint64_t unusedContentLength;
|
||||
@ -468,7 +468,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDa
|
||||
const Blob& blob = aBodyInit.GetAsBlob();
|
||||
return ExtractFromBlob(blob, aStream, aContentType);
|
||||
} else if (aBodyInit.IsFormData()) {
|
||||
nsFormData& form = aBodyInit.GetAsFormData();
|
||||
FormData& form = aBodyInit.GetAsFormData();
|
||||
return ExtractFromFormData(form, aStream, aContentType);
|
||||
} else if (aBodyInit.IsUSVString()) {
|
||||
nsAutoString str;
|
||||
@ -500,7 +500,7 @@ ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUS
|
||||
const Blob& blob = aBodyInit.GetAsBlob();
|
||||
return ExtractFromBlob(blob, aStream, aContentType);
|
||||
} else if (aBodyInit.IsFormData()) {
|
||||
nsFormData& form = aBodyInit.GetAsFormData();
|
||||
FormData& form = aBodyInit.GetAsFormData();
|
||||
return ExtractFromFormData(form, aStream, aContentType);
|
||||
} else if (aBodyInit.IsUSVString()) {
|
||||
nsAutoString str;
|
||||
@ -1039,7 +1039,7 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
|
||||
data.Adopt(reinterpret_cast<char*>(aResult), aResultLength);
|
||||
autoFree.Reset();
|
||||
|
||||
RefPtr<nsFormData> fd = FetchUtil::ConsumeFormData(
|
||||
RefPtr<dom::FormData> fd = FetchUtil::ConsumeFormData(
|
||||
DerivedClass()->GetParentObject(),
|
||||
mMimeType, data, error);
|
||||
if (!error.Failed()) {
|
||||
|
@ -194,7 +194,7 @@ class MOZ_STACK_CLASS FillFormIterator final
|
||||
: public URLSearchParams::ForEachIterator
|
||||
{
|
||||
public:
|
||||
explicit FillFormIterator(nsFormData* aFormData)
|
||||
explicit FillFormIterator(FormData* aFormData)
|
||||
: mFormData(aFormData)
|
||||
{
|
||||
MOZ_ASSERT(aFormData);
|
||||
@ -210,7 +210,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
nsFormData* mFormData;
|
||||
FormData* mFormData;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -224,7 +224,7 @@ private:
|
||||
* never return a partially filled FormData.
|
||||
* The content-disposition header is used to figure out the name and filename
|
||||
* entries. The inclusion of the filename parameter decides if the entry is
|
||||
* inserted into the nsFormData as a string or a File.
|
||||
* inserted into the FormData as a string or a File.
|
||||
*
|
||||
* File blobs are copies of the underlying data string since we cannot adopt
|
||||
* char* chunks embedded within the larger body without significant effort.
|
||||
@ -235,7 +235,7 @@ private:
|
||||
class MOZ_STACK_CLASS FormDataParser
|
||||
{
|
||||
private:
|
||||
RefPtr<nsFormData> mFormData;
|
||||
RefPtr<FormData> mFormData;
|
||||
nsCString mMimeType;
|
||||
nsCString mData;
|
||||
|
||||
@ -388,7 +388,7 @@ private:
|
||||
aStart.advance(2);
|
||||
|
||||
if (!mFormData) {
|
||||
mFormData = new nsFormData();
|
||||
mFormData = new FormData();
|
||||
}
|
||||
|
||||
NS_ConvertUTF8toUTF16 name(mName);
|
||||
@ -488,7 +488,7 @@ public:
|
||||
if (start != end && *start == '-') {
|
||||
// End of data.
|
||||
if (!mFormData) {
|
||||
mFormData = new nsFormData();
|
||||
mFormData = new FormData();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -535,7 +535,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<nsFormData> FormData()
|
||||
already_AddRefed<FormData> GetFormData()
|
||||
{
|
||||
return mFormData.forget();
|
||||
}
|
||||
@ -543,7 +543,7 @@ public:
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsFormData>
|
||||
already_AddRefed<FormData>
|
||||
FetchUtil::ConsumeFormData(nsIGlobalObject* aParent, const nsCString& aMimeType,
|
||||
const nsCString& aStr, ErrorResult& aRv)
|
||||
{
|
||||
@ -564,7 +564,7 @@ FetchUtil::ConsumeFormData(nsIGlobalObject* aParent, const nsCString& aMimeType,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<nsFormData> fd = parser.FormData();
|
||||
RefPtr<FormData> fd = parser.GetFormData();
|
||||
MOZ_ASSERT(fd);
|
||||
return fd.forget();
|
||||
}
|
||||
@ -580,7 +580,7 @@ FetchUtil::ConsumeFormData(nsIGlobalObject* aParent, const nsCString& aMimeType,
|
||||
URLParams params;
|
||||
params.ParseInput(aStr);
|
||||
|
||||
RefPtr<nsFormData> fd = new nsFormData(aParent);
|
||||
RefPtr<FormData> fd = new FormData(aParent);
|
||||
FillFormIterator iterator(fd);
|
||||
DebugOnly<bool> status = params.ForEach(iterator);
|
||||
MOZ_ASSERT(status);
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsError.h"
|
||||
#include "nsFormData.h"
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FormData.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -47,7 +47,7 @@ public:
|
||||
* Creates a form data object from a UTF-8 encoded |aStr|. Returns |nullptr|
|
||||
* and sets |aRv| to MSG_BAD_FORMDATA if |aStr| contains invalid data.
|
||||
*/
|
||||
static already_AddRefed<nsFormData>
|
||||
static already_AddRefed<FormData>
|
||||
ConsumeFormData(nsIGlobalObject* aParent, const nsCString& aMimeType,
|
||||
const nsCString& aStr, ErrorResult& aRv);
|
||||
|
||||
|
@ -93,7 +93,7 @@ class Gamepad {
|
||||
// Index given by our superclass.
|
||||
uint32_t mSuperIndex;
|
||||
|
||||
const bool isDpad(IOHIDElementRef element) const
|
||||
bool isDpad(IOHIDElementRef element) const
|
||||
{
|
||||
return element == mDpad;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "nsQueryObject.h"
|
||||
|
||||
// form submission
|
||||
#include "mozilla/dom/FormData.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsIFormSubmitObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
@ -49,7 +50,6 @@
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsFormSubmissionConstants.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsISecurityUITelemetry.h"
|
||||
|
@ -103,7 +103,7 @@ InputPortData::GetId() const
|
||||
return mId;
|
||||
}
|
||||
|
||||
const InputPortType
|
||||
InputPortType
|
||||
InputPortData::GetType() const
|
||||
{
|
||||
return ToInputPortType(mType);
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
|
||||
const nsString& GetId() const;
|
||||
|
||||
const InputPortType GetType() const;
|
||||
InputPortType GetType() const;
|
||||
|
||||
private:
|
||||
~InputPortData();
|
||||
|
@ -124,7 +124,7 @@ PluginHangUIMessage=%S may be busy, or it may have stopped responding. You can s
|
||||
PluginHangUIWaitButton=Continue
|
||||
PluginHangUIStopButton=Stop plugin
|
||||
# LOCALIZATION NOTE: Do not translate "mozHidden", "mozVisibilityState", "hidden", or "visibilityState"
|
||||
PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
|
||||
PrefixedVisibilityAPIWarning='mozHidden' and 'mozVisibilityState' are deprecated. Please use the unprefixed 'hidden' and 'visibilityState' instead.
|
||||
# LOCALIZATION NOTE: Do not translate "NodeIterator" or "detach()".
|
||||
NodeIteratorDetachWarning=Calling detach() on a NodeIterator no longer has an effect.
|
||||
# LOCALIZATION NOTE: Do not translate "LenientThis" and "this"
|
||||
|
@ -78,6 +78,9 @@
|
||||
#endif
|
||||
#if defined (XP_WIN)
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <tchar.h>
|
||||
#endif
|
||||
|
||||
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
|
||||
@ -1640,6 +1643,28 @@ MediaManager::GetNonE10sParent()
|
||||
return mNonE10sParent;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
MediaManager::StartupInit()
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (IsVistaOrLater() && !IsWin8OrLater()) {
|
||||
// Bug 1107702 - Older Windows fail in GetAdaptersInfo (and others) if the
|
||||
// first(?) call occurs after the process size is over 2GB (kb/2588507).
|
||||
// Attempt to 'prime' the pump by making a call at startup.
|
||||
unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
|
||||
PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
|
||||
if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(pAdapterInfo);
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
|
||||
GetAdaptersInfo(pAdapterInfo, &out_buf_len);
|
||||
}
|
||||
if (pAdapterInfo) {
|
||||
free(pAdapterInfo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
MediaManager::PostTask(const tracked_objects::Location& from_here, Task* task)
|
||||
|
@ -415,6 +415,7 @@ public:
|
||||
// from MediaManager thread.
|
||||
static MediaManager* Get();
|
||||
static MediaManager* GetIfExists();
|
||||
static void StartupInit();
|
||||
static void PostTask(const tracked_objects::Location& from_here, Task* task);
|
||||
#ifdef DEBUG
|
||||
static bool IsInMediaThread();
|
||||
|
@ -17,7 +17,7 @@ class AndroidMediaDecoder : public MediaDecoder
|
||||
public:
|
||||
AndroidMediaDecoder(MediaDecoderOwner* aOwner, const nsACString& aType);
|
||||
|
||||
const nsresult GetContentType(nsACString& aType) const {
|
||||
nsresult GetContentType(nsACString& aType) const {
|
||||
aType = mType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ static const int DEFAULT_SAMPLING_RATE = 16000;
|
||||
static const int DEFAULT_FRAME_WIDTH = 640;
|
||||
static const int DEFAULT_FRAME_HEIGHT = 480;
|
||||
static const int DEFAULT_TRACK_RATE = USECS_PER_S;
|
||||
// 30 seconds threshold if the encoder still can't not be initialized.
|
||||
static const int INIT_FAILED_DURATION = 30;
|
||||
|
||||
TrackEncoder::TrackEncoder()
|
||||
: mReentrantMonitor("media.TrackEncoder")
|
||||
@ -34,8 +36,8 @@ TrackEncoder::TrackEncoder()
|
||||
, mInitialized(false)
|
||||
, mEndOfStream(false)
|
||||
, mCanceled(false)
|
||||
, mAudioInitCounter(0)
|
||||
, mVideoInitCounter(0)
|
||||
, mInitCounter(0)
|
||||
, mNotInitDuration(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -54,8 +56,8 @@ AudioTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
|
||||
|
||||
// Check and initialize parameters for codec encoder.
|
||||
if (!mInitialized) {
|
||||
mAudioInitCounter++;
|
||||
TRACK_LOG(LogLevel::Debug, ("Init the audio encoder %d times", mAudioInitCounter));
|
||||
mInitCounter++;
|
||||
TRACK_LOG(LogLevel::Debug, ("Init the audio encoder %d times", mInitCounter));
|
||||
AudioSegment::ChunkIterator iter(const_cast<AudioSegment&>(audio));
|
||||
while (!iter.IsEnded()) {
|
||||
AudioChunk chunk = *iter;
|
||||
@ -73,6 +75,15 @@ AudioTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
|
||||
|
||||
iter.Next();
|
||||
}
|
||||
|
||||
mNotInitDuration += aQueuedMedia.GetDuration();
|
||||
if (!mInitialized &&
|
||||
(mNotInitDuration / aGraph->GraphRate() > INIT_FAILED_DURATION) &&
|
||||
mInitCounter > 1) {
|
||||
LOG("[AudioTrackEncoder]: Initialize failed for 30s.");
|
||||
NotifyEndOfStream();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Append and consume this raw segment.
|
||||
@ -187,8 +198,8 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
|
||||
|
||||
// Check and initialize parameters for codec encoder.
|
||||
if (!mInitialized) {
|
||||
mVideoInitCounter++;
|
||||
TRACK_LOG(LogLevel::Debug, ("Init the video encoder %d times", mVideoInitCounter));
|
||||
mInitCounter++;
|
||||
TRACK_LOG(LogLevel::Debug, ("Init the video encoder %d times", mInitCounter));
|
||||
VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(video));
|
||||
while (!iter.IsEnded()) {
|
||||
VideoChunk chunk = *iter;
|
||||
@ -207,6 +218,15 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
|
||||
|
||||
iter.Next();
|
||||
}
|
||||
|
||||
mNotInitDuration += aQueuedMedia.GetDuration();
|
||||
if (!mInitialized &&
|
||||
(mNotInitDuration / aGraph->GraphRate() > INIT_FAILED_DURATION) &&
|
||||
mInitCounter > 1) {
|
||||
LOG("[VideoTrackEncoder]: Initialize failed for 30s.");
|
||||
NotifyEndOfStream();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AppendVideoSegment(video);
|
||||
|
@ -132,8 +132,8 @@ protected:
|
||||
bool mCanceled;
|
||||
|
||||
// How many times we have tried to initialize the encoder.
|
||||
uint32_t mAudioInitCounter;
|
||||
uint32_t mVideoInitCounter;
|
||||
uint32_t mInitCounter;
|
||||
StreamTime mNotInitDuration;
|
||||
};
|
||||
|
||||
class AudioTrackEncoder : public TrackEncoder
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
{
|
||||
mPluginId = aPluginId;
|
||||
}
|
||||
const uint32_t GetPluginId()
|
||||
uint32_t GetPluginId() const
|
||||
{
|
||||
return mPluginId;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
|
||||
// GMPDecryptorProxy
|
||||
|
||||
virtual const uint32_t GetPluginId() const override { return mPluginId; }
|
||||
virtual uint32_t GetPluginId() const override { return mPluginId; }
|
||||
|
||||
virtual nsresult Init(GMPDecryptorProxyCallback* aCallback) override;
|
||||
|
||||
|
@ -59,7 +59,7 @@ class GMPDecryptorProxy {
|
||||
public:
|
||||
~GMPDecryptorProxy() {}
|
||||
|
||||
virtual const uint32_t GetPluginId() const = 0;
|
||||
virtual uint32_t GetPluginId() const = 0;
|
||||
|
||||
virtual nsresult Init(GMPDecryptorProxyCallback* aCallback) = 0;
|
||||
|
||||
|
@ -99,7 +99,7 @@ GMPStringListImpl::GMPStringListImpl(const nsTArray<nsCString>& aStrings)
|
||||
{
|
||||
}
|
||||
|
||||
const uint32_t
|
||||
uint32_t
|
||||
GMPStringListImpl::Size() const
|
||||
{
|
||||
return mStrings.Length();
|
||||
|
@ -19,7 +19,7 @@ class GMPStringListImpl : public GMPStringList
|
||||
{
|
||||
public:
|
||||
explicit GMPStringListImpl(const nsTArray<nsCString>& aStrings);
|
||||
virtual const uint32_t Size() const override;
|
||||
virtual uint32_t Size() const override;
|
||||
virtual void StringAt(uint32_t aIndex,
|
||||
const char** aOutString, uint32_t *aOutLength) const override;
|
||||
virtual ~GMPStringListImpl() override;
|
||||
|
@ -936,7 +936,7 @@ GMPParent::GetVersion() const
|
||||
return mVersion;
|
||||
}
|
||||
|
||||
const uint32_t
|
||||
uint32_t
|
||||
GMPParent::GetPluginId() const
|
||||
{
|
||||
return mPluginId;
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
|
||||
const nsCString& GetDisplayName() const;
|
||||
const nsCString& GetVersion() const;
|
||||
const uint32_t GetPluginId() const;
|
||||
uint32_t GetPluginId() const;
|
||||
nsString GetPluginBaseName() const;
|
||||
|
||||
// Returns true if a plugin can be or is being used across multiple NodeIds.
|
||||
|
@ -105,7 +105,7 @@ protected:
|
||||
nsIDocument* aDocument);
|
||||
void Run(const nsACString& aPluginName);
|
||||
bool IsStillValid();
|
||||
const uint32_t GetPluginId() const { return mPluginId; }
|
||||
uint32_t GetPluginId() const { return mPluginId; }
|
||||
private:
|
||||
virtual ~GMPCrashCallback() { MOZ_ASSERT(NS_IsMainThread()); }
|
||||
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
int64_t aRenderTimeMs = -1) override;
|
||||
virtual nsresult Reset() override;
|
||||
virtual nsresult Drain() override;
|
||||
virtual const uint32_t GetPluginId() const override { return mPluginId; }
|
||||
virtual uint32_t GetPluginId() const override { return mPluginId; }
|
||||
virtual const nsCString& GetDisplayName() const override;
|
||||
|
||||
// GMPSharedMemManager
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
int64_t aRenderTimeMs = -1) = 0;
|
||||
virtual nsresult Reset() = 0;
|
||||
virtual nsresult Drain() = 0;
|
||||
virtual const uint32_t GetPluginId() const = 0;
|
||||
virtual uint32_t GetPluginId() const = 0;
|
||||
|
||||
// Call to tell GMP/plugin the consumer will no longer use this
|
||||
// interface/codec.
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) override;
|
||||
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) override;
|
||||
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) override;
|
||||
virtual const uint32_t GetPluginId() const override { return mPluginId; }
|
||||
virtual uint32_t GetPluginId() const override { return mPluginId; }
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem) override
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
|
||||
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
|
||||
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
|
||||
virtual const uint32_t GetPluginId() const = 0;
|
||||
virtual uint32_t GetPluginId() const = 0;
|
||||
|
||||
// Call to tell GMP/plugin the consumer will no longer use this
|
||||
// interface/codec.
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
class GMPStringList {
|
||||
public:
|
||||
virtual const uint32_t Size() const = 0;
|
||||
virtual uint32_t Size() const = 0;
|
||||
|
||||
virtual void StringAt(uint32_t aIndex,
|
||||
const char** aOutString, uint32_t* aOutLength) const = 0;
|
||||
|
@ -805,7 +805,7 @@ public:
|
||||
private:
|
||||
uint8_t* GetPointer() { return mData + mOffset; }
|
||||
|
||||
const size_t AvailableSize() { return mCapicity - mOffset; }
|
||||
size_t AvailableSize() const { return mCapicity - mOffset; }
|
||||
|
||||
void IncreaseOffset(size_t aValue)
|
||||
{
|
||||
@ -814,12 +814,12 @@ private:
|
||||
mOffset += aValue;
|
||||
}
|
||||
|
||||
bool IsEmpty()
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return (mOffset == 0);
|
||||
}
|
||||
|
||||
const size_t GetCapacity()
|
||||
size_t GetCapacity() const
|
||||
{
|
||||
return mCapicity;
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ AudioNodeStream::Create(AudioContext* aCtx, AudioNodeEngine* aEngine,
|
||||
// MediaRecorders use an AudioNodeStream, but no AudioNode
|
||||
AudioNode* node = aEngine->NodeMainThread();
|
||||
MediaStreamGraph* graph = aGraph ? aGraph : aCtx->Graph();
|
||||
MOZ_ASSERT(graph->GraphRate() == aCtx->SampleRate());
|
||||
|
||||
RefPtr<AudioNodeStream> stream =
|
||||
new AudioNodeStream(aEngine, aFlags, graph->GraphRate());
|
||||
|
@ -549,15 +549,17 @@ WebAudioDecodeJob::OnSuccess(ErrorCode aErrorCode)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aErrorCode == NoError);
|
||||
|
||||
// Ignore errors in calling the callback, since there is not much that we can
|
||||
// do about it here.
|
||||
ErrorResult rv;
|
||||
if (mSuccessCallback) {
|
||||
ErrorResult rv;
|
||||
mSuccessCallback->Call(*mOutput, rv);
|
||||
// Ignore errors in calling the callback, since there is not much that we can
|
||||
// do about it here.
|
||||
rv.SuppressException();
|
||||
}
|
||||
mPromise->MaybeResolve(mOutput);
|
||||
|
||||
mContext->RemoveFromDecodeQueue(this);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -133,7 +133,7 @@ public:
|
||||
virtual bool IsFake() = 0;
|
||||
|
||||
/* Returns the type of media source (camera, microphone, screen, window, etc) */
|
||||
virtual const dom::MediaSourceEnum GetMediaSource() = 0;
|
||||
virtual dom::MediaSourceEnum GetMediaSource() const = 0;
|
||||
|
||||
// Callback interface for TakePhoto(). Either PhotoComplete() or PhotoError()
|
||||
// should be called.
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const dom::MediaSourceEnum GetMediaSource() override {
|
||||
virtual dom::MediaSourceEnum GetMediaSource() const override {
|
||||
return dom::MediaSourceEnum::Camera;
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const dom::MediaSourceEnum GetMediaSource() override {
|
||||
virtual dom::MediaSourceEnum GetMediaSource() const override {
|
||||
return dom::MediaSourceEnum::Microphone;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
SourceMediaStream* aSource,
|
||||
TrackID aId,
|
||||
StreamTime aDesiredTime) override;
|
||||
virtual const dom::MediaSourceEnum GetMediaSource() override {
|
||||
virtual dom::MediaSourceEnum GetMediaSource() const override {
|
||||
return dom::MediaSourceEnum::Camera;
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
SourceMediaStream* aSource,
|
||||
TrackID aId,
|
||||
StreamTime aDesiredTime) override;
|
||||
virtual const dom::MediaSourceEnum GetMediaSource() override {
|
||||
virtual dom::MediaSourceEnum GetMediaSource() const override {
|
||||
return mMediaSource;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ class MediaEngineTabVideoSource : public MediaEngineVideoSource, nsIDOMEventList
|
||||
const nsString& aDeviceId) override;
|
||||
virtual nsresult Config(bool, uint32_t, bool, uint32_t, bool, uint32_t, int32_t) override;
|
||||
virtual bool IsFake() override;
|
||||
virtual const dom::MediaSourceEnum GetMediaSource() override {
|
||||
virtual dom::MediaSourceEnum GetMediaSource() const override {
|
||||
return dom::MediaSourceEnum::Browser;
|
||||
}
|
||||
virtual uint32_t GetBestFitnessDistance(
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
void NotifyPull(MediaStreamGraph* aGraph, SourceMediaStream* aSource,
|
||||
TrackID aID, StreamTime aDesiredTime) override
|
||||
{}
|
||||
const dom::MediaSourceEnum GetMediaSource() override
|
||||
dom::MediaSourceEnum GetMediaSource() const override
|
||||
{
|
||||
return dom::MediaSourceEnum::AudioCapture;
|
||||
}
|
||||
@ -178,7 +178,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const dom::MediaSourceEnum GetMediaSource() override {
|
||||
virtual dom::MediaSourceEnum GetMediaSource() const override {
|
||||
return dom::MediaSourceEnum::Microphone;
|
||||
}
|
||||
|
||||
|
@ -344,7 +344,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
static const NotificationDirection StringToDirection(const nsAString& aDirection)
|
||||
static NotificationDirection StringToDirection(const nsAString& aDirection)
|
||||
{
|
||||
if (aDirection.EqualsLiteral("ltr")) {
|
||||
return NotificationDirection::Ltr;
|
||||
|
@ -1447,9 +1447,8 @@ GetOffsetRootContent(nsIFrame* aFrame)
|
||||
const nsIFrame* f = aFrame;
|
||||
int32_t currAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
int32_t apd = currAPD;
|
||||
nsRect displayPort;
|
||||
while (f) {
|
||||
if (f->GetContent() && nsLayoutUtils::GetDisplayPort(f->GetContent(), &displayPort))
|
||||
if (f->GetContent() && nsLayoutUtils::HasDisplayPort(f->GetContent()))
|
||||
break;
|
||||
|
||||
docOffset += f->GetPosition();
|
||||
|
@ -120,7 +120,7 @@ typedef mozilla::null_t DXGISharedSurfaceHandle;
|
||||
// XXX maybe not the best place for these. better one?
|
||||
|
||||
#define VARSTR(v_) case v_: return #v_
|
||||
inline const char* const
|
||||
inline const char*
|
||||
NPPVariableToString(NPPVariable aVar)
|
||||
{
|
||||
switch (aVar) {
|
||||
|
@ -86,12 +86,12 @@ private:
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
const uint16_t Port() const
|
||||
uint16_t Port() const
|
||||
{
|
||||
return mPort;
|
||||
}
|
||||
|
||||
const DeviceState State() const
|
||||
DeviceState State() const
|
||||
{
|
||||
return mState;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ GetZeroValueForUnit(StyleAnimationValue::Unit aUnit)
|
||||
// with a eUnit_Float value. (See comment below.)
|
||||
//
|
||||
// Returns true on success, or false.
|
||||
static const bool
|
||||
static bool
|
||||
FinalizeStyleAnimationValues(const StyleAnimationValue*& aValue1,
|
||||
const StyleAnimationValue*& aValue2)
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ protected:
|
||||
|
||||
// Interface for SVGMatrix's use
|
||||
friend class dom::SVGMatrix;
|
||||
const bool IsAnimVal() const {
|
||||
bool IsAnimVal() const {
|
||||
return mIsAnimValItem;
|
||||
}
|
||||
const gfxMatrix& Matrixgfx() const {
|
||||
|
@ -827,6 +827,21 @@ interface WEBGL_compressed_texture_atc
|
||||
const GLenum COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE;
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface WEBGL_compressed_texture_es3
|
||||
{
|
||||
const GLenum COMPRESSED_R11_EAC = 0x9270;
|
||||
const GLenum COMPRESSED_SIGNED_R11_EAC = 0x9271;
|
||||
const GLenum COMPRESSED_RG11_EAC = 0x9272;
|
||||
const GLenum COMPRESSED_SIGNED_RG11_EAC = 0x9273;
|
||||
const GLenum COMPRESSED_RGB8_ETC2 = 0x9274;
|
||||
const GLenum COMPRESSED_SRGB8_ETC2 = 0x9275;
|
||||
const GLenum COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
|
||||
const GLenum COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
|
||||
const GLenum COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
|
||||
const GLenum COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface WEBGL_compressed_texture_etc1
|
||||
{
|
||||
|
@ -1623,6 +1623,13 @@ private:
|
||||
{
|
||||
return aWorkerPrivate->ConnectMessagePort(aCx, mPortIdentifier);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Cancel() override
|
||||
{
|
||||
MessagePort::ForceClose(mPortIdentifier);
|
||||
return WorkerRunnable::Cancel();
|
||||
}
|
||||
};
|
||||
|
||||
class DummyRunnable final
|
||||
|
@ -16,11 +16,11 @@
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FormData.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "mozilla/dom/StructuredCloneHolder.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsVariant.h"
|
||||
@ -2203,7 +2203,7 @@ XMLHttpRequest::Send(Blob& aBody, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
void
|
||||
XMLHttpRequest::Send(nsFormData& aBody, ErrorResult& aRv)
|
||||
XMLHttpRequest::Send(FormData& aBody, ErrorResult& aRv)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
JSContext* cx = mWorkerPrivate->GetJSContext();
|
||||
|
@ -174,7 +174,7 @@ public:
|
||||
Send(Blob& aBody, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
Send(nsFormData& aBody, ErrorResult& aRv);
|
||||
Send(FormData& aBody, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
Send(const ArrayBuffer& aBody, ErrorResult& aRv);
|
||||
|
14
dom/workers/test/crashtests/1228456.html
Normal file
14
dom/workers/test/crashtests/1228456.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var w;
|
||||
for (var i = 0; i < 99; ++i) {
|
||||
w = new SharedWorker("data:text/javascript;charset=UTF-8," + encodeURIComponent(i + ";"));
|
||||
}
|
||||
w.port.postMessage("");
|
||||
}
|
||||
|
||||
</script>
|
||||
<body onload="boom();"></body>
|
@ -2,3 +2,4 @@ load 779707.html
|
||||
load 943516.html
|
||||
load 1153636.html
|
||||
load 1158031.html
|
||||
load 1228456.html
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
|
||||
}
|
||||
nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; }
|
||||
operator nsIDialogParamBlock * const () { return mBlock; }
|
||||
operator nsIDialogParamBlock * () const { return mBlock; }
|
||||
|
||||
private:
|
||||
nsIDialogParamBlock *mBlock;
|
||||
|
@ -91,7 +91,7 @@ CreateDataSourceSurfaceByCloning(DataSourceSurface* aSource);
|
||||
*/
|
||||
uint8_t*
|
||||
DataAtOffset(DataSourceSurface* aSurface,
|
||||
DataSourceSurface::MappedSurface* aMap,
|
||||
const DataSourceSurface::MappedSurface* aMap,
|
||||
IntPoint aPoint);
|
||||
|
||||
/**
|
||||
|
@ -8,9 +8,11 @@
|
||||
|
||||
#include "Types.h"
|
||||
#include <math.h>
|
||||
#include <ostream>
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/gfx/MatrixFwd.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
@ -54,11 +54,21 @@ GetBitsPerTexel(GLenum format, GLenum type)
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_ETC1_RGB8_OES:
|
||||
case LOCAL_GL_COMPRESSED_RGB8_ETC2:
|
||||
case LOCAL_GL_COMPRESSED_SRGB8_ETC2:
|
||||
case LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||||
case LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||||
case LOCAL_GL_COMPRESSED_R11_EAC:
|
||||
case LOCAL_GL_COMPRESSED_SIGNED_R11_EAC:
|
||||
return 4;
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
|
||||
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
|
||||
case LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC:
|
||||
case LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||||
case LOCAL_GL_COMPRESSED_RG11_EAC:
|
||||
case LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC:
|
||||
return 8;
|
||||
default:
|
||||
break;
|
||||
|
@ -941,7 +941,7 @@ Layer::ApplyPendingUpdatesForThisTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
const float
|
||||
float
|
||||
Layer::GetLocalOpacity()
|
||||
{
|
||||
float opacity = mOpacity;
|
||||
|
@ -1354,7 +1354,7 @@ public:
|
||||
* Returns the local opacity for this layer: either mOpacity or,
|
||||
* for shadow layers, GetShadowOpacity()
|
||||
*/
|
||||
const float GetLocalOpacity();
|
||||
float GetLocalOpacity();
|
||||
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
@ -1637,7 +1637,7 @@ public:
|
||||
* marked as needed to be recomposited.
|
||||
*/
|
||||
const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; }
|
||||
const void AddInvalidRegion(const nsIntRegion& aRegion) {
|
||||
void AddInvalidRegion(const nsIntRegion& aRegion) {
|
||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
||||
}
|
||||
|
||||
|
@ -1968,6 +1968,7 @@ nsEventStatus AsyncPanZoomController::OnPanMomentumStart(const PanGestureInput&
|
||||
}
|
||||
|
||||
SetState(PAN_MOMENTUM);
|
||||
RequestSnapToDestination();
|
||||
|
||||
// Call into OnPan in order to process any delta included in this event.
|
||||
OnPan(aEvent, false);
|
||||
@ -2429,6 +2430,14 @@ void AsyncPanZoomController::AcceptFling(FlingHandoffState& aHandoffState) {
|
||||
aHandoffState.mChain,
|
||||
!aHandoffState.mIsHandoff, // only apply acceleration if this is an initial fling
|
||||
aHandoffState.mScrolledApzc);
|
||||
RequestSnapToDestination();
|
||||
StartAnimation(fling);
|
||||
}
|
||||
|
||||
void
|
||||
AsyncPanZoomController::RequestSnapToDestination()
|
||||
{
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
||||
float friction = gfxPrefs::APZFlingFriction();
|
||||
ParentLayerPoint velocity(mX.GetVelocity(), mY.GetVelocity());
|
||||
@ -2462,8 +2471,6 @@ void AsyncPanZoomController::AcceptFling(FlingHandoffState& aHandoffState) {
|
||||
predictedDestination);
|
||||
}
|
||||
}
|
||||
|
||||
StartAnimation(fling);
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::AttemptFling(FlingHandoffState& aHandoffState) {
|
||||
|
@ -640,6 +640,9 @@ protected:
|
||||
// to a nearby snap position if appropriate. The current scroll position is
|
||||
// used as the final destination.
|
||||
void RequestSnap();
|
||||
// Same as above, but takes into account the current velocity to find a
|
||||
// predicted destination.
|
||||
void RequestSnapToDestination();
|
||||
|
||||
uint64_t mLayersId;
|
||||
RefPtr<CompositorParent> mCompositorParent;
|
||||
|
@ -92,11 +92,11 @@ void mozilla_dump_image(void* bytes, int width, int height, int bytepp,
|
||||
|
||||
}
|
||||
|
||||
static const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
|
||||
static uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
|
||||
return gfxUtils::sPremultiplyTable[a*256+v];
|
||||
}
|
||||
|
||||
static const uint8_t UnpremultiplyValue(uint8_t a, uint8_t v) {
|
||||
static uint8_t UnpremultiplyValue(uint8_t a, uint8_t v) {
|
||||
return gfxUtils::sUnpremultiplyTable[a*256+v];
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ class Message : public Pickle {
|
||||
header()->seqno = aSeqno;
|
||||
}
|
||||
|
||||
const char* const name() const {
|
||||
const char* name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class MessageIterator {
|
||||
NOTREACHED();
|
||||
return val;
|
||||
}
|
||||
const void NextData(const char** data, int* length) const {
|
||||
void NextData(const char** data, int* length) const {
|
||||
if (!msg_.ReadData(&iter_, data, length)) {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
@ -577,7 +577,7 @@ def _cxxConstPtrToType(ipdltype, side):
|
||||
t.ptrconstptr = 1
|
||||
return t
|
||||
t.const = 1
|
||||
t.ptrconst = 1
|
||||
t.ptr = 1
|
||||
return t
|
||||
|
||||
def _allocMethod(ptype, side):
|
||||
|
@ -92,6 +92,40 @@ class GCHashMap : public HashMap<Key, Value, HashPolicy, AllocPolicy>,
|
||||
GCHashMap& operator=(const GCHashMap& hm) = delete;
|
||||
};
|
||||
|
||||
// HashMap that supports rekeying.
|
||||
template <typename Key,
|
||||
typename Value,
|
||||
typename HashPolicy = DefaultHasher<Key>,
|
||||
typename AllocPolicy = TempAllocPolicy,
|
||||
typename GCPolicy = DefaultMapGCPolicy<Key, Value>>
|
||||
class GCRekeyableHashMap : public GCHashMap<Key, Value, HashPolicy, AllocPolicy, GCPolicy>
|
||||
{
|
||||
using Base = GCHashMap<Key, Value, HashPolicy, AllocPolicy>;
|
||||
|
||||
public:
|
||||
explicit GCRekeyableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {}
|
||||
|
||||
void sweep() {
|
||||
if (!this->initialized())
|
||||
return;
|
||||
|
||||
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
|
||||
Key key(e.front().key());
|
||||
if (GCPolicy::needsSweep(&key, &e.front().value()))
|
||||
e.removeFront();
|
||||
else if (!HashPolicy::match(key, e.front().key()))
|
||||
e.rekeyFront(key);
|
||||
}
|
||||
}
|
||||
|
||||
// GCRekeyableHashMap is movable
|
||||
GCRekeyableHashMap(GCRekeyableHashMap&& rhs) : Base(mozilla::Forward<GCRekeyableHashMap>(rhs)) {}
|
||||
void operator=(GCRekeyableHashMap&& rhs) {
|
||||
MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited");
|
||||
Base::operator=(mozilla::Forward<GCRekeyableHashMap>(rhs));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Outer, typename... Args>
|
||||
class GCHashMapOperations
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -430,18 +430,32 @@ enum NeedsBoundsCheck : uint8_t
|
||||
// referenced by the FuncIR.
|
||||
class FuncIR
|
||||
{
|
||||
typedef Vector<wasm::Val, 4, LifoAllocPolicy<Fallible>> VarInitVector;
|
||||
typedef Vector<ValType, 4, LifoAllocPolicy<Fallible>> ValTypeVector;
|
||||
|
||||
public:
|
||||
// Source coordinates for a call site. As they're read sequentially, we
|
||||
// don't need to store the call's bytecode offset, unless we want to
|
||||
// check its consistency in debug mode.
|
||||
struct SourceCoords {
|
||||
DebugOnly<uint32_t> offset; // after call opcode
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
};
|
||||
|
||||
private:
|
||||
typedef Vector<uint8_t, 4096, LifoAllocPolicy<Fallible>> Bytecode;
|
||||
typedef Vector<SourceCoords, 4, LifoAllocPolicy<Fallible>> SourceCoordsVector;
|
||||
|
||||
// Note: this unrooted field assumes AutoKeepAtoms via TokenStream via
|
||||
// asm.js compilation.
|
||||
PropertyName* name_;
|
||||
unsigned line_;
|
||||
unsigned column_;
|
||||
SourceCoordsVector callSourceCoords_;
|
||||
|
||||
uint32_t index_;
|
||||
const wasm::LifoSig* sig_;
|
||||
VarInitVector varInits_;
|
||||
const LifoSig* sig_;
|
||||
ValTypeVector localVars_;
|
||||
Bytecode bytecode_;
|
||||
unsigned generateTime_;
|
||||
|
||||
@ -450,18 +464,22 @@ class FuncIR
|
||||
: name_(name),
|
||||
line_(line),
|
||||
column_(column),
|
||||
callSourceCoords_(alloc),
|
||||
index_(UINT_MAX),
|
||||
sig_(nullptr),
|
||||
varInits_(alloc),
|
||||
localVars_(alloc),
|
||||
bytecode_(alloc),
|
||||
generateTime_(UINT_MAX)
|
||||
{}
|
||||
|
||||
bool addVariable(wasm::Val v) {
|
||||
return varInits_.append(v);
|
||||
bool addVariable(ValType v) {
|
||||
return localVars_.append(v);
|
||||
}
|
||||
|
||||
void finish(uint32_t funcIndex, const wasm::LifoSig& sig, unsigned generateTime) {
|
||||
bool addSourceCoords(uint32_t line, uint32_t column) {
|
||||
SourceCoords sc = { bytecode_.length(), line, column };
|
||||
return callSourceCoords_.append(sc);
|
||||
}
|
||||
void finish(uint32_t funcIndex, const LifoSig& sig, unsigned generateTime) {
|
||||
MOZ_ASSERT(index_ == UINT_MAX);
|
||||
MOZ_ASSERT(!sig_);
|
||||
MOZ_ASSERT(generateTime_ == UINT_MAX);
|
||||
@ -471,15 +489,27 @@ class FuncIR
|
||||
}
|
||||
|
||||
private:
|
||||
template<class T> size_t writePrimitive(T v) {
|
||||
size_t writeAt = bytecode_.length();
|
||||
if (!bytecode_.append(reinterpret_cast<uint8_t*>(&v), sizeof(T)))
|
||||
return -1;
|
||||
return writeAt;
|
||||
template<class T>
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool write(T v, size_t* offset) {
|
||||
if (offset)
|
||||
*offset = bytecode_.length();
|
||||
return bytecode_.append(reinterpret_cast<uint8_t*>(&v), sizeof(T));
|
||||
}
|
||||
|
||||
template<class T> T readPrimitive(size_t* pc) const {
|
||||
MOZ_ASSERT(*pc + sizeof(T) <= bytecode_.length());
|
||||
template<class T>
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool read(size_t* pc, T* out) const {
|
||||
if (size_t(bytecode_.length() - *pc) >= sizeof(T))
|
||||
return false;
|
||||
memcpy((void*)out, &bytecode_[*pc], sizeof(T));
|
||||
*pc += sizeof(T);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T uncheckedRead(size_t* pc) const {
|
||||
MOZ_ASSERT(size_t(bytecode_.length() - *pc) >= sizeof(T));
|
||||
T ret;
|
||||
memcpy(&ret, &bytecode_[*pc], sizeof(T));
|
||||
*pc += sizeof(T);
|
||||
@ -487,52 +517,44 @@ class FuncIR
|
||||
}
|
||||
|
||||
public:
|
||||
size_t writeU8(uint8_t i) { return writePrimitive<uint8_t>(i); }
|
||||
size_t writeI32(int32_t i) { return writePrimitive<int32_t>(i); }
|
||||
size_t writeU32(uint32_t i) { return writePrimitive<uint32_t>(i); }
|
||||
size_t writeF32(float f) { return writePrimitive<float>(f); }
|
||||
size_t writeF64(double d) { return writePrimitive<double>(d); }
|
||||
// Packing interface
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
writeU8(uint8_t i, size_t* offset = nullptr) { return write<uint8_t>(i, offset); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
writeI32(int32_t i, size_t* offset = nullptr) { return write<int32_t>(i, offset); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
writeU32(uint32_t i, size_t* offset = nullptr) { return write<uint32_t>(i, offset); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
writeF32(float f, size_t* offset = nullptr) { return write<float>(f, offset); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
writeF64(double d, size_t* offset = nullptr) { return write<double>(d, offset); }
|
||||
|
||||
size_t writeI32X4(const int32_t* i4) {
|
||||
size_t pos = bytecode_.length();
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
writePrimitive<int32_t>(i4[i]);
|
||||
return pos;
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
writeI32X4(const int32_t* i4, size_t* offset = nullptr) {
|
||||
if (!writeI32(i4[0], offset))
|
||||
return false;
|
||||
for (size_t i = 1; i < 4; i++) {
|
||||
if (!writeI32(i4[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
size_t writeF32X4(const float* f4) {
|
||||
size_t pos = bytecode_.length();
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
writePrimitive<float>(f4[i]);
|
||||
return pos;
|
||||
}
|
||||
|
||||
uint8_t readU8 (size_t* pc) const { return readPrimitive<uint8_t>(pc); }
|
||||
int32_t readI32(size_t* pc) const { return readPrimitive<int32_t>(pc); }
|
||||
float readF32(size_t* pc) const { return readPrimitive<float>(pc); }
|
||||
uint32_t readU32(size_t* pc) const { return readPrimitive<uint32_t>(pc); }
|
||||
double readF64(size_t* pc) const { return readPrimitive<double>(pc); }
|
||||
const wasm::LifoSig* readSig(size_t* pc) const { return readPrimitive<wasm::LifoSig*>(pc); }
|
||||
|
||||
jit::SimdConstant readI32X4(size_t* pc) const {
|
||||
int32_t x = readI32(pc);
|
||||
int32_t y = readI32(pc);
|
||||
int32_t z = readI32(pc);
|
||||
int32_t w = readI32(pc);
|
||||
return jit::SimdConstant::CreateX4(x, y, z, w);
|
||||
}
|
||||
jit::SimdConstant readF32X4(size_t* pc) const {
|
||||
float x = readF32(pc);
|
||||
float y = readF32(pc);
|
||||
float z = readF32(pc);
|
||||
float w = readF32(pc);
|
||||
return jit::SimdConstant::CreateX4(x, y, z, w);
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
writeF32X4(const float* f4, size_t* offset = nullptr) {
|
||||
if (!writeF32(f4[0], offset))
|
||||
return false;
|
||||
for (size_t i = 1; i < 4; i++) {
|
||||
if (!writeF32(f4[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool pcIsPatchable(size_t pc, unsigned size) const {
|
||||
bool patchable = true;
|
||||
for (unsigned i = 0; patchable && i < size; i++)
|
||||
patchable &= wasm::Stmt(bytecode_[pc]) == wasm::Stmt::Bad;
|
||||
patchable &= Stmt(bytecode_[pc]) == Stmt::Bad;
|
||||
return patchable;
|
||||
}
|
||||
#endif
|
||||
@ -550,22 +572,85 @@ class FuncIR
|
||||
memcpy(&bytecode_[pc], &i, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void patchSig(size_t pc, const wasm::LifoSig* ptr) {
|
||||
MOZ_ASSERT(pcIsPatchable(pc, sizeof(wasm::LifoSig*)));
|
||||
memcpy(&bytecode_[pc], &ptr, sizeof(wasm::LifoSig*));
|
||||
void patchSig(size_t pc, const LifoSig* ptr) {
|
||||
MOZ_ASSERT(pcIsPatchable(pc, sizeof(LifoSig*)));
|
||||
memcpy(&bytecode_[pc], &ptr, sizeof(LifoSig*));
|
||||
}
|
||||
|
||||
// The fallible unpacking API should be used when we're not assuming
|
||||
// anything about the bytecode, in particular if it is well-formed.
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readU8 (size_t* pc, uint8_t* i) const { return read(pc, i); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readI32(size_t* pc, int32_t* i) const { return read(pc, i); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readF32(size_t* pc, float* f) const { return read(pc, f); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readU32(size_t* pc, uint32_t* u) const { return read(pc, u); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readF64(size_t* pc, double* d) const { return read(pc, d); }
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readSig(size_t* pc, const LifoSig* sig) const { return read(pc, sig); }
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readI32X4(size_t* pc, jit::SimdConstant* c) const {
|
||||
int32_t v[4] = { 0, 0, 0, 0 };
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
if (!readI32(pc, &v[i]))
|
||||
return false;
|
||||
}
|
||||
*c = jit::SimdConstant::CreateX4(v[0], v[1], v[2], v[3]);
|
||||
return true;
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool
|
||||
readF32X4(size_t* pc, jit::SimdConstant* c) const {
|
||||
float v[4] = { 0., 0., 0., 0. };
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
if (!readF32(pc, &v[i]))
|
||||
return false;
|
||||
}
|
||||
*c = jit::SimdConstant::CreateX4(v[0], v[1], v[2], v[3]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// The unfallible unpacking API should be used when we are sure that the
|
||||
// bytecode is well-formed.
|
||||
uint8_t uncheckedReadU8 (size_t* pc) const { return uncheckedRead<uint8_t>(pc); }
|
||||
int32_t uncheckedReadI32(size_t* pc) const { return uncheckedRead<int32_t>(pc); }
|
||||
float uncheckedReadF32(size_t* pc) const { return uncheckedRead<float>(pc); }
|
||||
uint32_t uncheckedReadU32(size_t* pc) const { return uncheckedRead<uint32_t>(pc); }
|
||||
double uncheckedReadF64(size_t* pc) const { return uncheckedRead<double>(pc); }
|
||||
const LifoSig* uncheckedReadSig(size_t* pc) const { return uncheckedRead<const LifoSig*>(pc); }
|
||||
|
||||
jit::SimdConstant uncheckedReadI32X4(size_t* pc) const {
|
||||
int32_t v[4] = { 0, 0, 0, 0 };
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
v[i] = uncheckedReadI32(pc);
|
||||
return jit::SimdConstant::CreateX4(v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
jit::SimdConstant uncheckedReadF32X4(size_t* pc) const {
|
||||
float v[4] = { 0., 0., 0., 0. };
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
v[i] = uncheckedReadF32(pc);
|
||||
return jit::SimdConstant::CreateX4(v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
|
||||
// Read-only interface
|
||||
PropertyName* name() const { return name_; }
|
||||
unsigned line() const { return line_; }
|
||||
unsigned column() const { return column_; }
|
||||
const SourceCoords& sourceCoords(size_t i) const { return callSourceCoords_[i]; }
|
||||
|
||||
uint32_t index() const { MOZ_ASSERT(index_ != UINT32_MAX); return index_; }
|
||||
size_t size() const { return bytecode_.length(); }
|
||||
const wasm::LifoSig& sig() const { MOZ_ASSERT(sig_); return *sig_; }
|
||||
size_t numVarInits() const { return varInits_.length(); }
|
||||
wasm::Val varInit(size_t i) const { return varInits_[i]; }
|
||||
size_t numLocals() const { return sig_->args().length() + varInits_.length(); }
|
||||
const LifoSig& sig() const { MOZ_ASSERT(sig_); return *sig_; }
|
||||
|
||||
size_t numLocalVars() const { return localVars_.length(); }
|
||||
ValType localVarType(size_t i) const { return localVars_[i]; }
|
||||
size_t numLocals() const { return sig_->args().length() + numLocalVars(); }
|
||||
|
||||
unsigned generateTime() const { MOZ_ASSERT(generateTime_ != UINT_MAX); return generateTime_; }
|
||||
|
||||
size_t size() const { return bytecode_.length(); }
|
||||
};
|
||||
|
||||
} // namespace wasm
|
||||
|
@ -38,10 +38,10 @@ class FunctionCompiler
|
||||
typedef HashMap<uint32_t, BlockVector, DefaultHasher<uint32_t>, SystemAllocPolicy> LabeledBlockMap;
|
||||
typedef HashMap<size_t, BlockVector, DefaultHasher<uint32_t>, SystemAllocPolicy> UnlabeledBlockMap;
|
||||
typedef Vector<size_t, 4, SystemAllocPolicy> PositionStack;
|
||||
typedef Vector<ValType, 4, SystemAllocPolicy> LocalTypes;
|
||||
|
||||
const FuncIR& func_;
|
||||
size_t pc_;
|
||||
size_t lastReadCallSite_;
|
||||
|
||||
TempAllocator& alloc_;
|
||||
MIRGraph& graph_;
|
||||
@ -57,14 +57,13 @@ class FunctionCompiler
|
||||
LabeledBlockMap labeledBreaks_;
|
||||
LabeledBlockMap labeledContinues_;
|
||||
|
||||
LocalTypes localTypes_;
|
||||
|
||||
FuncCompileResults& compileResults_;
|
||||
|
||||
public:
|
||||
FunctionCompiler(const FuncIR& func, MIRGenerator& mirGen, FuncCompileResults& compileResults)
|
||||
: func_(func),
|
||||
pc_(0),
|
||||
lastReadCallSite_(0),
|
||||
alloc_(mirGen.alloc()),
|
||||
graph_(mirGen.graph()),
|
||||
info_(mirGen.info()),
|
||||
@ -101,34 +100,31 @@ class FunctionCompiler
|
||||
curBlock_->initSlot(info().localSlot(i.index()), ins);
|
||||
if (!mirGen_.ensureBallast())
|
||||
return false;
|
||||
if (!localTypes_.append(args[i.index()]))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < func_.numVarInits(); i++) {
|
||||
Val v = func_.varInit(i);
|
||||
for (size_t i = 0; i < func_.numLocalVars(); i++) {
|
||||
MInstruction* ins = nullptr;
|
||||
switch (v.type()) {
|
||||
switch (func_.localVarType(i)) {
|
||||
case ValType::I32:
|
||||
ins = MConstant::NewAsmJS(alloc(), Int32Value(v.i32()), MIRType_Int32);
|
||||
ins = MConstant::NewAsmJS(alloc(), Int32Value(0), MIRType_Int32);
|
||||
break;
|
||||
case ValType::I64:
|
||||
MOZ_CRASH("int64");
|
||||
case ValType::F32:
|
||||
ins = MConstant::NewAsmJS(alloc(), Float32Value(v.f32()), MIRType_Float32);
|
||||
ins = MConstant::NewAsmJS(alloc(), Float32Value(0.f), MIRType_Float32);
|
||||
break;
|
||||
case ValType::F64:
|
||||
ins = MConstant::NewAsmJS(alloc(), DoubleValue(v.f64()), MIRType_Double);
|
||||
ins = MConstant::NewAsmJS(alloc(), DoubleValue(0.0), MIRType_Double);
|
||||
break;
|
||||
case ValType::I32x4:
|
||||
ins = MSimdConstant::New(alloc(), SimdConstant::CreateX4(v.i32x4()), MIRType_Int32x4);
|
||||
ins = MSimdConstant::New(alloc(), SimdConstant::SplatX4(0), MIRType_Int32x4);
|
||||
break;
|
||||
case ValType::F32x4:
|
||||
ins = MSimdConstant::New(alloc(), SimdConstant::CreateX4(v.f32x4()), MIRType_Float32x4);
|
||||
ins = MSimdConstant::New(alloc(), SimdConstant::SplatX4(0.f), MIRType_Float32x4);
|
||||
break;
|
||||
case ValType::B32x4:
|
||||
// Bool32x4 uses the same data layout as Int32x4.
|
||||
ins = MSimdConstant::New(alloc(), SimdConstant::CreateX4(v.i32x4()), MIRType_Bool32x4);
|
||||
ins = MSimdConstant::New(alloc(), SimdConstant::SplatX4(0), MIRType_Bool32x4);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -136,8 +132,6 @@ class FunctionCompiler
|
||||
curBlock_->initSlot(info().localSlot(firstVarSlot + i), ins);
|
||||
if (!mirGen_.ensureBallast())
|
||||
return false;
|
||||
if (!localTypes_.append(v.type()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1166,20 +1160,26 @@ class FunctionCompiler
|
||||
|
||||
/************************************************************ DECODING ***/
|
||||
|
||||
uint8_t readU8() { return func_.readU8(&pc_); }
|
||||
uint32_t readU32() { return func_.readU32(&pc_); }
|
||||
int32_t readI32() { return func_.readI32(&pc_); }
|
||||
float readF32() { return func_.readF32(&pc_); }
|
||||
double readF64() { return func_.readF64(&pc_); }
|
||||
const LifoSig* readSig() { return func_.readSig(&pc_); }
|
||||
SimdConstant readI32X4() { return func_.readI32X4(&pc_); }
|
||||
SimdConstant readF32X4() { return func_.readF32X4(&pc_); }
|
||||
uint8_t readU8() { return func_.uncheckedReadU8(&pc_); }
|
||||
uint32_t readU32() { return func_.uncheckedReadU32(&pc_); }
|
||||
int32_t readI32() { return func_.uncheckedReadI32(&pc_); }
|
||||
float readF32() { return func_.uncheckedReadF32(&pc_); }
|
||||
double readF64() { return func_.uncheckedReadF64(&pc_); }
|
||||
const LifoSig* readSig() { return func_.uncheckedReadSig(&pc_); }
|
||||
SimdConstant readI32X4() { return func_.uncheckedReadI32X4(&pc_); }
|
||||
SimdConstant readF32X4() { return func_.uncheckedReadF32X4(&pc_); }
|
||||
|
||||
Stmt readStmtOp() { return Stmt(readU8()); }
|
||||
|
||||
void readCallLineCol(uint32_t* line, uint32_t* column) {
|
||||
const FuncIR::SourceCoords& sc = func_.sourceCoords(lastReadCallSite_++);
|
||||
MOZ_ASSERT(pc_ == sc.offset);
|
||||
*line = sc.line;
|
||||
*column = sc.column;
|
||||
}
|
||||
|
||||
void assertDebugCheckPoint() {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(Stmt(readU8()) == Stmt::DebugCheckPoint);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool done() const { return pc_ == func_.size(); }
|
||||
@ -1563,13 +1563,6 @@ EmitCallArgs(FunctionCompiler& f, const LifoSig& sig, FunctionCompiler::Call* ca
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ReadCallLineCol(FunctionCompiler& f, uint32_t* line, uint32_t* column)
|
||||
{
|
||||
*line = f.readU32();
|
||||
*column = f.readU32();
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitInternalCall(FunctionCompiler& f, ExprType ret, MDefinition** def)
|
||||
{
|
||||
@ -1578,7 +1571,7 @@ EmitInternalCall(FunctionCompiler& f, ExprType ret, MDefinition** def)
|
||||
MOZ_ASSERT_IF(!IsVoid(sig.ret()), sig.ret() == ret);
|
||||
|
||||
uint32_t lineno, column;
|
||||
ReadCallLineCol(f, &lineno, &column);
|
||||
f.readCallLineCol(&lineno, &column);
|
||||
|
||||
FunctionCompiler::Call call(f, lineno, column);
|
||||
if (!EmitCallArgs(f, sig, &call))
|
||||
@ -1597,7 +1590,7 @@ EmitFuncPtrCall(FunctionCompiler& f, ExprType ret, MDefinition** def)
|
||||
MOZ_ASSERT_IF(!IsVoid(sig.ret()), sig.ret() == ret);
|
||||
|
||||
uint32_t lineno, column;
|
||||
ReadCallLineCol(f, &lineno, &column);
|
||||
f.readCallLineCol(&lineno, &column);
|
||||
|
||||
MDefinition *index;
|
||||
if (!EmitI32Expr(f, &index))
|
||||
@ -1619,7 +1612,7 @@ EmitFFICall(FunctionCompiler& f, ExprType ret, MDefinition** def)
|
||||
MOZ_ASSERT_IF(!IsVoid(sig.ret()), sig.ret() == ret);
|
||||
|
||||
uint32_t lineno, column;
|
||||
ReadCallLineCol(f, &lineno, &column);
|
||||
f.readCallLineCol(&lineno, &column);
|
||||
|
||||
FunctionCompiler::Call call(f, lineno, column);
|
||||
if (!EmitCallArgs(f, sig, &call))
|
||||
@ -1634,7 +1627,7 @@ EmitMathBuiltinCall(FunctionCompiler& f, F32 f32, MDefinition** def)
|
||||
MOZ_ASSERT(f32 == F32::Ceil || f32 == F32::Floor);
|
||||
|
||||
uint32_t lineno, column;
|
||||
ReadCallLineCol(f, &lineno, &column);
|
||||
f.readCallLineCol(&lineno, &column);
|
||||
|
||||
FunctionCompiler::Call call(f, lineno, column);
|
||||
f.startCallArgs(&call);
|
||||
@ -1653,7 +1646,7 @@ static bool
|
||||
EmitMathBuiltinCall(FunctionCompiler& f, F64 f64, MDefinition** def)
|
||||
{
|
||||
uint32_t lineno, column;
|
||||
ReadCallLineCol(f, &lineno, &column);
|
||||
f.readCallLineCol(&lineno, &column);
|
||||
|
||||
FunctionCompiler::Call call(f, lineno, column);
|
||||
f.startCallArgs(&call);
|
||||
|
@ -903,6 +903,182 @@ function TypedArraySome(callbackfn, thisArg = undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For sorting small arrays
|
||||
function InsertionSort(array, from, to, comparefn) {
|
||||
var item, swap;
|
||||
for (var i = from + 1; i <= to; i++) {
|
||||
item = array[i];
|
||||
for (var j = i - 1; j >= from; j--) {
|
||||
swap = array[j];
|
||||
if (comparefn(swap, item) <= 0)
|
||||
break
|
||||
array[j + 1] = swap;
|
||||
}
|
||||
array[j + 1] = item;
|
||||
}
|
||||
}
|
||||
|
||||
function SwapArrayElements(array, i, j) {
|
||||
var swap = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = swap;
|
||||
}
|
||||
|
||||
// Rearranges the elements in array[from:to + 1] and returns an index j such that:
|
||||
// - from < j < to
|
||||
// - each element in array[from:j] is less than or equal to array[j]
|
||||
// - each element in array[j + 1:to + 1] greater than or equal to array[j].
|
||||
function Partition(array, from, to, comparefn) {
|
||||
assert(to - from >= 3,
|
||||
"Partition will not work with less than three elements");
|
||||
|
||||
var median_i = (from + to) >> 1;
|
||||
|
||||
var i = from + 1;
|
||||
var j = to;
|
||||
|
||||
SwapArrayElements(array, median_i, i);
|
||||
|
||||
// Median of three pivot selection
|
||||
if (comparefn(array[from], array[to]) > 0)
|
||||
SwapArrayElements(array, from, to);
|
||||
|
||||
if (comparefn(array[i], array[to]) > 0)
|
||||
SwapArrayElements(array, i, to);
|
||||
|
||||
if (comparefn(array[from], array[i]) > 0)
|
||||
SwapArrayElements(array, from, i);
|
||||
|
||||
var pivot_i = i;
|
||||
|
||||
// Hoare partition method
|
||||
for(;;) {
|
||||
do i++; while (comparefn(array[i], array[pivot_i]) < 0);
|
||||
do j--; while (comparefn(array[j], array[pivot_i]) > 0);
|
||||
if (i > j)
|
||||
break;
|
||||
SwapArrayElements(array, i, j);
|
||||
}
|
||||
|
||||
SwapArrayElements(array, pivot_i, j);
|
||||
return j;
|
||||
}
|
||||
|
||||
// In-place QuickSort
|
||||
function QuickSort(array, len, comparefn) {
|
||||
// Managing the stack ourselves seems to provide a small performance boost
|
||||
var stack = new List();
|
||||
var top = 0;
|
||||
|
||||
var start = 0;
|
||||
var end = len - 1;
|
||||
|
||||
var pivot_i, i, j, l_len, r_len;
|
||||
|
||||
for (;;) {
|
||||
// Insertion sort for the first N elements where N is some value
|
||||
// determined by performance testing.
|
||||
if (end - start <= 23) {
|
||||
InsertionSort(array, start, end, comparefn);
|
||||
if (top < 1)
|
||||
break;
|
||||
end = stack[--top];
|
||||
start = stack[--top];
|
||||
} else {
|
||||
pivot_i = Partition(array, start, end, comparefn);
|
||||
|
||||
// Calculate the left and right sub-array lengths and save
|
||||
// stack space by directly modifying start/end so that
|
||||
// we sort the longest of the two during the next iteration.
|
||||
// This reduces the maximum stack size to log2(len)
|
||||
l_len = (pivot_i - 1) - start;
|
||||
r_len = end - (pivot_i + 1);
|
||||
|
||||
if (r_len > l_len) {
|
||||
stack[top++] = start;
|
||||
stack[top++] = pivot_i - 1;
|
||||
start = pivot_i + 1;
|
||||
} else {
|
||||
stack[top++] = pivot_i + 1;
|
||||
stack[top++] = end;
|
||||
end = pivot_i - 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// ES6 draft 20151210 22.2.3.26
|
||||
// Cases are ordered according to likelihood of occurrence
|
||||
// as opposed to the ordering in the spec.
|
||||
function TypedArrayCompare(x, y) {
|
||||
// Step 1.
|
||||
assert(typeof x === "number" && typeof y === "number",
|
||||
"x and y are not numbers.");
|
||||
|
||||
// Steps 6 - 7.
|
||||
var diff = x - y;
|
||||
if (diff)
|
||||
return diff;
|
||||
|
||||
// Steps 8 - 10.
|
||||
if (x === 0 && y === 0)
|
||||
return (1/x > 0 ? 1 : 0) - (1/y > 0 ? 1 : 0);
|
||||
|
||||
// Step 2. Implemented in TypedArraySort
|
||||
|
||||
// Step 3.
|
||||
if (Number_isNaN(x) && Number_isNaN(y))
|
||||
return 0;
|
||||
|
||||
// Steps 4 - 5.
|
||||
if (Number_isNaN(x) || Number_isNaN(y))
|
||||
return Number_isNaN(x) ? 1 : -1;
|
||||
|
||||
}
|
||||
|
||||
// ES6 draft 20151210 22.2.3.26 %TypedArray%.prototype.sort ( comparefn ).
|
||||
function TypedArraySort(comparefn) {
|
||||
// This function is not generic.
|
||||
if (!IsObject(this) || !IsTypedArray(this)) {
|
||||
return callFunction(CallTypedArrayMethodIfWrapped, this, comparefn,
|
||||
"TypedArraySort");
|
||||
}
|
||||
|
||||
// Step 1.
|
||||
var obj = this;
|
||||
|
||||
// Step 2.
|
||||
var buffer = TypedArrayBuffer(obj);
|
||||
if (IsDetachedBuffer(buffer))
|
||||
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
||||
|
||||
// Step 3.
|
||||
var len = TypedArrayLength(obj);
|
||||
|
||||
if (comparefn === undefined) {
|
||||
comparefn = TypedArrayCompare;
|
||||
} else {
|
||||
// To satisfy step 2 from TypedArray SortCompare described in 22.2.3.26
|
||||
// the user supplied comparefn is wrapped.
|
||||
var wrappedCompareFn = comparefn;
|
||||
comparefn = function(x, y) {
|
||||
// Step a.
|
||||
var v = wrappedCompareFn(x, y);
|
||||
// Step b.
|
||||
if (IsDetachedBuffer(buffer))
|
||||
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
||||
// Step c. is redundant, see:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1121937#c36
|
||||
// Step d.
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
return QuickSort(obj, len, comparefn);
|
||||
}
|
||||
|
||||
// ES6 draft 20150304 %TypedArray%.prototype.subarray
|
||||
function TypedArraySubarray(begin, end) {
|
||||
// Step 1.
|
||||
|
@ -1191,7 +1191,7 @@ if test "$GNU_CC"; then
|
||||
|
||||
# -Wall - lots of useful warnings
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Wignored-qualifiers - catches returns types with qualifiers like const
|
||||
# -Wignored-qualifiers - catches return types with qualifiers like const
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall"
|
||||
@ -1268,11 +1268,13 @@ if test "$GNU_CXX"; then
|
||||
|
||||
# -Wall - lots of useful warnings
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Wignored-qualifiers - catches return types with qualifiers like const
|
||||
# -Woverloaded-virtual - function declaration hides virtual function from base class
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wempty-body"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wignored-qualifiers"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Woverloaded-virtual"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wpointer-arith"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
|
||||
|
@ -415,7 +415,7 @@ JitCompartment::~JitCompartment()
|
||||
bool
|
||||
JitCompartment::initialize(JSContext* cx)
|
||||
{
|
||||
stubCodes_ = cx->new_<ICStubCodeMap>(cx);
|
||||
stubCodes_ = cx->new_<ICStubCodeMap>(cx->runtime());
|
||||
if (!stubCodes_)
|
||||
return false;
|
||||
|
||||
@ -730,7 +730,7 @@ JitCompartment::sweep(FreeOp* fop, JSCompartment* compartment)
|
||||
CancelOffThreadIonCompile(compartment, nullptr);
|
||||
FinishAllOffThreadCompilations(compartment);
|
||||
|
||||
stubCodes_->sweep(fop);
|
||||
stubCodes_->sweep();
|
||||
|
||||
// If the sweep removed the ICCall_Fallback stub, nullptr the baselineCallReturnAddr_ field.
|
||||
if (!stubCodes_->lookup(ICCall_Fallback::Compiler::BASELINE_CALL_KEY))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user