--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -927,23 +927,29 @@ HyperTextAccessible::GetTextBeforeOffset
case BOUNDARY_LINE_START:
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
offset = AdjustCaretOffset(offset);
*aStartOffset = FindLineBoundary(offset, ePrevLineBegin);
*aEndOffset = FindLineBoundary(offset, eThisLineBegin);
return GetText(*aStartOffset, *aEndOffset, aText);
- case BOUNDARY_LINE_END:
+ case BOUNDARY_LINE_END: {
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
offset = AdjustCaretOffset(offset);
*aEndOffset = FindLineBoundary(offset, ePrevLineEnd);
- *aStartOffset = FindLineBoundary(*aEndOffset, ePrevLineEnd);
+ int32_t tmpOffset = *aEndOffset;
+ // Adjust offset if line is wrapped.
+ if (*aEndOffset != 0 && !IsLineEndCharAt(*aEndOffset))
+ tmpOffset--;
+
+ *aStartOffset = FindLineBoundary(tmpOffset, ePrevLineEnd);
return GetText(*aStartOffset, *aEndOffset, aText);
+ }
default:
return NS_ERROR_INVALID_ARG;
}
}
NS_IMETHODIMP
HyperTextAccessible::GetTextAtOffset(int32_t aOffset,
@@ -2146,23 +2152,19 @@ HyperTextAccessible::RenderedToContentOf
bool
HyperTextAccessible::GetCharAt(int32_t aOffset, EGetTextType aShift,
nsAString& aChar, int32_t* aStartOffset,
int32_t* aEndOffset)
{
aChar.Truncate();
int32_t offset = ConvertMagicOffset(aOffset) + static_cast<int32_t>(aShift);
- int32_t childIdx = GetChildIndexAtOffset(offset);
- if (childIdx == -1)
+ if (!CharAt(offset, aChar))
return false;
- Accessible* child = GetChildAt(childIdx);
- child->AppendTextTo(aChar, offset - GetChildOffset(childIdx), 1);
-
if (aStartOffset)
*aStartOffset = offset;
if (aEndOffset)
*aEndOffset = aChar.IsEmpty() ? offset : offset + 1;
return true;
}
--- a/accessible/src/generic/HyperTextAccessible.h
+++ b/accessible/src/generic/HyperTextAccessible.h
@@ -160,16 +160,46 @@ public:
* Return character count within the hypertext accessible.
*/
uint32_t CharacterCount()
{
return GetChildOffset(ChildCount());
}
/**
+ * Get a character at the given offset (don't support magic offsets).
+ */
+ bool CharAt(int32_t aOffset, nsAString& aChar)
+ {
+ int32_t childIdx = GetChildIndexAtOffset(aOffset);
+ if (childIdx == -1)
+ return false;
+
+ Accessible* child = GetChildAt(childIdx);
+ child->AppendTextTo(aChar, aOffset - GetChildOffset(childIdx), 1);
+ return true;
+ }
+
+ /**
+ * Return true if char at the given offset equals to given char.
+ */
+ bool IsCharAt(int32_t aOffset, char aChar)
+ {
+ nsAutoString charAtOffset;
+ CharAt(aOffset, charAtOffset);
+ return charAtOffset.CharAt(0) == aChar;
+ }
+
+ /**
+ * Return true if terminal char is at the given offset.
+ */
+ bool IsLineEndCharAt(int32_t aOffset)
+ { return IsCharAt(aOffset, '\n'); }
+
+ /**
* Get a character before/at/after the given offset.
*
* @param aOffset [in] the given offset
* @param aShift [in] specifies whether to get a char before/at/after
* offset
* @param aChar [out] the character
* @param aStartOffset [out, optional] the start offset of the character
* @param aEndOffset [out, optional] the end offset of the character
@@ -283,22 +313,18 @@ protected:
return aOffset;
}
/**
* Return true if the given offset points to terminal empty line if any.
*/
bool IsEmptyLastLineOffset(int32_t aOffset)
{
- if (aOffset != static_cast<int32_t>(CharacterCount()))
- return false;
-
- nsAutoString lastChar;
- GetText(aOffset -1, -1, lastChar);
- return lastChar.EqualsLiteral("\n");
+ return aOffset == static_cast<int32_t>(CharacterCount()) &&
+ IsLineEndCharAt(aOffset - 1);
}
/**
* Return an offset of the found word boundary.
*/
int32_t FindWordBoundary(int32_t aOffset, nsDirection aDirection,
EWordMovementType aWordMovementType)
{
--- a/accessible/tests/mochitest/text/test_atcaretoffset.html
+++ b/accessible/tests/mochitest/text/test_atcaretoffset.html
@@ -51,17 +51,17 @@
testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
[ "textarea" ]);
testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
[ "textarea" ]);
testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
- "textarea", kTodo, kTodo, kOk);
+ [ "textarea" ]);
}
this.getID = function moveToLastLineEnd_getID()
{
return "move to last line end";
}
}
@@ -82,17 +82,17 @@
testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
[ "textarea" ]);
testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
[ "textarea" ]);
testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
- "textarea", kTodo, kTodo, kOk);
+ [ "textarea" ]);
}
this.getID = function moveToLastLineStart_getID()
{
return "move to last line start";
}
}
@@ -176,17 +176,17 @@
testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
[ "textarea" ]);
testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "", 0, 0,
[ "textarea" ]);
testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "", 0, 0,
- "textarea", kOk, kOk, kOk);
+ [ "textarea" ]);
}
this.getID = function moveToFirstLineStart_getID()
{
return "move to first line start";
}
}
--- a/addon-sdk/source/app-extension/bootstrap.js
+++ b/addon-sdk/source/app-extension/bootstrap.js
@@ -215,16 +215,18 @@ function startup(data, reasonCode) {
loadReason: reason,
prefixURI: prefixURI,
// Add-on URI.
rootURI: rootURI,
// options used by system module.
// File to write 'OK' or 'FAIL' (exit code emulation).
resultFile: options.resultFile,
+ // File to write stdout.
+ logFile: options.logFile,
// Arguments passed as --static-args
staticArgs: options.staticArgs,
// Arguments related to test runner.
modules: {
'@test/options': {
allTestModules: options.allTestModules,
iterations: options.iterations,
--- a/addon-sdk/source/app-extension/install.rdf
+++ b/addon-sdk/source/app-extension/install.rdf
@@ -12,18 +12,18 @@
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:unpack>false</em:unpack>
<!-- Firefox -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>21.0</em:minVersion>
- <em:maxVersion>25.0a1</em:maxVersion>
+ <em:minVersion>19.0</em:minVersion>
+ <em:maxVersion>22.0a1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Test App</em:name>
<em:description>Harness for tests.</em:description>
<em:creator>Mozilla Corporation</em:creator>
<em:homepageURL></em:homepageURL>
--- a/addon-sdk/source/doc/dev-guide-source/cfx-tool.md
+++ b/addon-sdk/source/doc/dev-guide-source/cfx-tool.md
@@ -635,24 +635,25 @@ of `updateURL`.
Note that as the [add-on documentation](https://developer.mozilla.org/en/extension_versioning,_update_and_compatibility#Securing_Updates)
explains, you should make sure the update procedure for your add-on is secure,
and this usually involves using HTTPS for the links.
So if we run the following command:
<pre>
- cfx xpi --update-link https://example.com/addon/latest/pluginName.xpi --update-url https://example.com/addon/update_rdf/pluginName.update.rdf
+ cfx xpi --update-link https://example.com/addon/latest
+ --update-url https://example.com/addon/update_rdf
</pre>
`cfx` will create two files:
* an XPI file which embeds
-`https://example.com/addon/update_rdf/pluginName.update.rdf` as the value of `updateURL`
-* an RDF file which embeds `https://example.com/addon/latest/pluginName.xpi` as the value of
+`https://example.com/addon/update_rdf` as the value of `updateURL`
+* an RDF file which embeds `https://example.com/addon/latest` as the value of
`updateLink`.
### Supported Options ###
As with `cfx run` you can point `cfx` at a different `package.json` file using
the `--pkgdir` option. You can also embed arguments in the XPI using the
`--static-args` option: if you do this the arguments will be passed to your
add-on whenever it is run.
--- a/addon-sdk/source/doc/module-source/sdk/self.md
+++ b/addon-sdk/source/doc/module-source/sdk/self.md
@@ -8,23 +8,16 @@ The `self` module provides access to dat
as a whole. It also provides access to the
[Program ID](dev-guide/guides/program-id.html), a value which is
unique for each add-on.
Note that the `self` module is completely different from the global `self`
object accessible to content scripts, which is used by a content script to
[communicate with the add-on code](dev-guide/guides/content-scripts/using-port.html).
-<api name="uri">
-@property {string}
-This property represents an add-on associated unique URI string.
-This URI can be used for APIs which require a valid URI string, such as the
-[passwords](modules/sdk/passwords.html) module.
-</api>
-
<api name="id">
@property {string}
This property is a printable string that is unique for each add-on. It comes
from the `id` property set in the `package.json` file in the main package
(i.e. the package in which you run `cfx xpi`). While not generally of use to
add-on code directly, it can be used by internal API code to index local
storage and other resources that are associated with a particular add-on.
Eventually, this ID will be unspoofable (see
deleted file mode 100644
--- a/addon-sdk/source/doc/module-source/sdk/test/utils.md
+++ /dev/null
@@ -1,90 +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/. -->
-
-The `test/utils` module provides additional helper methods to be used in
-the CommonJS Unit Testing test suite.
-
-## Before and After
-
-Helper functions `before()` and `after()` are available for running a function
-before or after each test in a suite. They're useful when you need to
-guarantee a particular state before running a test, and to clean up
-after your test.
-
- let { before, after } = require('sdk/test/utils');
- let { search } = require('sdk/places/bookmarks');
-
- exports.testCountBookmarks = function (assert, done) {
- search().on('end', function (results) {
- assert.equal(results, 0, 'should be no bookmarks');
- done();
- });
- };
-
- before(exports, function (name, assert) {
- removeAllBookmarks();
- });
-
- require('sdk/test').run(exports);
-
-Both `before` and `after` may be asynchronous. To make them asynchronous,
-pass a third argument `done`, which is a function to call when you have
-finished:
-
- let { before, after } = require('sdk/test/utils');
- let { search } = require('sdk/places/bookmarks');
-
- exports.testCountBookmarks = function (assert, done) {
- search().on('end', function (results) {
- assert.equal(results, 0, 'should be no bookmarks');
- done();
- });
- };
-
- before(exports, function (name, assert, done) {
- removeAllBookmarksAsync(function () {
- done();
- });
- });
-
- require('sdk/test').run(exports);
-
-<api name="before">
-@function
- Runs `beforeFn` before each test in the file. May be asynchronous
- if `beforeFn` accepts a third argument, which is a callback.
-
- @param exports {Object}
- A test file's `exports` object
- @param beforeFn {Function}
- The function to be called before each test. It has two arguments,
- or three if it is asynchronous:
-
- * the first argument is the test's name as a `String`.
- * the second argument is the `assert` object for the test.
- * the third, optional, argument is a callback. If the callback is
- defined, then the `beforeFn` is considered asynchronous, and the
- callback must be invoked before the test runs.
-
-</api>
-
-<api name="after">
-@function
- Runs `afterFn` after each test in the file. May be asynchronous
- if `afterFn` accepts a third argument, which is a callback.
-
- @param exports {Object}
- A test file's `exports` object
- @param afterFn {Function}
- The function to be called after each test. It has two arguments,
- or three if it is asynchronous:
-
- * the first argument is the test's name as a `String`.
- * the second argument is the `assert` object for the test.
- * the third, optional, argument is a callback. If the callback is
- defined, then the `afterFn` is considered asynchronous, and the
- callback must be invoked before the next test runs.
-
-</api>
-
--- a/addon-sdk/source/doc/module-source/sdk/util/array.md
+++ b/addon-sdk/source/doc/module-source/sdk/util/array.md
@@ -1,13 +1,13 @@
<!-- 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/. -->
-The `util/array` module provides simple helper functions for working with
+The `util/array` module provides simple helper functions for working with
arrays.
<api name="has">
@function
Returns `true` if the given [`Array`](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array) contains the element or `false` otherwise.
A simplified version of `array.indexOf(element) >= 0`.
let { has } = require('sdk/util/array');
@@ -24,17 +24,17 @@ A simplified version of `array.indexOf(e
The element to search for in the array.
@returns {boolean}
A boolean indicating whether or not the element was found in the array.
</api>
<api name="hasAny">
@function
-Returns `true` if the given [`Array`](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array) contains any of the elements in the
+Returns `true` if the given [`Array`](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array) contains any of the elements in the
`elements` array, or `false` otherwise.
let { hasAny } = require('sdk/util/array');
let a = ['rock', 'roll', 100];
hasAny(a, ['rock', 'bright', 'light']); // true
hasAny(a, ['rush', 'coil', 'jet']); // false
@@ -79,17 +79,17 @@ does not add the element and returns `fa
If the given [array](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array) contains the given element, this function
removes the element from the array and returns `true`. Otherwise, this function
does not alter the array and returns `false`.
let { remove } = require('sdk/util/array');
let a = ['alice', 'bob', 'carol'];
remove(a, 'dave'); // false
- remove(a, 'bob'); // true
+ remove(a, 'bob'); // true
remove(a, 'bob'); // false
console.log(a); // ['alice', 'carol']
@param array {array}
The array to remove the element from.
@param element {*}
@@ -149,29 +149,8 @@ Iterates over an [iterator](https://deve
@param iterator {iterator}
The [`Iterator`](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Iterators_and_Generators#Iterators) object over which to iterate and place results into an array.
@returns {array}
The iterator's results in an array.
</api>
-<api name="find">
-@function
-Iterates over given `array` and applies given `predicate` function until
-`predicate(element)` is `true`. If such element is found it's retured back
-otherwise third optional `fallback` argument is returned back. If fallback
-is not provided returns `undefined`.
-
- let { find } = require('sdk/util/array');
- let isOdd = (x) => x % 2;
- find([2, 4, 5, 7, 8, 9], isOdd); // => 5
- find([2, 4, 6, 8], isOdd); // => undefiend
- find([2, 4, 6, 8], isOdd, null); // => null
-
- fromIterator(i) // ['otoro', 'unagi', 'keon']
-
-@param iterator {iterator}
- The [`Iterator`](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Iterators_and_Generators#Iterators) object over which to iterate and place results into an array.
-
-@returns {array}
- The iterator's results in an array.
-</api>
--- a/addon-sdk/source/lib/sdk/console/plain-text.js
+++ b/addon-sdk/source/lib/sdk/console/plain-text.js
@@ -3,77 +3,134 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "unstable"
};
-const { Cc, Ci, Cu, Cr } = require("chrome");
+const { Cc, Ci } = require("chrome");
const self = require("../self");
+const traceback = require("./traceback")
const prefs = require("../preferences/service");
const { merge } = require("../util/object");
-const { ConsoleAPI } = Cu.import("resource://gre/modules/devtools/Console.jsm");
+const { partial } = require("../lang/functional");
+const LEVELS = {
+ "all": Number.MIN_VALUE,
+ "debug": 20000,
+ "info": 30000,
+ "warn": 40000,
+ "error": 50000,
+ "off": Number.MAX_VALUE,
+};
const DEFAULT_LOG_LEVEL = "error";
const ADDON_LOG_LEVEL_PREF = "extensions." + self.id + ".sdk.console.logLevel";
const SDK_LOG_LEVEL_PREF = "extensions.sdk.console.logLevel";
-let logLevel = DEFAULT_LOG_LEVEL;
+let logLevel;
+
function setLogLevel() {
- logLevel = prefs.get(ADDON_LOG_LEVEL_PREF,
- prefs.get(SDK_LOG_LEVEL_PREF,
- DEFAULT_LOG_LEVEL));
+ logLevel = prefs.get(ADDON_LOG_LEVEL_PREF, prefs.get(SDK_LOG_LEVEL_PREF,
+ DEFAULT_LOG_LEVEL));
}
setLogLevel();
let logLevelObserver = {
- QueryInterface: function(iid) {
- if (!iid.equals(Ci.nsIObserver) &&
- !iid.equals(Ci.nsISupportsWeakReference) &&
- !iid.equals(Ci.nsISupports))
- throw Cr.NS_ERROR_NO_INTERFACE;
- return this;
- },
observe: function(subject, topic, data) {
setLogLevel();
}
};
let branch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService).
getBranch(null);
-branch.addObserver(ADDON_LOG_LEVEL_PREF, logLevelObserver, true);
-branch.addObserver(SDK_LOG_LEVEL_PREF, logLevelObserver, true);
+branch.addObserver(ADDON_LOG_LEVEL_PREF, logLevelObserver, false);
+branch.addObserver(SDK_LOG_LEVEL_PREF, logLevelObserver, false);
+
+function stringify(arg) {
+ try {
+ return String(arg);
+ }
+ catch(ex) {
+ return "<toString() error>";
+ }
+}
+
+function stringifyArgs(args) {
+ return Array.map(args, stringify).join(" ");
+}
+
+function message(print, level) {
+ if (LEVELS[level] < LEVELS[logLevel])
+ return;
+
+ let args = Array.slice(arguments, 2);
+
+ print(level + ": " + self.name + ": " + stringifyArgs(args) + "\n", level);
+}
+
+function errorMessage(print, e) {
+ // Some platform exception doesn't have name nor message but
+ // can be stringified to a meaningfull message
+ var fullString = ("An exception occurred.\n" +
+ (e.name ? e.name + ": " : "") +
+ (e.message ? e.message : e.toString()) + "\n" +
+ (e.fileName ? traceback.sourceURI(e.fileName) + " " +
+ e.lineNumber + "\n"
+ : "") +
+ traceback.format(e));
+
+ message(print, "error", fullString);
+}
+
+function traceMessage(print) {
+ var stack = traceback.get();
+ stack.splice(-1, 1);
+
+ message(print, "info", traceback.format(stack));
+}
function PlainTextConsole(print) {
+ if (!print)
+ print = dump;
- let consoleOptions = {
- prefix: self.name + ": ",
- maxLogLevel: logLevel,
- dump: print
- };
- let console = new ConsoleAPI(consoleOptions);
+ if (print === dump) {
+ // If we're just using dump(), auto-enable preferences so
+ // that the developer actually sees the console output.
+ var prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+ prefs.setBoolPref("browser.dom.window.dump.enabled", true);
+ }
- // As we freeze the console object, we can't modify this property afterward
- Object.defineProperty(console, "maxLogLevel", {
- get: function() {
- return logLevel;
- }
+ merge(this, {
+ log: partial(message, print, "info"),
+ info: partial(message, print, "info"),
+ warn: partial(message, print, "warn"),
+ error: partial(message, print, "error"),
+ debug: partial(message, print, "debug"),
+ exception: partial(errorMessage, print),
+ trace: partial(traceMessage, print),
+
+ dir: function dir() {},
+ group: function group() {},
+ groupCollapsed: function groupCollapsed() {},
+ groupEnd: function groupEnd() {},
+ time: function time() {},
+ timeEnd: function timeEnd() {}
});
// We defined the `__exposedProps__` in our console chrome object.
// Although it seems redundant, because we use `createObjectIn` too, in
// worker.js, we are following what `ConsoleAPI` does. See:
// http://mxr.mozilla.org/mozilla-central/source/dom/base/ConsoleAPI.js#132
//
// Meanwhile we're investigating with the platform team if `__exposedProps__`
// are needed, or are just a left-over.
- console.__exposedProps__ = Object.keys(ConsoleAPI.prototype).reduce(function(exposed, prop) {
+ this.__exposedProps__ = Object.keys(this).reduce(function(exposed, prop) {
exposed[prop] = "r";
return exposed;
}, {});
- Object.freeze(console);
- return console;
+ Object.freeze(this);
};
exports.PlainTextConsole = PlainTextConsole;
--- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js
+++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js
@@ -4,18 +4,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "deprecated"
};
-const { Cu } = require("chrome");
-const memory = require("./memory");
+const memory = require('./memory');
var timer = require("../timers");
var cfxArgs = require("@test/options");
exports.findAndRunTests = function findAndRunTests(options) {
var TestFinder = require("./unit-test-finder").TestFinder;
var finder = new TestFinder({
filter: options.filter,
testInProcess: options.testInProcess,
@@ -439,28 +438,27 @@ TestRunner.prototype = {
// We may already have registered a timeout callback
if (this.waitTimeout)
timer.clearTimeout(this.waitTimeout);
this.waitTimeout = timer.setTimeout(tiredOfWaiting, ms);
},
startMany: function startMany(options) {
- let runNextTest = (self) => Cu.schedulePreciseGC(_ => {
+ function runNextTest(self) {
var test = options.tests.shift();
if (options.stopOnError && self.test && self.test.failed) {
self.console.error("aborted: test failed and --stop-on-error was specified");
options.onDone(self);
} else if (test) {
self.start({test: test, onDone: runNextTest});
} else {
options.onDone(self);
}
- });
-
+ }
runNextTest(this);
},
start: function start(options) {
this.test = options.test;
this.test.passed = 0;
this.test.failed = 0;
this.test.errors = {};
--- a/addon-sdk/source/lib/sdk/io/buffer.js
+++ b/addon-sdk/source/lib/sdk/io/buffer.js
@@ -4,257 +4,79 @@
*/
"use strict";
module.metadata = {
"stability": "experimental"
};
-const { Cu } = require("chrome");
-const { TextEncoder, TextDecoder } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
-
-exports.TextEncoder = TextEncoder;
-exports.TextDecoder = TextDecoder;
-
+const { Cc, Ci, CC } = require("chrome");
+const { Class } = require("../core/heritage");
-function Buffer(subject, encoding) {
- var type = typeof(subject);
- switch (type) {
- case "number":
- // Create typed array of the given size if number.
- return Uint8Array(subject > 0 ? Math.floor(subject) : 0);
- case "string":
- // If string encode it and use buffer for the returned Uint8Array
- // to create a local patched version that acts like node buffer.
- encoding = encoding || "utf8";
- return Uint8Array(TextEncoder(encoding).encode(subject).buffer);
- case "object":
- // If array or alike just make a copy with a local patched prototype.
- return Uint8Array(subject);
- default:
- throw new TypeError("must start with number, buffer, array or string");
- }
-}
-exports.Buffer = Buffer;
-
-// Tests if `value` is a Buffer.
-Buffer.isBuffer = value => value instanceof Buffer
-
-// Returns true if the encoding is a valid encoding argument & false otherwise
-Buffer.isEncoding = encoding => !!ENCODINGS[String(encoding).toLowerCase()]
+const Transcoder = CC("@mozilla.org/intl/scriptableunicodeconverter",
+ "nsIScriptableUnicodeConverter");
-// Gives the actual byte length of a string. encoding defaults to 'utf8'.
-// This is not the same as String.prototype.length since that returns the
-// number of characters in a string.
-Buffer.byteLength = (value, encoding = "utf8") =>
- TextEncoder(encoding).encode(value).byteLength
-
-// Direct copy of the nodejs's buffer implementation:
-// https://github.com/joyent/node/blob/b255f4c10a80343f9ce1cee56d0288361429e214/lib/buffer.js#L146-L177
-Buffer.concat = function(list, length) {
- if (!Array.isArray(list))
- throw new TypeError('Usage: Buffer.concat(list[, length])');
-
- if (typeof length === 'undefined') {
- length = 0;
- for (var i = 0; i < list.length; i++)
- length += list[i].length;
- } else {
- length = ~~length;
- }
-
- if (length < 0)
- length = 0;
-
- if (list.length === 0)
- return new Buffer(0);
- else if (list.length === 1)
- return list[0];
-
- if (length < 0)
- throw new RangeError('length is not a positive number');
-
- var buffer = new Buffer(length);
- var pos = 0;
- for (var i = 0; i < list.length; i++) {
- var buf = list[i];
- buf.copy(buffer, pos);
- pos += buf.length;
- }
-
- return buffer;
-};
+var Buffer = Class({
+ initialize: function initialize(subject, encoding) {
+ subject = subject ? subject.valueOf() : 0;
+ let length = typeof subject === "number" ? subject : 0;
+ this.encoding = encoding || "utf-8";
+ this.valueOf(Array.isArray(subject) ? subject : new Array(length));
-// Node buffer is very much like Uint8Array although it has bunch of methods
-// that typically can be used in combination with `DataView` while preserving
-// access by index. Since in SDK echo module has it's own set of bult-ins it
-// ok to patch ours to make it nodejs Buffer compatible.
-Buffer.prototype = Uint8Array.prototype;
-Object.defineProperties(Buffer.prototype, {
- view: {
- get: function() this._view || (this._view = DataView(this.buffer))
+ if (typeof subject === "string") this.write(subject);
+ },
+ get length() {
+ return this.valueOf().length;
+ },
+ get: function get(index) {
+ return this.valueOf()[index];
+ },
+ set: function set(index, value) {
+ return this.valueOf()[index] = value;
},
- toString: {
- value: function(encoding, start, end) {
- encoding = !!encoding ? (encoding + '').toLowerCase() : "utf8";
- start = Math.max(0, ~~start);
- end = Math.min(this.length, end === void(0) ? this.length : ~~end);
- return TextDecoder(encoding).decode(this.subarray(start, end));
- }
- },
- toJSON: {
- value: function() ({ type: "Buffer", data: Array.slice(this, 0) })
+ valueOf: function valueOf(value) {
+ Object.defineProperty(this, "valueOf", {
+ value: Array.prototype.valueOf.bind(value),
+ configurable: false,
+ writable: false,
+ enumerable: false
+ });
},
- get: {
- value: function(offset) this[offset]
- },
- set: {
- value: function(offset, value) this[offset] = value
- },
- copy: {
- value: function(target, offset, start, end)
- Uint8Array.set(target, this.subarray(start, end), offset)
- },
- slice: {
- value: Buffer.prototype.subarray
+ toString: function toString(encoding, start, end) {
+ let bytes = this.valueOf().slice(start || 0, end || this.length);
+ let transcoder = Transcoder();
+ transcoder.charset = String(encoding || this.encoding).toUpperCase();
+ return transcoder.convertFromByteArray(bytes, this.length);
},
- write: {
- value: function(string, offset, length, encoding = "utf8") {
- if (typeof(offset) === "string")
- ([offset, length, encoding]) = [0, null, offset];
- else if (typeof(length) === "string")
- ([length, encoding]) = [null, length];
-
- offset = ~~offset;
- length = length || this.length - offset;
- let buffer = TextEncoder(encoding).encode(string);
- let result = Math.min(buffer.length, length);
- if (buffer.length !== length)
- buffer = buffer.subarray(0, length);
- Uint8Array.set(this, buffer, offset);
- return result;
- }
+ toJSON: function toJSON() {
+ return this.toString()
},
- fill: {
- value: function fill(value, start, end) {
- value = value || 0;
- start = start || 0;
- end = end || this.length;
-
- if (typeof(value) === "string")
- value = value.charCodeAt(0);
- if (typeof(value) !== "number" || isNaN(value))
- throw TypeError("value is not a number");
- if (end < start)
- throw new RangeError("end < start");
-
- // Fill 0 bytes; we're done
- if (end === start)
- return 0;
- if (this.length == 0)
- return 0;
-
- if (start < 0 || start >= this.length)
- throw RangeError("start out of bounds");
-
- if (end < 0 || end > this.length)
- throw RangeError("end out of bounds");
-
- let index = start;
- while (index < end) this[index++] = value;
- }
+ write: function write(string, offset, encoding) {
+ offset = Math.max(offset || 0, 0);
+ let value = this.valueOf();
+ let transcoder = Transcoder();
+ transcoder.charset = String(encoding || this.encoding).toUpperCase();
+ let bytes = transcoder.convertToByteArray(string, {});
+ value.splice.apply(value, [
+ offset,
+ Math.min(value.length - offset, bytes.length, bytes)
+ ].concat(bytes));
+ return bytes;
+ },
+ slice: function slice(start, end) {
+ return new Buffer(this.valueOf().slice(start, end));
+ },
+ copy: function copy(target, offset, start, end) {
+ offset = Math.max(offset || 0, 0);
+ target = target.valueOf();
+ let bytes = this.valueOf();
+ bytes.slice(Math.max(start || 0, 0), end);
+ target.splice.apply(target, [
+ offset,
+ Math.min(target.length - offset, bytes.length),
+ ].concat(bytes));
}
});
-
-// Define nodejs Buffer's getter and setter functions that just proxy
-// to internal DataView's equivalent methods.
-[["readUInt16LE", "getUint16", true],
- ["readUInt16BE", "getUint16", false],
- ["readInt16LE", "getInt16", true],
- ["readInt16BE", "getInt16", false],
- ["readUInt32LE", "getInt32", true],
- ["readUInt32BE", "getInt32", false],
- ["readInt32LE", "getInt32", true],
- ["readInt32BE", "getInt32", false],
- ["readFloatLE", "getFloat32", true],
- ["readFloatBE", "getFloat32", false],
- ["readDoubleLE", "getFloat64", true],
- ["readDoubleBE", "getFloat64", false],
- ["readUInt8", "getUint8"],
- ["readInt8", "getInt8"]].forEach(([alias, name, littleEndian]) => {
- Object.defineProperty(Buffer.prototype, alias, {
- value: function(offset) this.view[name](offset, littleEndian)
- });
-});
-
-[["writeUInt16LE", "setUint16", true],
- ["writeUInt16BE", "setUint16", false],
- ["writeInt16LE", "setInt16", true],
- ["writeInt16BE", "setInt16", false],
- ["writeUInt32LE", "setUint32", true],
- ["writeUInt32BE", "setUint32", false],
- ["writeInt32LE", "setInt32", true],
- ["writeInt32BE", "setInt32", false],
- ["writeFloatLE", "setFloat32", true],
- ["writeFloatBE", "setFloat32", false],
- ["writeDoubleLE", "setFloat64", true],
- ["writeDoubleBE", "setFloat64", false],
- ["writeUInt8", "setUint8"],
- ["writeInt8", "setInt8"]].forEach(([alias, name, littleEndian]) => {
- Object.defineProperty(Buffer.prototype, alias, {
- value: function(value, offset) this.view[name](offset, value, littleEndian)
- });
-});
-
-
-// List of supported encodings taken from:
-// http://mxr.mozilla.org/mozilla-central/source/dom/encoding/labelsencodings.properties
-const ENCODINGS = { "unicode-1-1-utf-8": 1, "utf-8": 1, "utf8": 1,
- "866": 1, "cp866": 1, "csibm866": 1, "ibm866": 1, "csisolatin2": 1,
- "iso-8859-2": 1, "iso-ir-101": 1, "iso8859-2": 1, "iso88592": 1,
- "iso_8859-2": 1, "iso_8859-2:1987": 1, "l2": 1, "latin2": 1, "csisolatin3": 1,
- "iso-8859-3": 1, "iso-ir-109": 1, "iso8859-3": 1, "iso88593": 1,
- "iso_8859-3": 1, "iso_8859-3:1988": 1, "l3": 1, "latin3": 1, "csisolatin4": 1,
- "iso-8859-4": 1, "iso-ir-110": 1, "iso8859-4": 1, "iso88594": 1,
- "iso_8859-4": 1, "iso_8859-4:1988": 1, "l4": 1, "latin4": 1,
- "csisolatincyrillic": 1, "cyrillic": 1, "iso-8859-5": 1, "iso-ir-144": 1,
- "iso8859-5": 1, "iso88595": 1, "iso_8859-5": 1, "iso_8859-5:1988": 1,
- "arabic": 1, "asmo-708": 1, "csiso88596e": 1, "csiso88596i": 1,
- "csisolatinarabic": 1, "ecma-114": 1, "iso-8859-6": 1, "iso-8859-6-e": 1,
- "iso-8859-6-i": 1, "iso-ir-127": 1, "iso8859-6": 1, "iso88596": 1,
- "iso_8859-6": 1, "iso_8859-6:1987": 1, "csisolatingreek": 1, "ecma-118": 1,
- "elot_928": 1, "greek": 1, "greek8": 1, "iso-8859-7": 1, "iso-ir-126": 1,
- "iso8859-7": 1, "iso88597": 1, "iso_8859-7": 1, "iso_8859-7:1987": 1,
- "sun_eu_greek": 1, "csiso88598e": 1, "csisolatinhebrew": 1, "hebrew": 1,
- "iso-8859-8": 1, "iso-8859-8-e": 1, "iso-ir-138": 1, "iso8859-8": 1,
- "iso88598": 1, "iso_8859-8": 1, "iso_8859-8:1988": 1, "visual": 1,
- "csiso88598i": 1, "iso-8859-8-i": 1, "logical": 1, "csisolatin6": 1,
- "iso-8859-10": 1, "iso-ir-157": 1, "iso8859-10": 1, "iso885910": 1,
- "l6": 1, "latin6": 1, "iso-8859-13": 1, "iso8859-13": 1, "iso885913": 1,
- "iso-8859-14": 1, "iso8859-14": 1, "iso885914": 1, "csisolatin9": 1,
- "iso-8859-15": 1, "iso8859-15": 1, "iso885915": 1, "iso_8859-15": 1,
- "l9": 1, "iso-8859-16": 1, "cskoi8r": 1, "koi": 1, "koi8": 1, "koi8-r": 1,
- "koi8_r": 1, "koi8-u": 1, "csmacintosh": 1, "mac": 1, "macintosh": 1,
- "x-mac-roman": 1, "dos-874": 1, "iso-8859-11": 1, "iso8859-11": 1,
- "iso885911": 1, "tis-620": 1, "windows-874": 1, "cp1250": 1,
- "windows-1250": 1, "x-cp1250": 1, "cp1251": 1, "windows-1251": 1,
- "x-cp1251": 1, "ansi_x3.4-1968": 1, "ascii": 1, "cp1252": 1, "cp819": 1,
- "csisolatin1": 1, "ibm819": 1, "iso-8859-1": 1, "iso-ir-100": 1,
- "iso8859-1": 1, "iso88591": 1, "iso_8859-1": 1, "iso_8859-1:1987": 1,
- "l1": 1, "latin1": 1, "us-ascii": 1, "windows-1252": 1, "x-cp1252": 1,
- "cp1253": 1, "windows-1253": 1, "x-cp1253": 1, "cp1254": 1, "csisolatin5": 1,
- "iso-8859-9": 1, "iso-ir-148": 1, "iso8859-9": 1, "iso88599": 1,
- "iso_8859-9": 1, "iso_8859-9:1989": 1, "l5": 1, "latin5": 1,
- "windows-1254": 1, "x-cp1254": 1, "cp1255": 1, "windows-1255": 1,
- "x-cp1255": 1, "cp1256": 1, "windows-1256": 1, "x-cp1256": 1, "cp1257": 1,
- "windows-1257": 1, "x-cp1257": 1, "cp1258": 1, "windows-1258": 1,
- "x-cp1258": 1, "x-mac-cyrillic": 1, "x-mac-ukrainian": 1, "chinese": 1,
- "csgb2312": 1, "csiso58gb231280": 1, "gb2312": 1, "gb_2312": 1,
- "gb_2312-80": 1, "gbk": 1, "iso-ir-58": 1, "x-gbk": 1, "gb18030": 1,
- "hz-gb-2312": 1, "big5": 1, "big5-hkscs": 1, "cn-big5": 1, "csbig5": 1,
- "x-x-big5": 1, "cseucpkdfmtjapanese": 1, "euc-jp": 1, "x-euc-jp": 1,
- "csiso2022jp": 1, "iso-2022-jp": 1, "csshiftjis": 1, "ms_kanji": 1,
- "shift-jis": 1, "shift_jis": 1, "sjis": 1, "windows-31j": 1, "x-sjis": 1,
- "cseuckr": 1, "csksc56011987": 1, "euc-kr": 1, "iso-ir-149": 1, "korean": 1,
- "ks_c_5601-1987": 1, "ks_c_5601-1989": 1, "ksc5601": 1, "ksc_5601": 1,
- "windows-949": 1, "csiso2022kr": 1, "iso-2022-kr": 1, "utf-16": 1,
- "utf-16le": 1, "utf-16be": 1, "x-user-defined": 1 };
+Buffer.isBuffer = function isBuffer(buffer) {
+ return buffer instanceof Buffer
+};
+exports.Buffer = Buffer;
--- a/addon-sdk/source/lib/sdk/io/fs.js
+++ b/addon-sdk/source/lib/sdk/io/fs.js
@@ -7,22 +7,20 @@
module.metadata = {
"stability": "experimental"
};
const { Cc, Ci, CC } = require("chrome");
const { setTimeout } = require("../timers");
const { Stream, InputStream, OutputStream } = require("./stream");
-const { emit, on } = require("../event/core");
const { Buffer } = require("./buffer");
const { ns } = require("../core/namespace");
const { Class } = require("../core/heritage");
-
const nsILocalFile = CC("@mozilla.org/file/local;1", "nsILocalFile",
"initWithPath");
const FileOutputStream = CC("@mozilla.org/network/file-output-stream;1",
"nsIFileOutputStream", "init");
const FileInputStream = CC("@mozilla.org/network/file-input-stream;1",
"nsIFileInputStream", "init");
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream", "setInputStream");
@@ -30,18 +28,16 @@ const BinaryOutputStream = CC("@mozilla.
"nsIBinaryOutputStream", "setOutputStream");
const StreamPump = CC("@mozilla.org/network/input-stream-pump;1",
"nsIInputStreamPump", "init");
const { createOutputTransport, createInputTransport } =
Cc["@mozilla.org/network/stream-transport-service;1"].
getService(Ci.nsIStreamTransportService);
-const { OPEN_UNBUFFERED } = Ci.nsITransport;
-
const { REOPEN_ON_REWIND, DEFER_OPEN } = Ci.nsIFileInputStream;
const { DIRECTORY_TYPE, NORMAL_FILE_TYPE } = Ci.nsIFile;
const { NS_SEEK_SET, NS_SEEK_CUR, NS_SEEK_END } = Ci.nsISeekableStream;
const FILE_PERMISSION = parseInt("0666", 8);
const PR_UINT32_MAX = 0xfffffff;
// Values taken from:
@@ -156,26 +152,24 @@ const ReadStream = Class({
input.QueryInterface(Ci.nsISeekableStream).seek(NS_SEEK_SET, position);
// We use `nsIStreamTransportService` service to transform blocking
// file input stream into a fully asynchronous stream that can be written
// without blocking the main thread.
let transport = createInputTransport(input, position, length, false);
// Open an input stream on a transport. We don"t pass flags to guarantee
// non-blocking stream semantics. Also we use defaults for segment size &
// count.
- InputStream.prototype.initialize.call(this, {
- asyncInputStream: transport.openInputStream(null, 0, 0)
- });
+ let asyncInputStream = transport.openInputStream(null, 0, 0);
+ let binaryInputStream = BinaryInputStream(asyncInputStream);
+ nsIBinaryInputStream(fd, binaryInputStream);
+ let pump = StreamPump(asyncInputStream, position, length, 0, 0, false);
- // Close file descriptor on end and destroy the stream.
- on(this, "end", _ => {
- this.destroy();
- emit(this, "close");
+ InputStream.prototype.initialize.call(this, {
+ input: binaryInputStream, pump: pump
});
-
this.read();
},
destroy: function() {
closeSync(this.fd);
InputStream.prototype.destroy.call(this);
}
});
exports.ReadStream = ReadStream;
@@ -212,30 +206,31 @@ const WriteStream = Class({
output.QueryInterface(Ci.nsISeekableStream).seek(NS_SEEK_SET, position);
// We use `nsIStreamTransportService` service to transform blocking
// file output stream into a fully asynchronous stream that can be written
// without blocking the main thread.
let transport = createOutputTransport(output, position, -1, false);
// Open an output stream on a transport. We don"t pass flags to guarantee
// non-blocking stream semantics. Also we use defaults for segment size &
// count.
- OutputStream.prototype.initialize.call(this, {
- asyncOutputStream: transport.openOutputStream(OPEN_UNBUFFERED, 0, 0),
- output: output
- });
+ let asyncOutputStream = transport.openOutputStream(null, 0, 0);
+ // Finally we create a non-blocking binary output stream. This will allows
+ // us to write buffers as byte arrays without any further transcoding.
+ let binaryOutputStream = BinaryOutputStream(asyncOutputStream);
+ nsIBinaryOutputStream(fd, binaryOutputStream);
- // For write streams "finish" basically means close.
- on(this, "finish", _ => {
- this.destroy();
- emit(this, "close");
+ // Storing output stream so that it can beaccessed later.
+ OutputStream.prototype.initialize.call(this, {
+ output: binaryOutputStream,
+ asyncOutputStream: asyncOutputStream
});
},
destroy: function() {
+ closeSync(this.fd);
OutputStream.prototype.destroy.call(this);
- closeSync(this.fd);
}
});
exports.WriteStream = WriteStream;
exports.createWriteStream = function createWriteStream(path, options) {
return new WriteStream(path, options);
};
const Stats = Class({
@@ -365,17 +360,17 @@ exports.truncate = truncate;
function ftruncate(fd, length, callback) {
write(fd, new Buffer(length), 0, length, 0, function(error) {
callback(error);
});
}
exports.ftruncate = ftruncate;
-function ftruncateSync(fd, length = 0) {
+function ftruncateSync(fd, length) {
writeSync(fd, new Buffer(length), 0, length, 0);
}
exports.ftruncateSync = ftruncateSync;
function chownSync(path, uid, gid) {
throw Error("Not implemented yet!!");
}
exports.chownSync = chownSync;
@@ -634,18 +629,16 @@ exports.close = close;
/**
* Synchronous open(2).
*/
function openSync(path, flags, mode) {
let [ fd, flags, mode, file ] =
[ { path: path }, Flags(flags), Mode(mode), nsILocalFile(path) ];
- nsIFile(fd, file);
-
// If trying to open file for just read that does not exists
// need to throw exception as node does.
if (!file.exists() && !isWritable(flags))
throw FSError("open", "ENOENT", 34, path);
// If we want to open file in read mode we initialize input stream.
if (isReadable(flags)) {
let input = FileInputStream(file, flags, mode, DEFER_OPEN);
@@ -677,19 +670,17 @@ function writeSync(fd, buffer, offset, l
if (length + offset > buffer.length) {
throw Error("Length is extends beyond buffer");
}
else if (length + offset !== buffer.length) {
buffer = buffer.slice(offset, offset + length);
}
let writeStream = new WriteStream(fd, { position: position,
length: length });
-
- let output = BinaryOutputStream(nsIFileOutputStream(fd));
- nsIBinaryOutputStream(fd, output);
+ let output = nsIBinaryOutputStream(fd);
// We write content as a byte array as this will avoid any transcoding
// if content was a buffer.
output.writeByteArray(buffer.valueOf(), buffer.length);
output.flush();
};
exports.writeSync = writeSync;
/**
@@ -740,24 +731,20 @@ function readSync(fd, buffer, offset, le
// Setting a stream position, unless it"s `-1` which means current position.
if (position >= 0)
input.QueryInterface(Ci.nsISeekableStream).seek(NS_SEEK_SET, position);
// We use `nsIStreamTransportService` service to transform blocking
// file input stream into a fully asynchronous stream that can be written
// without blocking the main thread.
let binaryInputStream = BinaryInputStream(input);
let count = length === ALL ? binaryInputStream.available() : length;
- if (offset === 0) binaryInputStream.readArrayBuffer(count, buffer.buffer);
- else {
- let chunk = new Buffer(count);
- binaryInputStream.readArrayBuffer(count, chunk.buffer);
- chunk.copy(buffer, offset);
- }
+ var bytes = binaryInputStream.readByteArray(count);
+ buffer.copy.call(bytes, buffer, offset);
- return buffer.slice(offset, offset + count);
+ return bytes;
};
exports.readSync = readSync;
/**
* Read data from the file specified by `fd`.
*
* `buffer` is the buffer that the data will be written to.
* `offset` is offset within the buffer where writing will start.
@@ -767,19 +754,19 @@ exports.readSync = readSync;
* `position` is an integer specifying where to begin reading from in the file.
* If `position` is `null`, data will be read from the current file position.
*
* The callback is given the three arguments, `(error, bytesRead, buffer)`.
*/
function read(fd, buffer, offset, length, position, callback) {
let bytesRead = 0;
let readStream = new ReadStream(fd, { position: position, length: length });
- readStream.on("data", function onData(data) {
- data.copy(buffer, offset + bytesRead);
- bytesRead += data.length;
+ readStream.on("data", function onData(chunck) {
+ chunck.copy(buffer, offset + bytesRead);
+ bytesRead += chunck.length;
});
readStream.on("end", function onEnd() {
callback(null, bytesRead, buffer);
readStream.destroy();
});
};
exports.read = read;
@@ -789,52 +776,44 @@ exports.read = read;
* contents of the file.
*/
function readFile(path, encoding, callback) {
if (isFunction(encoding)) {
callback = encoding
encoding = null
}
- let buffer = null;
+ let buffer = new Buffer();
try {
let readStream = new ReadStream(path);
- readStream.on("data", function(data) {
- if (!buffer) buffer = data;
- else {
- let bufferred = buffer
- buffer = new Buffer(buffer.length + data.length);
- bufferred.copy(buffer, 0);
- data.copy(buffer, bufferred.length);
- }
+ readStream.on("data", function(chunck) {
+ chunck.copy(buffer, buffer.length);
});
readStream.on("error", function onError(error) {
callback(error);
+ readStream.destroy();
});
readStream.on("end", function onEnd() {
- // Note: Need to destroy before invoking a callback
- // so that file descriptor is released.
+ callback(null, buffer);
readStream.destroy();
- callback(null, buffer);
});
} catch (error) {
setTimeout(callback, 0, error);
}
};
exports.readFile = readFile;
/**
* Synchronous version of `fs.readFile`. Returns the contents of the path.
* If encoding is specified then this function returns a string.
* Otherwise it returns a buffer.
*/
function readFileSync(path, encoding) {
+ let buffer = new Buffer();
let fd = openSync(path, "r");
- let size = fstatSync(fd).size;
- let buffer = new Buffer(size);
try {
readSync(fd, buffer, 0, ALL, 0);
}
finally {
closeSync(fd);
}
return buffer;
};
@@ -849,26 +828,23 @@ function writeFile(path, content, encodi
if (isFunction(encoding)) {
callback = encoding
encoding = null
}
if (isString(content))
content = new Buffer(content, encoding);
let writeStream = new WriteStream(path);
- let error = null;
-
- writeStream.end(content, function() {
- writeStream.destroy();
+ writeStream.on("error", function onError(error) {
callback(error);
+ writeStream.destroy();
});
-
- writeStream.on("error", function onError(reason) {
- error = reason;
+ writeStream.write(content, function onDrain() {
writeStream.destroy();
+ callback(null);
});
} catch (error) {
callback(error);
}
};
exports.writeFile = writeFile;
/**
--- a/addon-sdk/source/lib/sdk/io/stream.js
+++ b/addon-sdk/source/lib/sdk/io/stream.js
@@ -3,55 +3,109 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
"use strict";
module.metadata = {
"stability": "experimental"
};
-const { CC, Cc, Ci, Cu, Cr, components } = require("chrome");
const { EventTarget } = require("../event/target");
const { emit } = require("../event/core");
const { Buffer } = require("./buffer");
const { Class } = require("../core/heritage");
const { setTimeout } = require("../timers");
-
-
-const MultiplexInputStream = CC("@mozilla.org/io/multiplex-input-stream;1",
- "nsIMultiplexInputStream");
-const AsyncStreamCopier = CC("@mozilla.org/network/async-stream-copier;1",
- "nsIAsyncStreamCopier", "init");
-const StringInputStream = CC("@mozilla.org/io/string-input-stream;1",
- "nsIStringInputStream");
-const ArrayBufferInputStream = CC("@mozilla.org/io/arraybuffer-input-stream;1",
- "nsIArrayBufferInputStream");
+const { ns } = require("../core/namespace");
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream", "setInputStream");
-const InputStreamPump = CC("@mozilla.org/network/input-stream-pump;1",
- "nsIInputStreamPump", "init");
-
-const threadManager = Cc["@mozilla.org/thread-manager;1"].
- getService(Ci.nsIThreadManager);
-
-const eventTarget = Cc["@mozilla.org/network/socket-transport-service;1"].
- getService(Ci.nsIEventTarget);
-
-let isFunction = value => typeof(value) === "function"
+function isFunction(value) typeof value === "function"
function accessor() {
let map = new WeakMap();
- return function(target, value) {
- if (value)
- map.set(target, value);
- return map.get(target);
+ return function(fd, value) {
+ if (value === null) map.delete(fd);
+ if (value !== undefined) map.set(fd, value);
+ return map.get(fd);
}
}
+let nsIInputStreamPump = accessor();
+let nsIAsyncOutputStream = accessor();
+let nsIInputStream = accessor();
+let nsIOutputStream = accessor();
+
+
+/**
+ * Utility function / hack that we use to figure if output stream is closed.
+ */
+function isClosed(stream) {
+ // We assume that stream is not closed.
+ let isClosed = false;
+ stream.asyncWait({
+ // If `onClose` callback is called before outer function returns
+ // (synchronously) `isClosed` will be set to `true` identifying
+ // that stream is closed.
+ onOutputStreamReady: function onClose() isClosed = true
+
+ // `WAIT_CLOSURE_ONLY` flag overrides the default behavior, causing the
+ // `onOutputStreamReady` notification to be suppressed until the stream
+ // becomes closed.
+ }, stream.WAIT_CLOSURE_ONLY, 0, null);
+ return isClosed;
+}
+/**
+ * Utility function takes output `stream`, `onDrain`, `onClose` callbacks and
+ * calls one of this callbacks depending on stream state. It is guaranteed
+ * that only one called will be called and it will be called asynchronously.
+ * @param {nsIAsyncOutputStream} stream
+ * @param {Function} onDrain
+ * callback that is called when stream becomes writable.
+ * @param {Function} onClose
+ * callback that is called when stream becomes closed.
+ */
+function onStateChange(stream, target) {
+ let isAsync = false;
+ stream.asyncWait({
+ onOutputStreamReady: function onOutputStreamReady() {
+ // If `isAsync` was not yet set to `true` by the last line we know that
+ // `onOutputStreamReady` was called synchronously. In such case we just
+ // defer execution until next turn of event loop.
+ if (!isAsync)
+ return setTimeout(onOutputStreamReady, 0);
+
+ // As it"s not clear what is a state of the stream (TODO: Is there really
+ // no better way ?) we employ hack (see details in `isClosed`) to verify
+ // if stream is closed.
+ emit(target, isClosed(stream) ? "close" : "drain");
+ }
+ }, 0, 0, null);
+ isAsync = true;
+}
+
+function pump(stream) {
+ let input = nsIInputStream(stream);
+ nsIInputStreamPump(stream).asyncRead({
+ onStartRequest: function onStartRequest() {
+ emit(stream, "start");
+ },
+ onDataAvailable: function onDataAvailable(req, c, is, offset, count) {
+ try {
+ let bytes = input.readByteArray(count);
+ emit(stream, "data", new Buffer(bytes, stream.encoding));
+ } catch (error) {
+ emit(stream, "error", error);
+ stream.readable = false;
+ }
+ },
+ onStopRequest: function onStopRequest() {
+ stream.readable = false;
+ emit(stream, "end");
+ }
+ }, null);
+}
+
const Stream = Class({
extends: EventTarget,
initialize: function() {
this.readable = false;
this.writable = false;
this.encoding = null;
},
setEncoding: function setEncoding(encoding) {
@@ -61,18 +115,17 @@ const Stream = Class({
let source = this;
function onData(chunk) {
if (target.writable) {
if (false === target.write(chunk))
source.pause();
}
}
function onDrain() {
- if (source.readable)
- source.resume();
+ if (source.readable) source.resume();
}
function onEnd() {
target.end();
}
function onPause() {
source.pause();
}
function onResume() {
@@ -118,320 +171,154 @@ const Stream = Class({
emit(this, "resume");
},
destroySoon: function destroySoon() {
this.destroy();
}
});
exports.Stream = Stream;
-
-let nsIStreamListener = accessor();
-let nsIInputStreamPump = accessor();
-let nsIAsyncInputStream = accessor();
-let nsIBinaryInputStream = accessor();
-
-const StreamListener = Class({
- initialize: function(stream) {
- this.stream = stream;
- },
-
- // Next three methods are part of `nsIStreamListener` interface and are
- // invoked by `nsIInputStreamPump.asyncRead`.
- onDataAvailable: function(request, context, input, offset, count) {
- let stream = this.stream;
- let buffer = new ArrayBuffer(count);
- nsIBinaryInputStream(stream).readArrayBuffer(count, buffer);
- emit(stream, "data", new Buffer(buffer, stream.encoding));
- },
-
- // Next two methods implement `nsIRequestObserver` interface and are invoked
- // by `nsIInputStreamPump.asyncRead`.
- onStartRequest: function() {},
- // Called to signify the end of an asynchronous request. We only care to
- // discover errors.
- onStopRequest: function(request, context, status) {
- let stream = this.stream;
- stream.readable = false;
- if (!components.isSuccessCode(status))
- emit(stream, "error", status);
- else
- emit(stream, "end");
- }
-});
-
-
const InputStream = Class({
extends: Stream,
- readable: false,
- paused: false,
initialize: function initialize(options) {
- let { asyncInputStream } = options;
+ let { input, pump } = options;
this.readable = true;
-
- let binaryInputStream = new BinaryInputStream(asyncInputStream);
- let inputStreamPump = new InputStreamPump(asyncInputStream,
- -1, -1, 0, 0, false);
- let streamListener = new StreamListener(this);
-
- nsIAsyncInputStream(this, asyncInputStream);
- nsIInputStreamPump(this, inputStreamPump);
- nsIBinaryInputStream(this, binaryInputStream);
- nsIStreamListener(this, streamListener);
-
- this.asyncInputStream = asyncInputStream;
- this.inputStreamPump = inputStreamPump;
- this.binaryInputStream = binaryInputStream;
+ this.paused = false;
+ nsIInputStream(this, input);
+ nsIInputStreamPump(this, pump);
},
get status() nsIInputStreamPump(this).status,
- read: function() {
- nsIInputStreamPump(this).asyncRead(nsIStreamListener(this), null);
- },
+ read: function() pump(this),
pause: function pause() {
this.paused = true;
nsIInputStreamPump(this).suspend();
emit(this, "paused");
},
resume: function resume() {
this.paused = false;
nsIInputStreamPump(this).resume();
emit(this, "resume");
},
- close: function close() {
+ destroy: function destroy() {
this.readable = false;
- nsIInputStreamPump(this).cancel(Cr.NS_OK);
- nsIBinaryInputStream(this).close();
- nsIAsyncInputStream(this).close();
- },
- destroy: function destroy() {
- this.close();
+ try {
+ emit(this, "close", null);
+ nsIInputStreamPump(this).cancel(null);
+ nsIInputStreamPump(this, null);
- nsIInputStreamPump(this);
- nsIAsyncInputStream(this);
- nsIBinaryInputStream(this);
- nsIStreamListener(this);
+ nsIInputStream(this).close();
+ nsIInputStream(this, null);
+ } catch (error) {
+ emit(this, "error", error);
+ }
}
});
exports.InputStream = InputStream;
-
-
-let nsIRequestObserver = accessor();
-let nsIAsyncOutputStream = accessor();
-let nsIAsyncStreamCopier = accessor();
-let nsIMultiplexInputStream = accessor();
-
-const RequestObserver = Class({
- initialize: function(stream) {
- this.stream = stream;
- },
- // Method is part of `nsIRequestObserver` interface that is
- // invoked by `nsIAsyncStreamCopier.asyncCopy`.
- onStartRequest: function() {},
- // Method is part of `nsIRequestObserver` interface that is
- // invoked by `nsIAsyncStreamCopier.asyncCopy`.
- onStopRequest: function(request, context, status) {
- let stream = this.stream;
- stream.drained = true;
-
- // Remove copied chunk.
- let multiplexInputStream = nsIMultiplexInputStream(stream);
- multiplexInputStream.removeStream(0);
-
- // If there was an error report.
- if (!components.isSuccessCode(status))
- emit(stream, "error", status);
-
- // If there more chunks in queue then flush them.
- else if (multiplexInputStream.count)
- stream.flush();
-
- // If stream is still writable notify that queue has drained.
- else if (stream.writable)
- emit(stream, "drain");
-
- // If stream is no longer writable close it.
- else {
- nsIAsyncStreamCopier(stream).cancel(Cr.NS_OK);
- nsIMultiplexInputStream(stream).close();
- nsIAsyncOutputStream(stream).close();
- nsIAsyncOutputStream(stream).flush();
- }
- }
-});
-
-const OutputStreamCallback = Class({
- initialize: function(stream) {
- this.stream = stream;
- },
- // Method is part of `nsIOutputStreamCallback` interface that
- // is invoked by `nsIAsyncOutputStream.asyncWait`. It is registered
- // with `WAIT_CLOSURE_ONLY` flag that overrides the default behavior,
- // causing the `onOutputStreamReady` notification to be suppressed until
- // the stream becomes closed.
- onOutputStreamReady: function(nsIAsyncOutputStream) {
- emit(this.stream, "finish");
- }
-});
-
const OutputStream = Class({
extends: Stream,
- writable: false,
- drained: true,
- get bufferSize() {
- let multiplexInputStream = nsIMultiplexInputStream(this);
- return multiplexInputStream && multiplexInputStream.available();
- },
initialize: function initialize(options) {
- let { asyncOutputStream, output } = options;
- this.writable = true;
-
- // Ensure that `nsIAsyncOutputStream` was provided.
- asyncOutputStream.QueryInterface(Ci.nsIAsyncOutputStream);
+ let { output, asyncOutputStream } = options;
- // Create a `nsIMultiplexInputStream` and `nsIAsyncStreamCopier`. Former
- // is used to queue written data chunks that `asyncStreamCopier` will
- // asynchronously drain into `asyncOutputStream`.
- let multiplexInputStream = MultiplexInputStream();
- let asyncStreamCopier = AsyncStreamCopier(multiplexInputStream,
- output || asyncOutputStream,
- eventTarget,
- // nsIMultiplexInputStream
- // implemnts .readSegments()
- true,
- // nsIOutputStream may or
- // may not implemnet
- // .writeSegments().
- false,
- // Use default buffer size.
- null,
- // Should not close an input.
- false,
- // Should not close an output.
- false);
-
- // Create `requestObserver` implementing `nsIRequestObserver` interface
- // in the constructor that's gonna be reused across several flushes.
- let requestObserver = RequestObserver(this);
-
-
- // Create observer that implements `nsIOutputStreamCallback` and register
- // using `WAIT_CLOSURE_ONLY` flag. That way it will be notfied once
- // `nsIAsyncOutputStream` is closed.
- asyncOutputStream.asyncWait(OutputStreamCallback(this),
- asyncOutputStream.WAIT_CLOSURE_ONLY,
- 0,
- threadManager.currentThread);
-
- nsIRequestObserver(this, requestObserver);
+ this.writable = true;
+ nsIOutputStream(this, output);
nsIAsyncOutputStream(this, asyncOutputStream);
- nsIMultiplexInputStream(this, multiplexInputStream);
- nsIAsyncStreamCopier(this, asyncStreamCopier);
-
- this.asyncOutputStream = asyncOutputStream;
- this.multiplexInputStream = multiplexInputStream;
- this.asyncStreamCopier = asyncStreamCopier;
},
write: function write(content, encoding, callback) {
+ let output = nsIOutputStream(this);
+ let asyncOutputStream = nsIAsyncOutputStream(this);
+
if (isFunction(encoding)) {
callback = encoding;
encoding = callback;
}
+ // Flag indicating whether or not content has been flushed to the kernel
+ // buffer.
+ let isWritten = false;
// If stream is not writable we throw an error.
- if (!this.writable) throw Error("stream is not writable");
-
- let chunk = null;
+ if (!this.writable)
+ throw Error("stream not writable");
- // If content is not a buffer then we create one out of it.
- if (Buffer.isBuffer(content)) {
- chunk = new ArrayBufferInputStream();
- chunk.setData(content.buffer, 0, content.length);
- }
- else {
- chunk = new StringInputStream();
- chunk.setData(content, content.length);
- }
+ try {
+ // If content is not a buffer then we create one out of it.
+ if (!Buffer.isBuffer(content))
+ content = new Buffer(content, encoding);
- if (callback)
- this.once("drain", callback);
-
- // Queue up chunk to be copied to output sync.
- nsIMultiplexInputStream(this).appendStream(chunk);
- this.flush();
+ // We write content as a byte array as this will avoid any transcoding
+ // if content was a buffer.
+ output.writeByteArray(content.valueOf(), content.length);
+ output.flush();
- return this.drained;
+ if (callback) this.once("drain", callback);
+ onStateChange(asyncOutputStream, this);
+ return true;
+ } catch (error) {
+ // If errors occur we emit appropriate event.
+ emit(this, "error", error);
+ }
},
- flush: function() {
- if (this.drained) {
- this.drained = false;
- nsIAsyncStreamCopier(this).asyncCopy(nsIRequestObserver(this), null);
- }
+ flush: function flush() {
+ nsIOutputStream(this).flush();
},
end: function end(content, encoding, callback) {
if (isFunction(content)) {
callback = content
content = callback
}
if (isFunction(encoding)) {
callback = encoding
encoding = callback
}
- // Setting a listener to "finish" event if passed.
+ // Setting a listener to "close" event if passed.
if (isFunction(callback))
- this.once("finish", callback);
-
-
- if (content)
- this.write(content, encoding);
- this.writable = false;
+ this.once("close", callback);
- // Close `asyncOutputStream` only if output has drained. If it's
- // not drained than `asyncStreamCopier` is busy writing, so let
- // it finish. Note that since `this.writable` is false copier will
- // close `asyncOutputStream` once output drains.
- if (this.drained)
- nsIAsyncOutputStream(this).close();
+ // If content is passed then we defer closing until we finish with writing.
+ if (content)
+ this.write(content, encoding, end.bind(this));
+ // If we don"t write anything, then we close an outputStream.
+ else
+ nsIOutputStream(this).close();
},
- destroy: function destroy() {
- nsIAsyncOutputStream(this).close();
- nsIAsyncOutputStream(this);
- nsIMultiplexInputStream(this);
- nsIAsyncStreamCopier(this);
- nsIRequestObserver(this);
+ destroy: function destroy(callback) {
+ try {
+ this.end(callback);
+ nsIOutputStream(this, null);
+ nsIAsyncOutputStream(this, null);
+ } catch (error) {
+ emit(this, "error", error);
+ }
}
});
exports.OutputStream = OutputStream;
const DuplexStream = Class({
extends: Stream,
- implements: [InputStream, OutputStream],
- allowHalfOpen: true,
initialize: function initialize(options) {
- options = options || {};
- let { readable, writable, allowHalfOpen } = options;
+ let { input, output, pump } = options;
- InputStream.prototype.initialize.call(this, options);
- OutputStream.prototype.initialize.call(this, options);
-
- if (readable === false)
- this.readable = false;
+ this.writable = true;
+ this.readable = true;
+ this.encoding = null;
- if (writable === false)
- this.writable = false;
-
- if (allowHalfOpen === false)
- this.allowHalfOpen = false;
+ nsIInputStream(this, input);
+ nsIOutputStream(this, output);
+ nsIInputStreamPump(this, pump);
+ },
+ read: InputStream.prototype.read,
+ pause: InputStream.prototype.pause,
+ resume: InputStream.prototype.resume,
- // If in a half open state and it's disabled enforce end.
- this.once("end", () => {
- if (!this.allowHalfOpen && (!this.readable || !this.writable))
- this.end();
- });
- },
+ write: OutputStream.prototype.write,
+ flush: OutputStream.prototype.flush,
+ end: OutputStream.prototype.end,
+
destroy: function destroy(error) {
+ if (error)
+ emit(this, "error", error);
InputStream.prototype.destroy.call(this);
OutputStream.prototype.destroy.call(this);
}
});
exports.DuplexStream = DuplexStream;
--- a/addon-sdk/source/lib/sdk/lang/functional.js
+++ b/addon-sdk/source/lib/sdk/lang/functional.js
@@ -7,17 +7,17 @@
// those goes to him.
"use strict";
module.metadata = {
"stability": "unstable"
};
-const { setImmediate, setTimeout } = require("../timers");
+const { setTimeout } = require("../timers");
const { deprecateFunction } = require("../util/deprecate");
/**
* Takes `lambda` function and returns a method. When returned method is
* invoked it calls wrapped `lambda` and passes `this` as a first argument
* and given argument as rest.
*/
function method(lambda) {
@@ -25,22 +25,23 @@ function method(lambda) {
return lambda.apply(null, [this].concat(Array.slice(arguments)));
}
}
exports.method = method;
/**
* Takes a function and returns a wrapped one instead, calling which will call
* original function in the next turn of event loop. This is basically utility
- * to do `setImmediate(function() { ... })`, with a difference that returned
+ * to do `setTimeout(function() { ... }, 0)`, with a difference that returned
* function is reused, instead of creating a new one each time. This also allows
* to use this functions as event listeners.
*/
function defer(f) {
- return function deferred() setImmediate(invoke, f, arguments, this);
+ return function deferred()
+ setTimeout(invoke, 0, f, arguments, this);
}
exports.defer = defer;
// Exporting `remit` alias as `defer` may conflict with promises.
exports.remit = defer;
/*
* Takes a funtion and returns a wrapped function that returns `this`
*/
--- a/addon-sdk/source/lib/sdk/system.js
+++ b/addon-sdk/source/lib/sdk/system.js
@@ -63,21 +63,29 @@ exports.exit = function exit(code) {
stream.write(status, status.length);
stream.flush();
stream.close();
}
appStartup.quit(code ? E_ATTEMPT : E_FORCE);
};
-// Adapter for nodejs's stdout & stderr:
-// http://nodejs.org/api/process.html#process_process_stdout
-let stdout = Object.freeze({ write: dump, end: dump });
-exports.stdout = stdout;
-exports.stderr = stdout;
+exports.stdout = new function() {
+ let write = dump
+ if ('logFile' in options && options.logFile) {
+ let mode = PR_WRONLY | PR_CREATE_FILE | PR_APPEND;
+ let stream = openFile(options.logFile, mode);
+ write = function write(data) {
+ let text = String(data);
+ stream.write(text, text.length);
+ stream.flush();
+ }
+ }
+ return Object.freeze({ write: write });
+};
/**
* Returns a path of the system's or application's special directory / file
* associated with a given `id`. For list of possible `id`s please see:
* https://developer.mozilla.org/en-US/docs/Code_snippets/File_I_O#Getting_files_in_special_directories
* http://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsAppDirectoryServiceDefs.h
* @example
*
@@ -121,17 +129,17 @@ exports.build = appInfo.appBuildID;
* The XUL application's UUID.
* This has traditionally been in the form
* `{AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE}` but for some applications it may
* be: "appname@vendor.tld".
*/
exports.id = appInfo.ID;
/**
- * The name of the application.
+ * The name of the application.
*/
exports.name = appInfo.name;
/**
* The XUL application's version, for example "0.8.0+" or "3.7a1pre".
*/
exports.version = appInfo.version;
--- a/addon-sdk/source/lib/sdk/system/globals.js
+++ b/addon-sdk/source/lib/sdk/system/globals.js
@@ -17,17 +17,30 @@ let consoleService = Cc['@mozilla.org/co
QueryInterface(Ci.nsIConsoleService);
// On windows dump does not writes into stdout so cfx can't read thous dumps.
// To workaround this issue we write to a special file from which cfx will
// read and print to the console.
// For more details see: bug-673383
exports.dump = stdout.write;
-exports.console = new PlainTextConsole();
+// Bug 718230: We need to send console messages to stdout and JS Console
+function forsakenConsoleDump(msg, level) {
+ stdout.write(msg);
+
+ if (level === 'error') {
+ let error = ScriptError();
+ msg = msg.replace(/^error: /, '');
+ error.init(msg, null, null, 0, 0, 0, 'Add-on SDK');
+ consoleService.logMessage(error);
+ }
+ else
+ consoleService.logStringMessage(msg);
+};
+exports.console = new PlainTextConsole(forsakenConsoleDump);
// Provide CommonJS `define` to allow authoring modules in a format that can be
// loaded both into jetpack and into browser via AMD loaders.
Object.defineProperty(exports, 'define', {
// `define` is provided as a lazy getter that binds below defined `define`
// function to the module scope, so that require, exports and module
// variables remain accessible.
configurable: true,
--- a/addon-sdk/source/lib/sdk/tabs/tabs-firefox.js
+++ b/addon-sdk/source/lib/sdk/tabs/tabs-firefox.js
@@ -21,19 +21,20 @@ function newTabWindow(options) {
}
Object.defineProperties(tabs, {
open: { value: function open(options) {
if (options.inNewWindow) {
newTabWindow(options);
return undefined;
}
+ // Open in active window if new window was not required.
let activeWindow = windows.activeWindow;
- let privateState = (supportPrivateTabs && (options.isPrivate || isPrivate(activeWindow))) || false;
+ let privateState = !!options.isPrivate;
// if the active window is in the state that we need then use it
if (activeWindow && (!supportPrivateTabs || privateState === isPrivate(activeWindow))) {
activeWindow.tabs.open(options);
}
else {
// find a window in the state that we need
let window = getWindow(privateState);
--- a/addon-sdk/source/lib/sdk/test/harness.js
+++ b/addon-sdk/source/lib/sdk/test/harness.js
@@ -3,17 +3,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "experimental"
};
-const { Cc, Ci, Cu } = require("chrome");
+const { Cc,Ci } = require("chrome");
const { Loader } = require('./loader');
const { serializeStack, parseStack } = require("toolkit/loader");
const { setTimeout } = require('../timers');
const memory = require('../deprecated/memory');
const { PlainTextConsole } = require("../console/plain-text");
const { when: unload } = require("../system/unload");
const { format, fromException } = require("../console/traceback");
const system = require("../system");
@@ -142,21 +142,19 @@ function dictDiff(last, curr) {
return diff;
}
function reportMemoryUsage() {
memory.gc();
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager);
-
var reporters = mgr.enumerateReporters();
if (reporters.hasMoreElements())
print("\n");
-
while (reporters.hasMoreElements()) {
var reporter = reporters.getNext();
reporter.QueryInterface(Ci.nsIMemoryReporter);
print(reporter.description + ": " + reporter.memoryUsed + "\n");
}
var weakrefs = [info.weakref.get()
for each (info in memory.getObjects())];
@@ -164,34 +162,36 @@ function reportMemoryUsage() {
print("Tracked memory objects in testing sandbox: " +
weakrefs.length + "\n");
}
var gWeakrefInfo;
function checkMemory() {
memory.gc();
- Cu.schedulePreciseGC(function () {
- let leaks = getPotentialLeaks();
-
- let compartmentURLs = Object.keys(leaks.compartments).filter(function(url) {
- return !(url in startLeaks.compartments);
- });
+ setTimeout(function () {
+ memory.gc();
+ setTimeout(function () {
+ let leaks = getPotentialLeaks();
+ let compartmentURLs = Object.keys(leaks.compartments).filter(function(url) {
+ return !(url in startLeaks.compartments);
+ });
- let windowURLs = Object.keys(leaks.windows).filter(function(url) {
- return !(url in startLeaks.windows);
- });
+ let windowURLs = Object.keys(leaks.windows).filter(function(url) {
+ return !(url in startLeaks.windows);
+ });
- for (let url of compartmentURLs)
- console.warn("LEAKED", leaks.compartments[url]);
+ for (let url of compartmentURLs)
+ console.warn("LEAKED", leaks.compartments[url]);
- for (let url of windowURLs)
- console.warn("LEAKED", leaks.windows[url]);
+ for (let url of windowURLs)
+ console.warn("LEAKED", leaks.windows[url]);
- showResults();
+ showResults();
+ });
});
}
function showResults() {
if (gWeakrefInfo) {
gWeakrefInfo.forEach(
function(info) {
var ref = info.weakref.get();
@@ -293,17 +293,16 @@ function getPotentialLeaks() {
let uri = ioService.newURI("chrome://global/content/", "UTF-8", null);
let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIChromeRegistry);
uri = chromeReg.convertChromeURL(uri);
let spec = uri.spec;
let pos = spec.indexOf("!/");
WHITELIST_BASE_URLS.push(spec.substring(0, pos + 2));
- let zoneRegExp = new RegExp("^explicit/js-non-window/zones/zone[^/]+/compartment\\((.+)\\)");
let compartmentRegexp = new RegExp("^explicit/js-non-window/compartments/non-window-global/compartment\\((.+)\\)/");
let compartmentDetails = new RegExp("^([^,]+)(?:, (.+?))?(?: \\(from: (.*)\\))?$");
let windowRegexp = new RegExp("^explicit/window-objects/top\\((.*)\\)/active");
let windowDetails = new RegExp("^(.*), id=.*$");
function isPossibleLeak(item) {
if (!item.location)
return false;
@@ -314,19 +313,18 @@ function getPotentialLeaks() {
}
return true;
}
let compartments = {};
let windows = {};
function logReporter(process, path, kind, units, amount, description) {
- let matches;
-
- if ((matches = compartmentRegexp.exec(path)) || (matches = zoneRegExp.exec(path))) {
+ let matches = compartmentRegexp.exec(path);
+ if (matches) {
if (matches[1] in compartments)
return;
let details = compartmentDetails.exec(matches[1]);
if (!details) {
console.error("Unable to parse compartment detail " + matches[1]);
return;
}
@@ -573,17 +571,17 @@ var runTests = exports.runTests = functi
print("Running tests on " + system.name + " " + system.version +
"/Gecko " + system.platformVersion + " (" +
system.id + ") under " +
system.platform + "/" + system.architecture + ".\n");
if (options.parseable)
testConsole = new TestRunnerTinderboxConsole(options);
else
- testConsole = new TestRunnerConsole(new PlainTextConsole(), options);
+ testConsole = new TestRunnerConsole(new PlainTextConsole(print), options);
loader = Loader(module, {
console: testConsole,
global: {} // useful for storing things like coverage testing.
});
// Load these before getting initial leak stats as they will still be in
// memory when we check later
--- a/addon-sdk/source/lib/sdk/timers.js
+++ b/addon-sdk/source/lib/sdk/timers.js
@@ -2,104 +2,52 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
module.metadata = {
"stability": "stable"
};
-const { CC, Cc, Ci } = require("chrome");
-const { when: unload } = require("./system/unload");
+const { CC, Ci } = require('chrome');
+const { when: unload } = require('./system/unload');
const { TYPE_ONE_SHOT, TYPE_REPEATING_SLACK } = Ci.nsITimer;
-const Timer = CC("@mozilla.org/timer;1", "nsITimer");
+const Timer = CC('@mozilla.org/timer;1', 'nsITimer');
const timers = Object.create(null);
-const threadManager = Cc["@mozilla.org/thread-manager;1"].
- getService(Ci.nsIThreadManager);
-const prefBranch = Cc["@mozilla.org/preferences-service;1"].
- getService(Ci.nsIPrefService).
- QueryInterface(Ci.nsIPrefBranch);
-
-let MIN_DELAY = 4;
-// Try to get min timeout delay used by browser.
-try { MIN_DELAY = prefBranch.getIntPref("dom.min_timeout_value"); } finally {}
-
// Last timer id.
let lastID = 0;
// Sets typer either by timeout or by interval
// depending on a given type.
-function setTimer(type, callback, delay, ...args) {
+function setTimer(type, callback, delay) {
let id = ++ lastID;
let timer = timers[id] = Timer();
+ let args = Array.slice(arguments, 3);
timer.initWithCallback({
notify: function notify() {
try {
if (type === TYPE_ONE_SHOT)
delete timers[id];
callback.apply(null, args);
}
catch(error) {
console.exception(error);
}
}
- }, Math.max(delay || MIN_DELAY), type);
+ }, delay || 0, type);
return id;
}
function unsetTimer(id) {
let timer = timers[id];
delete timers[id];
- if (timer) timer.cancel();
+ if (timer)
+ timer.cancel();
}
-let immediates = new Map();
-
-let dispatcher = _ => {
- // Allow scheduling of a new dispatch loop.
- dispatcher.scheduled = false;
- // Take a snapshot of timer `id`'s that have being present before
- // starting a dispatch loop, in order to ignore timers registered
- // in side effect to dispatch while also skipping immediates that
- // were removed in side effect.
- let ids = [id for ([id] of immediates)];
- for (let id of ids) {
- let immediate = immediates.get(id);
- if (immediate) {
- immediates.delete(id);
- try { immediate(); }
- catch (error) { console.exception(error); }
- }
- }
-}
-
-function setImmediate(callback, ...params) {
- let id = ++ lastID;
- // register new immediate timer with curried params.
- immediates.set(id, _ => callback.apply(callback, params));
- // if dispatch loop is not scheduled schedule one. Own scheduler
- if (!dispatcher.scheduled) {
- dispatcher.scheduled = true;
- threadManager.currentThread.dispatch(dispatcher,
- Ci.nsIThread.DISPATCH_NORMAL);
- }
- return id;
-}
-
-function clearImmediate(id) {
- immediates.delete(id);
-}
-
-// Bind timers so that toString-ing them looks same as on native timers.
-exports.setImmediate = setImmediate.bind(null);
-exports.clearImmediate = clearImmediate.bind(null);
exports.setTimeout = setTimer.bind(null, TYPE_ONE_SHOT);
exports.setInterval = setTimer.bind(null, TYPE_REPEATING_SLACK);
exports.clearTimeout = unsetTimer.bind(null);
exports.clearInterval = unsetTimer.bind(null);
-// all timers are cleared out on unload.
-unload(function() {
- immediates.clear();
- Object.keys(timers).forEach(unsetTimer)
-});
+unload(function() { Object.keys(timers).forEach(unsetTimer) });
--- a/addon-sdk/source/lib/sdk/util/array.js
+++ b/addon-sdk/source/lib/sdk/util/array.js
@@ -96,19 +96,18 @@ function fromIterator(iterator) {
else {
for (let item of iterator)
array.push(item);
}
return array;
}
exports.fromIterator = fromIterator;
-function find(array, predicate, fallback) {
+function find(array, predicate) {
var index = 0;
var count = array.length;
while (index < count) {
var value = array[index];
if (predicate(value)) return value;
else index = index + 1;
}
- return fallback;
}
exports.find = find;
--- a/addon-sdk/source/lib/sdk/window/utils.js
+++ b/addon-sdk/source/lib/sdk/window/utils.js
@@ -13,18 +13,16 @@ const observers = require('../deprecated
const { defer } = require('sdk/core/promise');
const windowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1'].
getService(Ci.nsIWindowWatcher);
const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].
getService(Ci.nsIAppShellService);
const WM = Cc['@mozilla.org/appshell/window-mediator;1'].
getService(Ci.nsIWindowMediator);
-const io = Cc['@mozilla.org/network/io-service;1'].
- getService(Ci.nsIIOService);
const BROWSER = 'navigator:browser',
URI_BROWSER = 'chrome://browser/content/browser.xul',
NAME = '_blank',
FEATURES = 'chrome,all,dialog=no,non-private';
function isWindowPrivate(win) {
if (!win)
@@ -181,31 +179,28 @@ function serializeFeatures(options) {
* @params {nsIDOMWindow} options.parent
* Used as parent for the created window.
* @params {String} options.name
* Optional name that is assigned to the window.
* @params {Object} options.features
* Map of key, values like: `{ width: 10, height: 15, chrome: true, private: true }`.
*/
function open(uri, options) {
- uri = uri || URI_BROWSER;
- options = options || {}
-
- if (['chrome', 'resource', 'data'].indexOf(io.newURI(uri, null, null).scheme) < 0)
- throw new Error('only chrome, resource and data uris are allowed');
-
+ options = options || {};
let newWindow = windowWatcher.
openWindow(options.parent || null,
- uri,
+ uri || URI_BROWSER,
options.name || null,
serializeFeatures(options.features || {}),
options.args || null);
return newWindow;
}
+
+
exports.open = open;
function onFocus(window) {
let { resolve, promise } = defer();
if (isFocused(window)) {
resolve(window);
}
--- a/addon-sdk/source/python-lib/cuddlefish/options_xul.py
+++ b/addon-sdk/source/python-lib/cuddlefish/options_xul.py
@@ -47,19 +47,16 @@ def validate_prefs(options):
def parse_options(options, jetpack_id):
doc = Document()
root = doc.createElement("vbox")
root.setAttribute("xmlns", "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")
doc.appendChild(root)
for pref in options:
- if ("hidden" in pref and pref["hidden"] == True):
- continue;
-
setting = doc.createElement("setting")
setting.setAttribute("pref-name", pref["name"])
setting.setAttribute("data-jetpack-id", jetpack_id)
setting.setAttribute("pref", "extensions." + jetpack_id + "." + pref["name"])
setting.setAttribute("type", pref["type"])
setting.setAttribute("title", pref["title"])
if ("description" in pref):
--- a/addon-sdk/source/python-lib/cuddlefish/runner.py
+++ b/addon-sdk/source/python-lib/cuddlefish/runner.py
@@ -25,17 +25,17 @@ FILTER_ONLY_CONSOLE_FROM_ADB = re.compil
# Used to detect the currently running test
PARSEABLE_TEST_NAME = re.compile(r'TEST-START \| ([^\n]+)\n')
# Maximum time we'll wait for tests to finish, in seconds.
# The purpose of this timeout is to recover from infinite loops. It should be
# longer than the amount of time any test run takes, including those on slow
# machines running slow (debug) versions of Firefox.
-RUN_TIMEOUT = 1.5 * 60 * 60 # 1.5 Hour
+RUN_TIMEOUT = 45 * 60 # 45 minutes
# Maximum time we'll wait for tests to emit output, in seconds.
# The purpose of this timeout is to recover from hangs. It should be longer
# than the amount of time any test takes to report results.
OUTPUT_TIMEOUT = 60 # one minute
def follow_file(filename):
"""
@@ -491,16 +491,19 @@ def run_app(harness_root_dir, manifest_r
fileno,logfile = tempfile.mkstemp(prefix="harness-log-")
os.close(fileno)
logfile_tail = follow_file(logfile)
atexit.register(maybe_remove_logfile)
logfile = os.path.abspath(os.path.expanduser(logfile))
maybe_remove_logfile()
+ if app_type != "fennec-on-device":
+ harness_options['logFile'] = logfile
+
env = {}
env.update(os.environ)
env['MOZ_NO_REMOTE'] = '1'
env['XPCOM_DEBUG_BREAK'] = 'stack'
env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
env.update(extra_environment)
if norun:
cmdargs.append("-no-remote")
--- a/addon-sdk/source/python-lib/mozrunner/winprocess.py
+++ b/addon-sdk/source/python-lib/mozrunner/winprocess.py
@@ -325,19 +325,23 @@ GetExitCodeProcessProto = WINFUNCTYPE(BO
GetExitCodeProcessFlags = ((1, "hProcess"),
(2, "lpExitCode"))
GetExitCodeProcess = GetExitCodeProcessProto(
("GetExitCodeProcess", windll.kernel32),
GetExitCodeProcessFlags)
GetExitCodeProcess.errcheck = ErrCheckBool
def CanCreateJobObject():
- # Running firefox in a job (from cfx) hangs on sites using flash plugin
- # so job creation is turned off for now. (see Bug 768651).
- return False
+ currentProc = GetCurrentProcess()
+ if IsProcessInJob(currentProc):
+ jobinfo = QueryInformationJobObject(HANDLE(0), 'JobObjectExtendedLimitInformation')
+ limitflags = jobinfo['BasicLimitInformation']['LimitFlags']
+ return bool(limitflags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) or bool(limitflags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)
+ else:
+ return True
### testing functions
def parent():
print 'Starting parent'
currentProc = GetCurrentProcess()
if IsProcessInJob(currentProc):
print >> sys.stderr, "You should not be in a job object to test"
--- a/addon-sdk/source/test/addons/content-permissions/main.js
+++ b/addon-sdk/source/test/addons/content-permissions/main.js
@@ -1,21 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
+const xulApp = require("sdk/system/xul-app");
const { PageMod } = require("sdk/page-mod");
const tabs = require("sdk/tabs");
-const { startServerAsync } = require("sdk/test/httpd");
-
-const serverPort = 8099;
exports.testCrossDomainIframe = function(assert, done) {
- let server = startServerAsync(serverPort);
+ let serverPort = 8099;
+ let server = require("sdk/test/httpd").startServerAsync(serverPort);
server.registerPathHandler("/iframe", function handle(request, response) {
response.write("<html><body>foo</body></html>");
});
let pageMod = PageMod({
include: "about:*",
contentScript: "new " + function ContentScriptScope() {
self.on("message", function (url) {
@@ -27,33 +26,29 @@ exports.testCrossDomainIframe = function
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
});
},
onAttach: function(w) {
w.on("message", function (body) {
assert.equal(body, "foo", "received iframe html content");
pageMod.destroy();
- w.tab.close(function() {
- server.stop(done);
- });
+ w.tab.close();
+ server.stop(done);
});
-
w.postMessage("http://localhost:8099/iframe");
}
});
- tabs.open({
- url: "about:home",
- inBackground: true
- });
+ tabs.open("about:credits");
};
exports.testCrossDomainXHR = function(assert, done) {
- let server = startServerAsync(serverPort);
+ let serverPort = 8099;
+ let server = require("sdk/test/httpd").startServerAsync(serverPort);
server.registerPathHandler("/xhr", function handle(request, response) {
response.write("foo");
});
let pageMod = PageMod({
include: "about:*",
contentScript: "new " + function ContentScriptScope() {
self.on("message", function (url) {
@@ -65,24 +60,27 @@ exports.testCrossDomainXHR = function(as
};
request.send(null);
});
},
onAttach: function(w) {
w.on("message", function (body) {
assert.equal(body, "foo", "received XHR content");
pageMod.destroy();
- w.tab.close(function() {
- server.stop(done);
- });
+ w.tab.close();
+ server.stop(done);
});
-
w.postMessage("http://localhost:8099/xhr");
}
});
- tabs.open({
- url: "about:home",
- inBackground: true
- });
+ tabs.open("about:credits");
};
+if (!xulApp.versionInRange(xulApp.platformVersion, "17.0a2", "*")) {
+ module.exports = {
+ "test Unsupported Application": function Unsupported (assert) {
+ assert.pass("This firefox version doesn't support cross-domain-content permission.");
+ }
+ };
+}
+
require("sdk/test/runner").runTestsFromModule(module);
deleted file mode 100644
--- a/addon-sdk/source/test/addons/main/main.js
+++ /dev/null
@@ -1,35 +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/. */
-'use strict';
-
-const { setTimeout } = require('sdk/timers');
-
-let mainStarted = false;
-
-exports.main = function main(options, callbacks) {
- mainStarted = true;
-
- let tests = {};
-
- tests.testMainArguments = function(assert) {
- assert.ok(!!options, 'options argument provided to main');
- assert.ok('loadReason' in options, 'loadReason is in options provided by main');
- assert.equal(typeof callbacks.print, 'function', 'callbacks.print is a function');
- assert.equal(typeof callbacks.quit, 'function', 'callbacks.quit is a function');
- assert.equal(options.loadReason, 'install', 'options.loadReason is install');
- }
-
- require('sdk/test/runner').runTestsFromModule({exports: tests});
-}
-
-// this causes a fail if main does not start
-setTimeout(function() {
- if (mainStarted)
- return;
-
- // main didn't start, fail..
- require("sdk/test/runner").runTestsFromModule({exports: {
- testFail: function(assert) assert.fail('Main did not start..')
- }});
-}, 500);
deleted file mode 100644
--- a/addon-sdk/source/test/addons/main/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "id": "test-main"
-}
--- a/addon-sdk/source/test/addons/private-browsing-supported/main.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/main.js
@@ -1,24 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const { merge } = require('sdk/util/object');
-const app = require('sdk/system/xul-app');
+const app = require("sdk/system/xul-app");
const { isGlobalPBSupported } = require('sdk/private-browsing/utils');
merge(module.exports,
require('./test-tabs'),
require('./test-page-mod'),
require('./test-selection'),
require('./test-panel'),
require('./test-private-browsing'),
isGlobalPBSupported ? require('./test-global-private-browsing') : {}
);
// Doesn't make sense to test window-utils and windows on fennec,
// as there is only one window which is never private
-if (!app.is('Fennec'))
+if (!app.is("Fennec"))
merge(module.exports, require('./test-windows'));
require('sdk/test/runner').runTestsFromModule(module);
--- a/addon-sdk/source/test/addons/private-browsing-supported/test-tabs.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-tabs.js
@@ -1,17 +1,15 @@
'use strict';
const tabs = require('sdk/tabs');
const { is } = require('sdk/system/xul-app');
const { isPrivate } = require('sdk/private-browsing');
const pbUtils = require('sdk/private-browsing/utils');
const { getOwnerWindow } = require('sdk/private-browsing/window/utils');
-const { promise: windowPromise, close, focus } = require('sdk/window/helpers');
-const { getMostRecentBrowserWindow } = require('sdk/window/utils');
exports.testPrivateTabsAreListed = function (assert, done) {
let originalTabCount = tabs.length;
tabs.open({
url: 'about:blank',
isPrivate: true,
onOpen: function(tab) {
@@ -23,91 +21,12 @@ exports.testPrivateTabsAreListed = funct
'New private window\'s tab are visible in tabs list');
}
else {
// Global case, openDialog didn't opened a private window/tab
assert.ok(!isPrivate(tab), "tab isn't private");
assert.equal(tabs.length, originalTabCount + 1,
'New non-private window\'s tab is visible in tabs list');
}
-
tab.close(done);
}
});
}
-
-exports.testOpenTabWithPrivateActiveWindowNoIsPrivateOption = function(assert, done) {
- let window = getMostRecentBrowserWindow().OpenBrowserWindow({ private: true });
-
- windowPromise(window, 'load').then(focus).then(function (window) {
- assert.ok(isPrivate(window), 'new window is private');
-
- tabs.open({
- url: 'about:blank',
- onOpen: function(tab) {
- assert.ok(isPrivate(tab), 'new tab is private');
- assert.ok(isPrivate(getOwnerWindow(tab)), 'new tab window is private');
- assert.strictEqual(getOwnerWindow(tab), window, 'the tab window and the private window are the same');
-
- close(window).then(done, assert.fail);
- }
- })
- }, assert.fail).then(null, assert.fail);
-}
-
-exports.testOpenTabWithNonPrivateActiveWindowNoIsPrivateOption = function(assert, done) {
- let window = getMostRecentBrowserWindow().OpenBrowserWindow({ private: false });
-
- windowPromise(window, 'load').then(focus).then(function (window) {
- assert.equal(isPrivate(window), false, 'new window is not private');
-
- tabs.open({
- url: 'about:blank',
- onOpen: function(tab) {
- assert.equal(isPrivate(tab), false, 'new tab is not private');
- assert.equal(isPrivate(getOwnerWindow(tab)), false, 'new tab window is not private');
- assert.strictEqual(getOwnerWindow(tab), window, 'the tab window and the new window are the same');
-
- close(window).then(done, assert.fail);
- }
- })
- }, assert.fail).then(null, assert.fail);
-}
-
-exports.testOpenTabWithPrivateActiveWindowWithIsPrivateOptionTrue = function(assert, done) {
- let window = getMostRecentBrowserWindow().OpenBrowserWindow({ private: true });
-
- windowPromise(window, 'load').then(focus).then(function (window) {
- assert.ok(isPrivate(window), 'new window is private');
-
- tabs.open({
- url: 'about:blank',
- isPrivate: true,
- onOpen: function(tab) {
- assert.ok(isPrivate(tab), 'new tab is private');
- assert.ok(isPrivate(getOwnerWindow(tab)), 'new tab window is private');
- assert.strictEqual(getOwnerWindow(tab), window, 'the tab window and the private window are the same');
-
- close(window).then(done, assert.fail);
- }
- })
- }, assert.fail).then(null, assert.fail);
-}
-
-exports.testOpenTabWithNonPrivateActiveWindowWithIsPrivateOptionFalse = function(assert, done) {
- let window = getMostRecentBrowserWindow().OpenBrowserWindow({ private: false });
-
- windowPromise(window, 'load').then(focus).then(function (window) {
- assert.equal(isPrivate(window), false, 'new window is not private');
-
- tabs.open({
- url: 'about:blank',
- isPrivate: false,
- onOpen: function(tab) {
- assert.equal(isPrivate(tab), false, 'new tab is not private');
- assert.equal(isPrivate(getOwnerWindow(tab)), false, 'new tab window is not private');
- assert.strictEqual(getOwnerWindow(tab), window, 'the tab window and the new window are the same');
-
- close(window).then(done, assert.fail);
- }
- })
- }, assert.fail).then(null, assert.fail);
-}
deleted file mode 100644
--- a/addon-sdk/source/test/addons/simple-prefs/lib/main.js
+++ /dev/null
@@ -1,82 +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/. */
-'use strict';
-
-const { Cu } = require('chrome');
-const sp = require('sdk/simple-prefs');
-const app = require('sdk/system/xul-app');
-const self = require('sdk/self');
-const tabs = require('sdk/tabs');
-
-const { AddonManager } = Cu.import('resource://gre/modules/AddonManager.jsm', {});
-
-exports.testDefaultValues = function (assert) {
- assert.equal(sp.prefs.myHiddenInt, 5, 'myHiddenInt default is 5');
- assert.equal(sp.prefs.myInteger, 8, 'myInteger default is 8');
- assert.equal(sp.prefs.somePreference, 'TEST', 'somePreference default is correct');
-}
-
-exports.testOptionsType = function(assert, done) {
- AddonManager.getAddonByID(self.id, function(aAddon) {
- assert.equal(aAddon.optionsType, AddonManager.OPTIONS_TYPE_INLINE, 'options type is inline');
- done();
- });
-}
-
-if (app.is('Firefox')) {
- exports.testAOM = function(assert, done) {
- tabs.open({
- url: 'about:addons',
- onReady: function(tab) {
- tab.attach({
- contentScript: 'AddonManager.getAddonByID("' + self.id + '", function(aAddon) {\n' +
- 'unsafeWindow.gViewController.viewObjects.detail.node.addEventListener("ViewChanged", function whenViewChanges() {\n' +
- 'unsafeWindow.gViewController.viewObjects.detail.node.removeEventListener("ViewChanged", whenViewChanges, false);\n' +
- 'setTimeout(function() {\n' + // TODO: figure out why this is necessary..
- 'self.postMessage({\n' +
- 'somePreference: getAttributes(unsafeWindow.document.querySelector("setting[title=\'some-title\']")),\n' +
- 'myInteger: getAttributes(unsafeWindow.document.querySelector("setting[title=\'my-int\']")),\n' +
- 'myHiddenInt: getAttributes(unsafeWindow.document.querySelector("setting[title=\'hidden-int\']"))\n' +
- '});\n' +
- '}, 250);\n' +
- '}, false);\n' +
- 'unsafeWindow.gViewController.commands.cmd_showItemDetails.doCommand(aAddon, true);\n' +
- '});\n' +
- 'function getAttributes(ele) {\n' +
- 'if (!ele) return {};\n' +
- 'return {\n' +
- 'pref: ele.getAttribute("pref"),\n' +
- 'type: ele.getAttribute("type"),\n' +
- 'title: ele.getAttribute("title"),\n' +
- 'desc: ele.getAttribute("desc")\n' +
- '}\n' +
- '}\n',
- onMessage: function(msg) {
- // test somePreference
- assert.equal(msg.somePreference.type, 'string', 'some pref is a string');
- assert.equal(msg.somePreference.pref, 'extensions.'+self.id+'.somePreference', 'somePreference path is correct');
- assert.equal(msg.somePreference.title, 'some-title', 'somePreference title is correct');
- assert.equal(msg.somePreference.desc, 'Some short description for the preference', 'somePreference description is correct');
-
- // test myInteger
- assert.equal(msg.myInteger.type, 'integer', 'myInteger is a int');
- assert.equal(msg.myInteger.pref, 'extensions.'+self.id+'.myInteger', 'extensions.test-simple-prefs.myInteger');
- assert.equal(msg.myInteger.title, 'my-int', 'myInteger title is correct');
- assert.equal(msg.myInteger.desc, 'How many of them we have.', 'myInteger desc is correct');
-
- // test myHiddenInt
- assert.equal(msg.myHiddenInt.type, undefined, 'myHiddenInt was not displayed');
- assert.equal(msg.myHiddenInt.pref, undefined, 'myHiddenInt was not displayed');
- assert.equal(msg.myHiddenInt.title, undefined, 'myHiddenInt was not displayed');
- assert.equal(msg.myHiddenInt.desc, undefined, 'myHiddenInt was not displayed');
-
- tab.close(done);
- }
- });
- }
- });
- }
-}
-
-require('sdk/test/runner').runTestsFromModule(module);
deleted file mode 100644
--- a/addon-sdk/source/test/addons/simple-prefs/package.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "id": "test-simple-prefs",
- "preferences": [{
- "name": "somePreference",
- "title": "some-title",
- "description": "Some short description for the preference",
- "type": "string",
- "value": "TEST"
- },
- {
- "description": "How many of them we have.",
- "name": "myInteger",
- "type": "integer",
- "value": 8,
- "title": "my-int"
- }, {
- "name": "myHiddenInt",
- "type": "integer",
- "hidden": true,
- "value": 5,
- "title": "hidden-int"
- }]
-}
--- a/addon-sdk/source/test/places-helper.js
+++ b/addon-sdk/source/test/places-helper.js
@@ -14,17 +14,16 @@ const tagsrv = Cc['@mozilla.org/browser/
getService(Ci.nsITaggingService);
const asyncHistory = Cc['@mozilla.org/browser/history;1'].
getService(Ci.mozIAsyncHistory);
const { send } = require('sdk/addon/events');
const { setTimeout } = require('sdk/timers');
const { newURI } = require('sdk/url/utils');
const { defer, all } = require('sdk/core/promise');
const { once } = require('sdk/system/events');
-const { set } = require('sdk/preferences/service');
const {
Bookmark, Group, Separator,
save, search,
MENU, TOOLBAR, UNSORTED
} = require('sdk/places/bookmarks');
function invalidResolve (assert) {
return function (e) {
@@ -41,35 +40,22 @@ function invalidReject (assert) {
exports.invalidReject = invalidReject;
// Removes all children of group
function clearBookmarks (group) {
group
? bmsrv.removeFolderChildren(group.id)
: clearAllBookmarks();
}
+exports.clearBookmarks = clearBookmarks;
function clearAllBookmarks () {
[MENU, TOOLBAR, UNSORTED].forEach(clearBookmarks);
}
-
-function clearHistory (done) {
- hsrv.removeAllPages();
- once('places-expiration-finished', done);
-}
-
-// Cleans bookmarks and history and disables maintanance
-function resetPlaces (done) {
- // Set last maintenance to current time to prevent
- // Places DB maintenance occuring and locking DB
- set('places.database.lastMaintenance', Math.floor(Date.now() / 1000));
- clearAllBookmarks();
- clearHistory(done);
-}
-exports.resetPlaces = resetPlaces;
+exports.clearAllBookmarks = clearAllBookmarks;
function compareWithHost (assert, item) {
let id = item.id;
let type = item.type === 'group' ? bmsrv.TYPE_FOLDER : bmsrv['TYPE_' + item.type.toUpperCase()];
let url = item.url && !item.url.endsWith('/') ? item.url + '/' : item.url;
if (type === bmsrv.TYPE_BOOKMARK) {
assert.equal(url, bmsrv.getBookmarkURI(id).spec.toString(), 'Matches host url');
@@ -114,16 +100,22 @@ function createVisit (url) {
place.visits = [{
transitionType: hsrv.TRANSITION_LINK,
visitDate: +(new Date()) * 1000,
referredURI: undefined
}];
return place;
}
+function clearHistory (done) {
+ hsrv.removeAllPages();
+ once('places-expiration-finished', done);
+}
+exports.clearHistory = clearHistory;
+
function createBookmark (data) {
data = data || {};
let item = {
title: data.title || 'Moz',
url: data.url || (!data.type || data.type === 'bookmark' ?
'http://moz.com/' :
undefined),
tags: data.tags || (!data.type || data.type === 'bookmark' ?
--- a/addon-sdk/source/test/tabs/test-fennec-tabs.js
+++ b/addon-sdk/source/test/tabs/test-fennec-tabs.js
@@ -106,21 +106,22 @@ exports.testTabProperties = function(tes
let tabsLen = tabs.length;
tabs.open({
url: url,
onReady: function(tab) {
test.assertEqual(tab.title, "foo", "title of the new tab matches");
test.assertEqual(tab.url, url, "URL of the new tab matches");
test.assert(tab.favicon, "favicon of the new tab is not empty");
// TODO: remove need for this test by implementing the favicon feature
- test.assertEqual(messages[0].msg,
- "tab.favicon is deprecated, and " +
- "currently favicon helpers are not yet supported " +
- "by Fennec",
- "favicon logs an error for now");
+ // Poors man deepEqual with JSON.stringify...
+ test.assertEqual(JSON.stringify(messages),
+ JSON.stringify(['tab.favicon is deprecated, and ' +
+ 'currently favicon helpers are not yet supported ' +
+ 'by Fennec']),
+ "favicon logs an error for now");
test.assertEqual(tab.style, null, "style of the new tab matches");
test.assertEqual(tab.index, tabsLen, "index of the new tab matches");
test.assertNotEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
test.assertNotEqual(tab.id, null, "a tab object always has an id property");
tab.close(function() {
loader.unload();
--- a/addon-sdk/source/test/test-array.js
+++ b/addon-sdk/source/test/test-array.js
@@ -80,16 +80,8 @@ exports.testUnique = function(test) {
function compareArray (a, b) {
test.assertEqual(a.length, b.length);
for (let i = 0; i < a.length; i++) {
test.assertEqual(a[i], b[i]);
}
}
};
-
-exports.testFind = function(test) {
- let isOdd = (x) => x % 2;
- test.assertEqual(array.find([2, 4, 5, 7, 8, 9], isOdd), 5);
- test.assertEqual(array.find([2, 4, 6, 8], isOdd), undefined);
- test.assertEqual(array.find([2, 4, 6, 8], isOdd, null), null);
-};
-
--- a/addon-sdk/source/test/test-browser-events.js
+++ b/addon-sdk/source/test/test-browser-events.js
@@ -87,9 +87,19 @@ exports["test browser events ignore othe
done();
}
});
// Open window and close it to trigger observers.
let window = open("data:text/html,not a browser");
};
+if (require("sdk/system/xul-app").is("Fennec")) {
+ module.exports = {
+ "test Unsupported Test": function UnsupportedTest (assert) {
+ assert.pass(
+ "Skipping this test until Fennec support is implemented." +
+ "See bug 793071");
+ }
+ }
+}
+
require("test").run(exports);
--- a/addon-sdk/source/test/test-content-script.js
+++ b/addon-sdk/source/test/test-content-script.js
@@ -1,71 +1,57 @@
/* 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/. */
const hiddenFrames = require("sdk/frame/hidden-frame");
-const { create: makeFrame } = require("sdk/frame/utils");
-const { window } = require("sdk/addon/window");
+
const { Loader } = require('sdk/test/loader');
-const { URL } = require("sdk/url");
-const testURI = require("sdk/self").data.url("test.html");
-const testHost = URL(testURI).scheme + '://' + URL(testURI).host;
/*
* Utility function that allow to easily run a proxy test with a clean
* new HTML document. See first unit test for usage.
*/
function createProxyTest(html, callback) {
return function (assert, done) {
- let url = 'data:text/html;charset=utf-8,' + encodeURIComponent(html);
- let principalLoaded = false;
+ let url = 'data:text/html;charset=utf-8,' + encodeURI(html);
+
+ let hiddenFrame = hiddenFrames.add(hiddenFrames.HiddenFrame({
+ onReady: function () {
- let element = makeFrame(window.document, {
- nodeName: "iframe",
- type: "content",
- allowJavascript: true,
- allowPlugins: true,
- allowAuth: true,
- uri: testURI
- });
+ function onDOMReady() {
+ hiddenFrame.element.removeEventListener("DOMContentLoaded", onDOMReady,
+ false);
- element.addEventListener("DOMContentLoaded", onDOMReady, false);
-
- function onDOMReady() {
- // Reload frame after getting principal from `testURI`
- if (!principalLoaded) {
- element.setAttribute("src", url);
- principalLoaded = true;
- return;
- }
+ let xrayWindow = hiddenFrame.element.contentWindow;
+ let rawWindow = xrayWindow.wrappedJSObject;
- assert.equal(element.getAttribute("src"), url, "correct URL loaded");
- element.removeEventListener("DOMContentLoaded", onDOMReady,
- false);
- let xrayWindow = element.contentWindow;
- let rawWindow = xrayWindow.wrappedJSObject;
+ let isDone = false;
+ let helper = {
+ xrayWindow: xrayWindow,
+ rawWindow: rawWindow,
+ createWorker: function (contentScript) {
+ return createWorker(assert, xrayWindow, contentScript, helper.done);
+ },
+ done: function () {
+ if (isDone)
+ return;
+ isDone = true;
+ hiddenFrames.remove(hiddenFrame);
+ done();
+ }
+ }
+ callback(helper, assert);
+ }
- let isDone = false;
- let helper = {
- xrayWindow: xrayWindow,
- rawWindow: rawWindow,
- createWorker: function (contentScript) {
- return createWorker(assert, xrayWindow, contentScript, helper.done);
- },
- done: function () {
- if (isDone)
- return;
- isDone = true;
- element.parentNode.removeChild(element);
- done();
- }
- };
- callback(helper, assert);
- }
+ hiddenFrame.element.addEventListener("DOMContentLoaded", onDOMReady, false);
+ hiddenFrame.element.setAttribute("src", url);
+
+ }
+ }));
};
}
function createWorker(assert, xrayWindow, contentScript, done) {
let loader = Loader(module);
let Worker = loader.require("sdk/content/worker").Worker;
let worker = Worker({
window: xrayWindow,
@@ -174,19 +160,19 @@ exports["test postMessage"] = createProx
// Listen without proxies, to check that it will work in regular case
// simulate listening from a web document.
ifWindow.addEventListener("message", function listener(event) {
ifWindow.removeEventListener("message", listener, false);
// As we are in system principal, event is an XrayWrapper
// xrays use current compartments when calling postMessage method.
// Whereas js proxies was using postMessage method compartment,
// not the caller one.
- assert.strictEqual(event.source, helper.xrayWindow,
- "event.source is the top window");
- assert.equal(event.origin, testHost, "origin matches testHost");
+ assert.equal(event.source, helper.xrayWindow,
+ "event.source is the top window");
+ assert.equal(event.origin, "null", "origin is null");
assert.equal(event.data, "{\"foo\":\"bar\\n \\\"escaped\\\".\"}",
"message data is correct");
helper.done();
}, false);
helper.createWorker(
@@ -225,40 +211,38 @@ exports["test Object Listener"] = create
}
);
});
exports["test Object Listener 2"] = createProxyTest("", function (helper) {
helper.createWorker(
- ('new ' + function ContentScriptScope() {
- // variable replaced with `testHost`
- let testHost = "TOKEN";
+ 'new ' + function ContentScriptScope() {
// Verify object as DOM event listener
let myMessageListener = {
called: false,
handleEvent: function(event) {
window.removeEventListener("message", myMessageListener, true);
assert(this == myMessageListener, "`this` is the original object");
assert(!this.called, "called only once");
this.called = true;
assert(event.target == document.defaultView, "event.target is the wrapped window");
assert(event.source == document.defaultView, "event.source is the wrapped window");
- assert(event.origin == testHost, "origin matches testHost");
+ assert(event.origin == "null", "origin is null");
assert(event.data == "ok", "message data is correct");
done();
}
};
window.addEventListener("message", myMessageListener, true);
document.defaultView.postMessage("ok", '*');
}
- ).replace("TOKEN", testHost));
+ );
});
let html = '<input id="input" type="text" /><input id="input3" type="checkbox" />' +
'<input id="input2" type="checkbox" />';
/* Disable test to keep tree green until Bug 756214 is fixed.
exports.testStringOverload = createProxyTest(html, function (helper, test) {
--- a/addon-sdk/source/test/test-fs.js
+++ b/addon-sdk/source/test/test-fs.js
@@ -4,17 +4,16 @@
"use strict";
const { pathFor } = require("sdk/system");
const fs = require("sdk/io/fs");
const url = require("sdk/url");
const path = require("sdk/fs/path");
const { Buffer } = require("sdk/io/buffer");
-const { is } = require("sdk/system/xul-app");
// Use profile directory to list / read / write files.
const profilePath = pathFor("ProfD");
const fileNameInProfile = "compatibility.ini";
const dirNameInProfile = "extensions";
const filePathInProfile = path.join(profilePath, fileNameInProfile);
const dirPathInProfile = path.join(profilePath, dirNameInProfile);
const mkdirPath = path.join(profilePath, "sdk-fixture-mkdir");
@@ -22,28 +21,29 @@ const writePath = path.join(profilePath,
const unlinkPath = path.join(profilePath, "sdk-fixture-unlink");
const truncatePath = path.join(profilePath, "sdk-fixture-truncate");
const renameFromPath = path.join(profilePath, "sdk-fixture-rename-from");
const renameToPath = path.join(profilePath, "sdk-fixture-rename-to");
const profileEntries = [
"compatibility.ini",
"extensions",
+ "extensions.ini",
"prefs.js"
// There are likely to be a lot more files but we can't really
// on consistent list so we limit to this.
];
-exports["test readdir"] = function(assert, end) {
+exports["test readir"] = function(assert, end) {
var async = false;
fs.readdir(profilePath, function(error, entries) {
assert.ok(async, "readdir is async");
assert.ok(!error, "there is no error when reading directory");
assert.ok(profileEntries.length <= entries.length,
- "got at least number of entries we expect");
+ "got et least number of entries we expect");
assert.ok(profileEntries.every(function(entry) {
return entries.indexOf(entry) >= 0;
}), "all profiles are present");
end();
});
async = true;
};
@@ -62,23 +62,23 @@ exports["test readdir error"] = function
async = true;
};
exports["test readdirSync"] = function(assert) {
var async = false;
var entries = fs.readdirSync(profilePath);
assert.ok(profileEntries.length <= entries.length,
- "got at least number of entries we expect");
+ "got et least number of entries we expect");
assert.ok(profileEntries.every(function(entry) {
return entries.indexOf(entry) >= 0;
}), "all profiles are present");
};
-exports["test readdirSync error"] = function(assert) {
+exports["test readirSync error"] = function(assert) {
var async = false;
var path = profilePath + "-does-not-exists";
try {
fs.readdirSync(path);
assert.fail(Error("No error was thrown"));
} catch (error) {
assert.equal(error.message, "ENOENT, readdir " + path);
assert.equal(error.code, "ENOENT", "error has a code");
@@ -87,17 +87,16 @@ exports["test readdirSync error"] = func
}
};
exports["test readFile"] = function(assert, end) {
let async = false;
fs.readFile(filePathInProfile, function(error, content) {
assert.ok(async, "readFile is async");
assert.ok(!error, "error is falsy");
-
assert.ok(Buffer.isBuffer(content), "readFile returns buffer");
assert.ok(typeof(content.length) === "number", "buffer has length");
assert.ok(content.toString().indexOf("[Compatibility]") >= 0,
"content contains expected data");
end();
});
async = true;
};
@@ -334,16 +333,17 @@ exports["test fs.truncateSync fs.unlinkS
exports["test fs.truncate"] = function(assert, end) {
let path = truncatePath;
if (!fs.existsSync(path)) {
let async = false;
fs.truncate(path, 0, function(error) {
assert.ok(async, "truncate is async");
+ console.log(error);
assert.ok(!error, "no error");
assert.equal(fs.existsSync(path), true, "file was created");
fs.unlinkSync(path);
assert.equal(fs.existsSync(path), false, "file was removed");
end();
})
async = true;
}
@@ -454,33 +454,9 @@ exports["test fs.writeFile"] = function(
fs.unlinkSync(path);
assert.ok(!fs.exists(path), "file was removed");
end();
});
async = true;
};
-exports["test fs.writeFile (with large files)"] = function(assert, end) {
- let path = writePath;
- let content = "";
-
- for (var i = 0; i < 100000; i++) {
- content += "buffer\n";
- }
-
- var async = false;
- fs.writeFile(path, content, function(error) {
- assert.ok(async, "fs write is async");
- assert.ok(!error, "error is falsy");
- assert.ok(fs.existsSync(path), "file was created");
- assert.equal(fs.readFileSync(path).toString(),
- content,
- "contet was written");
- fs.unlinkSync(path);
- assert.ok(!fs.exists(path), "file was removed");
-
- end();
- });
- async = true;
-};
-
require("test").run(exports);
--- a/addon-sdk/source/test/test-observer-service.js
+++ b/addon-sdk/source/test/test-observer-service.js
@@ -17,23 +17,23 @@ exports.testUnloadAndErrorLogging = func
var badCb = function(subject, data) {
throw new Error("foo");
};
sbobsvc.add("blarg", cb);
observers.notify("blarg", "yo yo");
test.assertEqual(timesCalled, 1);
sbobsvc.add("narg", badCb);
observers.notify("narg", "yo yo");
-
- test.assertEqual(messages[0], "console.error: " + require("sdk/self").name + ": \n");
- var lines = messages[1].split("\n");
- test.assertEqual(lines[0], " Message: Error: foo");
- test.assertEqual(lines[1], " Stack:");
+ var lines = messages[0].split("\n");
+ test.assertEqual(lines[0], "error: " + require("sdk/self").name + ": An exception occurred.");
+ test.assertEqual(lines[0], "error: " + require("sdk/self").name + ": An exception occurred.");
+ test.assertEqual(lines[1], "Error: foo");
// Keep in mind to update "18" to the line of "throw new Error("foo")"
- test.assert(lines[2].indexOf(module.uri + ":18") != -1);
+ test.assertEqual(lines[2], module.uri + " 18");
+ test.assertEqual(lines[3], "Traceback (most recent call last):");
loader.unload();
observers.notify("blarg", "yo yo");
test.assertEqual(timesCalled, 1);
};
exports.testObserverService = function(test) {
var ios = Cc['@mozilla.org/network/io-service;1']
--- a/addon-sdk/source/test/test-page-mod.js
+++ b/addon-sdk/source/test/test-page-mod.js
@@ -14,18 +14,16 @@ const windowUtils = require('sdk/depreca
const { getTabContentWindow, getActiveTab, setTabURL, openTab, closeTab } = require('sdk/tabs/utils');
const xulApp = require("sdk/system/xul-app");
const { data, isPrivateBrowsingSupported } = require('sdk/self');
const { isPrivate } = require('sdk/private-browsing');
const { openWebpage } = require('./private-browsing/helper');
const { isTabPBSupported, isWindowPBSupported, isGlobalPBSupported } = require('sdk/private-browsing/utils');
const promise = require("sdk/core/promise");
const { pb } = require('./private-browsing/helper');
-const { URL } = require("sdk/url");
-const testPageURI = require("sdk/self").data.url("test.html");
/* XXX This can be used to delay closing the test Firefox instance for interactive
* testing or visual inspection. This test is registered first so that it runs
* the last. */
exports.delay = function(test) {
if (false) {
test.waitUntilDone(60000);
timer.setTimeout(function() {test.done();}, 4000);
@@ -116,26 +114,26 @@ exports.testPageModIncludes = function(t
// so we attach it on 'start'.
contentScriptWhen: 'start',
onAttach: function(worker) {
worker.postMessage(this.include[0]);
}
};
}
- testPageMod(test, testPageURI, [
+ testPageMod(test, "about:buildconfig", [
createPageModTest("*", false),
createPageModTest("*.google.com", false),
- createPageModTest("resource:*", true),
- createPageModTest("resource:", false),
- createPageModTest(testPageURI, true)
+ createPageModTest("about:*", true),
+ createPageModTest("about:", false),
+ createPageModTest("about:buildconfig", true)
],
function (win, done) {
- test.waitUntil(function () win.localStorage[testPageURI],
- testPageURI + " page-mod to be executed")
+ test.waitUntil(function () win.localStorage["about:buildconfig"],
+ "about:buildconfig page-mod to be executed")
.then(function () {
asserts.forEach(function(fn) {
fn(test, win);
});
done();
});
}
);
--- a/addon-sdk/source/test/test-page-worker.js
+++ b/addon-sdk/source/test/test-page-worker.js
@@ -2,18 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Loader } = require('sdk/test/loader');
const Pages = require("sdk/page-worker");
const Page = Pages.Page;
-const { URL } = require("sdk/url");
-const testURI = require("sdk/self").data.url("test.html");
const ERR_DESTROYED =
"Couldn't find the worker to receive this message. " +
"The script may not be initialized yet, or may already have been unloaded.";
exports.testSimplePageCreation = function(assert, done) {
let page = new Page({
contentScript: "self.postMessage(window.location.href)",
@@ -153,33 +151,24 @@ exports.testValidateOptions = function(a
"Validation correctly denied a non-function onMessage."
);
assert.pass("Options validation is working.");
}
exports.testContentAndAllowGettersAndSetters = function(assert, done) {
let content = "data:text/html;charset=utf-8,<script>window.localStorage.allowScript=3;</script>";
-
- // Load up the page with testURI initially for the resource:// principal,
- // then load the actual data:* content, as data:* URIs no longer
- // have localStorage
let page = Page({
- contentURL: testURI,
- contentScript: "if (window.location.href==='"+testURI+"')" +
- " self.postMessage('reload');" +
- "else " +
- " self.postMessage(window.localStorage.allowScript)",
+ contentURL: content,
+ contentScript: "self.postMessage(window.localStorage.allowScript)",
contentScriptWhen: "end",
onMessage: step0
});
function step0(message) {
- if (message === 'reload')
- return page.contentURL = content;
assert.equal(message, "3",
"Correct value expected for allowScript - 3");
assert.equal(page.contentURL, content,
"Correct content expected");
page.removeListener('message', step0);
page.on('message', step1);
page.allow = { script: false };
page.contentURL = content =
--- a/addon-sdk/source/test/test-places-bookmarks.js
+++ b/addon-sdk/source/test/test-places-bookmarks.js
@@ -20,19 +20,19 @@ const { defer: async } = require('sdk/la
const { before, after } = require('sdk/test/utils');
const {
Bookmark, Group, Separator,
save, search, remove,
MENU, TOOLBAR, UNSORTED
} = require('sdk/places/bookmarks');
const {
- invalidResolve, invalidReject, createTree,
- compareWithHost, createBookmark, createBookmarkItem,
- createBookmarkTree, addVisits, resetPlaces
+ invalidResolve, invalidReject, clearBookmarks, createTree,
+ compareWithHost, clearAllBookmarks, createBookmark, createBookmarkItem,
+ createBookmarkTree, addVisits
} = require('./places-helper');
const { promisedEmitter } = require('sdk/places/utils');
const bmsrv = Cc['@mozilla.org/browser/nav-bookmarks-service;1'].
getService(Ci.nsINavBookmarksService);
const tagsrv = Cc['@mozilla.org/browser/tagging-service;1'].
getService(Ci.nsITaggingService);
exports.testDefaultFolders = function (assert) {
@@ -936,18 +936,23 @@ exports.testCheckSaveOrder = function (a
saveP(bookmarks).then(results => {
for (let i = 0; i < bookmarks.length; i++)
assert.equal(results[i].url, bookmarks[i].url,
'correct ordering of bookmark results');
done();
});
};
-before(exports, (name, assert, done) => resetPlaces(done));
-after(exports, (name, assert, done) => resetPlaces(done));
+before(exports, name => {
+ clearAllBookmarks();
+});
+
+after(exports, name => {
+ clearAllBookmarks();
+});
function saveP () {
return promisedEmitter(save.apply(null, Array.slice(arguments)));
}
function searchP () {
return promisedEmitter(search.apply(null, Array.slice(arguments)));
}
--- a/addon-sdk/source/test/test-places-favicon.js
+++ b/addon-sdk/source/test/test-places-favicon.js
@@ -14,17 +14,17 @@ const { Cc, Ci, Cu } = require('chrome')
const { getFavicon } = require('sdk/places/favicon');
const tabs = require('sdk/tabs');
const open = tabs.open;
const port = 8099;
const host = 'http://localhost:' + port;
const { onFaviconChange, serve, binFavicon } = require('./favicon-helpers');
const { once } = require('sdk/system/events');
const { defer } = require('sdk/core/promise');
-const { resetPlaces } = require('./places-helper');
+const { clearHistory } = require('./places-helper');
const faviconService = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
exports.testStringGetFaviconCallbackSuccess = function (assert, done) {
let name = 'callbacksuccess'
let srv = makeServer(name);
let url = host + '/' + name + '.html';
let favicon = host + '/' + name + '.ico';
@@ -176,15 +176,15 @@ function waitAndExpire (url) {
});
faviconService.expireAllFavicons();
});
return deferred.promise;
}
function complete(tab, srv, done) {
tab.close(function () {
- resetPlaces(() => {
+ clearHistory(() => {
srv.stop(done);
});
});
}
require("test").run(exports);
--- a/addon-sdk/source/test/test-places-history.js
+++ b/addon-sdk/source/test/test-places-history.js
@@ -9,25 +9,26 @@ module.metadata = {
}
};
const { Cc, Ci } = require('chrome');
const { defer, all } = require('sdk/core/promise');
const { has } = require('sdk/util/array');
const { setTimeout } = require('sdk/timers');
const { before, after } = require('sdk/test/utils');
-const { set } = require('sdk/preferences/service');
const {
search
} = require('sdk/places/history');
const {
- invalidResolve, invalidReject, createTree,
- compareWithHost, addVisits, resetPlaces
+ invalidResolve, invalidReject, clearBookmarks, createTree,
+ compareWithHost, clearAllBookmarks, addVisits, clearHistory
} = require('./places-helper');
const { promisedEmitter } = require('sdk/places/utils');
+const hsrv = Cc['@mozilla.org/browser/nav-history-service;1'].
+ getService(Ci.nsINavHistoryService);
exports.testEmptyQuery = function (assert, done) {
let within = toBeWithin();
addVisits([
'http://simplequery-1.com', 'http://simplequery-2.com'
]).then(searchP).then(results => {
assert.equal(results.length, 2, 'Correct number of entries returned');
assert.equal(results[0].url, 'http://simplequery-1.com/',
@@ -233,16 +234,21 @@ exports.testEmitters = function (assert,
function toBeWithin (range) {
range = range || 2000;
var current = new Date() * 1000; // convert to microseconds
return compared => {
return compared - current < range;
};
}
+function clear (done) {
+ clearAllBookmarks();
+ clearHistory(done);
+}
+
function searchP () {
return promisedEmitter(search.apply(null, Array.slice(arguments)));
}
-before(exports, (name, assert, done) => resetPlaces(done));
-after(exports, (name, assert, done) => resetPlaces(done));
+before(exports, (name, assert, done) => clear(done));
+after(exports, (name, assert, done) => clear(done));
require('test').run(exports);
--- a/addon-sdk/source/test/test-places-host.js
+++ b/addon-sdk/source/test/test-places-host.js
@@ -9,33 +9,32 @@ module.metadata = {
}
};
const { Cc, Ci } = require('chrome');
const { defer, all } = require('sdk/core/promise');
const { setTimeout } = require('sdk/timers');
const { newURI } = require('sdk/url/utils');
const { send } = require('sdk/addon/events');
-const { set } = require('sdk/preferences/service');
-const { before, after } = require('sdk/test/utils');
require('sdk/places/host/host-bookmarks');
require('sdk/places/host/host-tags');
require('sdk/places/host/host-query');
const {
- invalidResolve, invalidReject, createTree,
- compareWithHost, createBookmark, createBookmarkTree, resetPlaces
+ invalidResolve, invalidReject, clearBookmarks, createTree,
+ compareWithHost, clearAllBookmarks, createBookmark, createBookmarkTree
} = require('./places-helper');
const bmsrv = Cc['@mozilla.org/browser/nav-bookmarks-service;1'].
getService(Ci.nsINavBookmarksService);
const hsrv = Cc['@mozilla.org/browser/nav-history-service;1'].
getService(Ci.nsINavHistoryService);
const tagsrv = Cc['@mozilla.org/browser/tagging-service;1'].
getService(Ci.nsITaggingService);
+clearAllBookmarks();
exports.testBookmarksCreate = function (assert, done) {
let items = [{
title: 'my title',
url: 'http://moz.com',
tags: ['some', 'tags', 'yeah'],
type: 'bookmark'
}, {
@@ -47,16 +46,17 @@ exports.testBookmarksCreate = function (
group: bmsrv.unfiledBookmarksFolder
}];
all(items.map(function (item) {
return send('sdk-places-bookmarks-create', item).then(function (data) {
compareWithHost(assert, data);
}, invalidReject(assert));
})).then(function () {
+ clearAllBookmarks();
done();
}, invalidReject(assert));
};
exports.testBookmarksCreateFail = function (assert, done) {
let items = [{
title: 'my title',
url: 'not-a-url',
@@ -67,16 +67,17 @@ exports.testBookmarksCreateFail = functi
}, {
group: bmsrv.unfiledBookmarksFolder
}];
all(items.map(function (item) {
return send('sdk-places-bookmarks-create', item).then(null, function (reason) {
assert.ok(reason, 'bookmark create should fail');
});
})).then(function () {
+ clearAllBookmarks();
done();
});
};
exports.testBookmarkLastUpdated = function (assert, done) {
let timestamp;
let item;
createBookmark().then(function (data) {
@@ -88,31 +89,33 @@ exports.testBookmarkLastUpdated = functi
item.title = 'updated mozilla';
return send('sdk-places-bookmarks-save', item).then(function (data) {
let deferred = defer();
setTimeout(function () deferred.resolve(data), 100);
return deferred.promise;
});
}).then(function (data) {
assert.ok(data.updated > timestamp, 'time has elapsed and updated the updated property');
+ clearAllBookmarks();
done();
});
};
exports.testBookmarkRemove = function (assert, done) {
let id;
createBookmark().then(function (data) {
id = data.id;
compareWithHost(assert, data); // ensure bookmark exists
bmsrv.getItemTitle(id); // does not throw an error
return send('sdk-places-bookmarks-remove', data);
}).then(function () {
assert.throws(function () {
bmsrv.getItemTitle(id);
}, 'item should no longer exist');
+ clearAllBookmarks();
done();
}, console.error);
};
exports.testBookmarkGet = function (assert, done) {
let bookmark;
createBookmark().then(function (data) {
bookmark = data;
@@ -125,16 +128,17 @@ exports.testBookmarkGet = function (asse
'correctly fetched tag ' + tag);
}
assert.equal(bookmark.tags.length, data.tags.length,
'same amount of tags');
}
else
assert.equal(bookmark[prop], data[prop], 'correctly fetched ' + prop);
});
+ clearAllBookmarks();
done();
});
};
exports.testTagsTag = function (assert, done) {
let url;
createBookmark().then(function (data) {
url = data.url;
@@ -142,16 +146,17 @@ exports.testTagsTag = function (assert,
url: data.url, tags: ['mozzerella', 'foxfire']
});
}).then(function () {
let tags = tagsrv.getTagsForURI(newURI(url));
assert.ok(~tags.indexOf('mozzerella'), 'first tag found');
assert.ok(~tags.indexOf('foxfire'), 'second tag found');
assert.ok(~tags.indexOf('firefox'), 'default tag found');
assert.equal(tags.length, 3, 'no extra tags');
+ clearAllBookmarks();
done();
});
};
exports.testTagsUntag = function (assert, done) {
let item;
createBookmark({tags: ['tag1', 'tag2', 'tag3']}).then(function (data) {
item = data;
@@ -161,46 +166,49 @@ exports.testTagsUntag = function (assert
});
}).then(function () {
let tags = tagsrv.getTagsForURI(newURI(item.url));
assert.ok(~tags.indexOf('tag1'), 'first tag persisted');
assert.ok(~tags.indexOf('tag3'), 'second tag persisted');
assert.ok(!~tags.indexOf('firefox'), 'first tag removed');
assert.ok(!~tags.indexOf('tag2'), 'second tag removed');
assert.equal(tags.length, 2, 'no extra tags');
+ clearAllBookmarks();
done();
});
};
exports.testTagsGetURLsByTag = function (assert, done) {
let item;
createBookmark().then(function (data) {
item = data;
return send('sdk-places-tags-get-urls-by-tag', {
tag: 'firefox'
});
}).then(function(urls) {
assert.equal(item.url, urls[0], 'returned correct url');
assert.equal(urls.length, 1, 'returned only one url');
+ clearAllBookmarks();
done();
});
};
exports.testTagsGetTagsByURL = function (assert, done) {
let item;
createBookmark({ tags: ['firefox', 'mozilla', 'metal']}).then(function (data) {
item = data;
return send('sdk-places-tags-get-tags-by-url', {
url: data.url,
});
}).then(function(tags) {
assert.ok(~tags.indexOf('firefox'), 'returned first tag');
assert.ok(~tags.indexOf('mozilla'), 'returned second tag');
assert.ok(~tags.indexOf('metal'), 'returned third tag');
assert.equal(tags.length, 3, 'returned all tags');
+ clearAllBookmarks();
done();
});
};
exports.testHostQuery = function (assert, done) {
all([
createBookmark({ url: 'http://firefox.com', tags: ['firefox', 'mozilla'] }),
createBookmark({ url: 'http://mozilla.com', tags: ['mozilla'] }),
@@ -215,16 +223,17 @@ exports.testHostQuery = function (assert
assert.equal(results[0].url, 'http://mozilla.com/', 'is sorted by URI asc');
return send('sdk-places-query', {
queries: { tags: ['mozilla'] },
options: { sortingMode: 5, queryType: 1 } // sort by URI descending, bookmarks only
});
}).then(results => {
assert.equal(results.length, 2, 'should only return two');
assert.equal(results[0].url, 'http://firefox.com/', 'is sorted by URI desc');
+ clearAllBookmarks();
done();
});
};
exports.testHostMultiQuery = function (assert, done) {
all([
createBookmark({ url: 'http://firefox.com', tags: ['firefox', 'mozilla'] }),
createBookmark({ url: 'http://mozilla.com', tags: ['mozilla'] }),
@@ -239,38 +248,37 @@ exports.testHostMultiQuery = function (a
assert.equal(results[0].url, 'http://firefox.com/', 'should match URL or tag');
assert.equal(results[1].url, 'http://thunderbird.com/', 'should match URL or tag');
return send('sdk-places-query', {
queries: [{ tags: ['firefox'], url: 'http://mozilla.com/' }],
options: { sortingMode: 5, queryType: 1 } // sort by URI descending, bookmarks only
});
}).then(results => {
assert.equal(results.length, 0, 'query props should be AND\'d');
+ clearAllBookmarks();
done();
});
};
exports.testGetAllBookmarks = function (assert, done) {
createBookmarkTree().then(() => {
return send('sdk-places-bookmarks-get-all', {});
}).then(res => {
assert.equal(res.length, 8, 'all bookmarks returned');
+ clearAllBookmarks();
done();
}, console.error);
};
exports.testGetAllChildren = function (assert, done) {
createBookmarkTree().then(results => {
return send('sdk-places-bookmarks-get-children', {
id: results.filter(({title}) => title === 'mozgroup')[0].id
});
}).then(results => {
assert.equal(results.length, 5,
'should return all children and folders at a single depth');
+ clearAllBookmarks();
done();
});
};
-
-before(exports, (name, assert, done) => resetPlaces(done));
-after(exports, (name, assert, done) => resetPlaces(done));
-
require('test').run(exports);
--- a/addon-sdk/source/test/test-plain-text-console.js
+++ b/addon-sdk/source/test/test-plain-text-console.js
@@ -31,134 +31,121 @@ exports.testPlainTextConsole = function(
prefs.reset(ADDON_LOG_LEVEL_PREF);
var Console = require("sdk/console/plain-text").PlainTextConsole;
var con = new Console(print);
test.pass("PlainTextConsole instantiates");
con.log('testing', 1, [2, 3, 4]);
- test.assertEqual(lastPrint(), "console.log: " + name + ": testing, 1, Array [2,3,4]\n",
+ test.assertEqual(lastPrint(), "info: " + name + ": testing 1 2,3,4\n",
"PlainTextConsole.log() must work.");
con.info('testing', 1, [2, 3, 4]);
- test.assertEqual(lastPrint(), "console.info: " + name + ": testing, 1, Array [2,3,4]\n",
+ test.assertEqual(lastPrint(), "info: " + name + ": testing 1 2,3,4\n",
"PlainTextConsole.info() must work.");
con.warn('testing', 1, [2, 3, 4]);
- test.assertEqual(lastPrint(), "console.warn: " + name + ": testing, 1, Array [2,3,4]\n",
+ test.assertEqual(lastPrint(), "warn: " + name + ": testing 1 2,3,4\n",
"PlainTextConsole.warn() must work.");
con.error('testing', 1, [2, 3, 4]);
- test.assertEqual(prints[0], "console.error: " + name + ": \n",
+ test.assertEqual(lastPrint(), "error: " + name + ": testing 1 2,3,4\n",
"PlainTextConsole.error() must work.");
- test.assertEqual(prints[1], " testing\n")
- test.assertEqual(prints[2], " 1\n")
- test.assertEqual(prints[3], "Array\n - 0 = 2\n - 1 = 3\n - 2 = 4\n - length = 3\n");
- prints = [];
con.debug('testing', 1, [2, 3, 4]);
- test.assertEqual(prints[0], "console.debug: " + name + ": \n",
+ test.assertEqual(lastPrint(), "debug: " + name + ": testing 1 2,3,4\n",
"PlainTextConsole.debug() must work.");
- test.assertEqual(prints[1], " testing\n")
- test.assertEqual(prints[2], " 1\n")
- test.assertEqual(prints[3], "Array\n - 0 = 2\n - 1 = 3\n - 2 = 4\n - length = 3\n");
- prints = [];
con.log('testing', undefined);
- test.assertEqual(lastPrint(), "console.log: " + name + ": testing, undefined\n",
+ test.assertEqual(lastPrint(), "info: " + name + ": testing undefined\n",
"PlainTextConsole.log() must stringify undefined.");
con.log('testing', null);
- test.assertEqual(lastPrint(), "console.log: " + name + ": testing, null\n",
+ test.assertEqual(lastPrint(), "info: " + name + ": testing null\n",
"PlainTextConsole.log() must stringify null.");
- // TODO: Fix console.jsm to detect custom toString.
con.log("testing", { toString: function() "obj.toString()" });
- test.assertEqual(lastPrint(), "console.log: " + name + ": testing, {}\n",
- "PlainTextConsole.log() doesn't printify custom toString.");
+ test.assertEqual(lastPrint(), "info: " + name + ": testing obj.toString()\n",
+ "PlainTextConsole.log() must stringify custom toString.");
con.log("testing", { toString: function() { throw "fail!"; } });
- test.assertEqual(lastPrint(), "console.log: " + name + ": testing, {}\n",
+ test.assertEqual(lastPrint(), "info: " + name + ": testing <toString() error>\n",
"PlainTextConsole.log() must stringify custom bad toString.");
-
con.exception(new Error("blah"));
-
- test.assertEqual(prints[0], "console.error: " + name + ": \n");
- let tbLines = prints[1].split("\n");
- test.assertEqual(tbLines[0], " Message: Error: blah");
- test.assertEqual(tbLines[1], " Stack:");
- test.assert(prints[1].indexOf(module.uri + ":84") !== -1);
- prints = []
+ var tbLines = prints[0].split("\n");
+ test.assertEqual(tbLines[0], "error: " + name + ": An exception occurred.");
+ test.assertEqual(tbLines[1], "Error: blah");
+ test.assertEqual(tbLines[2], module.uri + " 74");
+ test.assertEqual(tbLines[3], "Traceback (most recent call last):");
+ prints = [];
try {
loadSubScript("invalid-url", {});
test.fail("successed in calling loadSubScript with invalid-url");
}
catch(e) {
con.exception(e);
}
- test.assertEqual(prints[0], "console.error: " + name + ": \n");
- test.assertEqual(prints[1], " Error creating URI (invalid URL scheme?)\n");
+ var tbLines = prints[0].split("\n");
+ test.assertEqual(tbLines[0], "error: " + name + ": An exception occurred.");
+ test.assertEqual(tbLines[1], "Error creating URI (invalid URL scheme?)");
+ test.assertEqual(tbLines[2], "Traceback (most recent call last):");
+
prints = [];
-
con.trace();
- let tbLines = prints[0].split("\n");
- test.assertEqual(tbLines[0], "console.trace: " + name + ": ");
- test.assert(tbLines[1].indexOf("_ain-text-console.js 105") == 0);
- prints = [];
+ tbLines = prints[0].split("\n");
+ test.assertEqual(tbLines[0], "info: " + name + ": Traceback (most recent call last):");
+ test.assertEqual(tbLines[tbLines.length - 4].trim(), "con.trace();");
// Whether or not console methods should print at the various log levels,
// structured as a hash of levels, each of which contains a hash of methods,
// each of whose value is whether or not it should print, i.e.:
// { [level]: { [method]: [prints?], ... }, ... }.
let levels = {
all: { debug: true, log: true, info: true, warn: true, error: true },
debug: { debug: true, log: true, info: true, warn: true, error: true },
info: { debug: false, log: true, info: true, warn: true, error: true },
warn: { debug: false, log: false, info: false, warn: true, error: true },
error: { debug: false, log: false, info: false, warn: false, error: true },
off: { debug: false, log: false, info: false, warn: false, error: false },
};
// The messages we use to test the various methods, as a hash of methods.
let messages = {
- debug: "console.debug: " + name + ": \n \n",
- log: "console.log: " + name + ": \n",
- info: "console.info: " + name + ": \n",
- warn: "console.warn: " + name + ": \n",
- error: "console.error: " + name + ": \n \n",
+ debug: "debug: " + name + ": \n",
+ log: "info: " + name + ": \n",
+ info: "info: " + name + ": \n",
+ warn: "warn: " + name + ": \n",
+ error: "error: " + name + ": \n",
};
for (let level in levels) {
let methods = levels[level];
for (let method in methods) {
// We have to reset the log level pref each time we run the test
// because the test runner relies on the console to print test output,
// and test results would not get printed to the console for some
// values of the pref.
prefs.set(SDK_LOG_LEVEL_PREF, level);
con[method]("");
prefs.set(SDK_LOG_LEVEL_PREF, "all");
- test.assertEqual(prints.join(""),
- (methods[method] ? messages[method] : ""),
+ test.assertEqual(lastPrint(), (methods[method] ? messages[method] : null),
"at log level '" + level + "', " + method + "() " +
(methods[method] ? "prints" : "doesn't print"));
- prints = [];
}
}
prefs.set(SDK_LOG_LEVEL_PREF, "off");
prefs.set(ADDON_LOG_LEVEL_PREF, "all");
con.debug("");
- test.assertEqual(prints.join(""), messages["debug"],
+ test.assertEqual(lastPrint(), messages["debug"],
"addon log level 'all' overrides SDK log level 'off'");
- prints = [];
prefs.set(SDK_LOG_LEVEL_PREF, "all");
prefs.set(ADDON_LOG_LEVEL_PREF, "off");
con.error("");
prefs.reset(ADDON_LOG_LEVEL_PREF);
test.assertEqual(lastPrint(), null,
"addon log level 'off' overrides SDK log level 'all'");
--- a/addon-sdk/source/test/test-system-events.js
+++ b/addon-sdk/source/test/test-system-events.js
@@ -5,18 +5,16 @@
const events = require("sdk/system/events");
const self = require("sdk/self");
const { Cc, Ci, Cu } = require("chrome");
const { setTimeout } = require("sdk/timers");
const { Loader, LoaderWithHookedConsole2 } = require("sdk/test/loader");
const nsIObserverService = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
-let isConsoleEvent = (topic) =>
- !!~["console-api-log-event", "console-storage-cache-event"].indexOf(topic)
exports["test basic"] = function(assert) {
let type = Date.now().toString(32);
let timesCalled = 0;
function handler(subject, data) { timesCalled++; };
events.on(type, handler);
@@ -45,20 +43,20 @@ exports["test error reporting"] = functi
let lineNumber;
try { brokenHandler() } catch (error) { lineNumber = error.lineNumber }
let errorType = Date.now().toString(32);
events.on(errorType, brokenHandler);
events.emit(errorType, { data: "yo yo" });
- assert.equal(messages.length, 2, "Got an exception");
- assert.equal(messages[0], "console.error: " + self.name + ": \n",
- "error is logged");
- let text = messages[1];
+ assert.equal(messages.length, 1, "Got an exception");
+ let text = messages[0];
+ assert.ok(text.indexOf(self.name + ": An exception occurred.") >= 0,
+ "error is logged");
assert.ok(text.indexOf("Error: foo") >= 0, "error message is logged");
assert.ok(text.indexOf(module.uri) >= 0, "module uri is logged");
assert.ok(text.indexOf(lineNumber) >= 0, "error line is logged");
events.off(errorType, brokenHandler);
loader.unload();
};
@@ -101,19 +99,16 @@ exports["test handle nsIObserverService
let type = Date.now().toString(32);
let timesCalled = 0;
let lastSubject = null;
let lastData = null;
let lastType = null;
function handler({ subject, data, type }) {
- // Ignores internal console events
- if (isConsoleEvent(type))
- return;
timesCalled++;
lastSubject = subject;
lastData = data;
lastType = type;
};
events.on(type, handler);
nsIObserverService.notifyObservers(uri, type, "some data");
@@ -168,35 +163,33 @@ exports["test emit to nsIObserverService
let lastTopic = null;
var topic = Date.now().toString(32)
let nsIObserver = {
QueryInterface: function() {
return nsIObserver;
},
observe: function(subject, topic, data) {
- // Ignores internal console events
- if (isConsoleEvent(topic))
- return;
timesCalled = timesCalled + 1;
lastSubject = subject;
lastData = data;
lastTopic = topic;
}
};
nsIObserverService.addObserver(nsIObserver, topic, false);
events.emit(topic, { subject: uri, data: "some data" });
assert.equal(timesCalled, 1, "emit notifies observers");
assert.equal(lastTopic, topic, "event type is notification topic");
assert.equal(lastSubject.wrappedJSObject.object, uri,
"event.subject is notification subject");
assert.equal(lastData, "some data", "event.data is notification data");
+
function customSubject() {}
function customData() {}
events.emit(topic, { subject: customSubject, data: customData });
assert.equal(timesCalled, 2, "emit notifies observers");
assert.equal(lastTopic, topic, "event.type is notification");
assert.equal(lastSubject.wrappedJSObject.object, customSubject,
"event.subject is notification subject");
@@ -208,21 +201,20 @@ exports["test emit to nsIObserverService
assert.equal(timesCalled, 2, "removed observers no longer invoked");
nsIObserverService.addObserver(nsIObserver, "*", false);
events.emit(topic, { data: "data again" });
assert.equal(timesCalled, 3, "emit notifies * observers");
-
assert.equal(lastTopic, topic, "event.type is notification");
assert.equal(lastSubject, null,
"event.subject is notification subject");
assert.equal(lastData, "data again", "event.data is notification data");
nsIObserverService.removeObserver(nsIObserver, "*");
-
+
events.emit(topic, { data: "last data" });
assert.equal(timesCalled, 3, "removed observers no longer invoked");
}
require("test").run(exports);
--- a/addon-sdk/source/test/test-tab-utils.js
+++ b/addon-sdk/source/test/test-tab-utils.js
@@ -1,50 +1,57 @@
'use strict';
const { getTabs } = require('sdk/tabs/utils');
const { isGlobalPBSupported, isWindowPBSupported, isTabPBSupported } = require('sdk/private-browsing/utils');
const { browserWindows } = require('sdk/windows');
const tabs = require('sdk/tabs');
const { pb } = require('./private-browsing/helper');
const { isPrivate } = require('sdk/private-browsing');
-const { openTab, closeTab, getTabContentWindow, getOwnerWindow } = require('sdk/tabs/utils');
+const { openTab, closeTab, getTabContentWindow } = require('sdk/tabs/utils');
const { open, close } = require('sdk/window/helpers');
const { windows } = require('sdk/window/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { fromIterator } = require('sdk/util/array');
-if (isWindowPBSupported) {
+if (isGlobalPBSupported) {
exports.testGetTabs = function(assert, done) {
- let tabCount = getTabs().length;
- let windowCount = browserWindows.length;
-
+ pb.once('start', function() {
+ tabs.open({
+ url: 'about:blank',
+ inNewWindow: true,
+ onOpen: function(tab) {
+ assert.equal(getTabs().length, 2, 'there are two tabs');
+ assert.equal(browserWindows.length, 2, 'there are two windows');
+ pb.once('stop', function() {
+ done();
+ });
+ pb.deactivate();
+ }
+ });
+ });
+ pb.activate();
+ };
+}
+else if (isWindowPBSupported) {
+ exports.testGetTabs = function(assert, done) {
open(null, {
features: {
private: true,
toolbar: true,
chrome: true
}
}).then(function(window) {
assert.ok(isPrivate(window), 'new tab is private');
-
- assert.equal(getTabs().length, tabCount, 'there are no new tabs found');
- getTabs().forEach(function(tab) {
- assert.equal(isPrivate(tab), false, 'all found tabs are not private');
- assert.equal(isPrivate(getOwnerWindow(tab)), false, 'all found tabs are not private');
- assert.equal(isPrivate(getTabContentWindow(tab)), false, 'all found tabs are not private');
+ assert.equal(getTabs().length, 1, 'there is one tab found');
+ assert.equal(browserWindows.length, 1, 'there is one window found');
+ fromIterator(browserWindows).forEach(function(window) {
+ assert.ok(!isPrivate(window), 'all found windows are not private');
});
-
- assert.equal(browserWindows.length, windowCount, 'there are no new windows found');
- fromIterator(browserWindows).forEach(function(window) {
- assert.equal(isPrivate(window), false, 'all found windows are not private');
- });
-
assert.equal(windows(null, {includePrivate: true}).length, 2, 'there are really two windows');
-
close(window).then(done);
});
};
}
else if (isTabPBSupported) {
exports.testGetTabs = function(assert, done) {
let startTabCount = getTabs().length;
let tab = openTab(getMostRecentBrowserWindow(), 'about:blank', {
@@ -59,9 +66,12 @@ else if (isTabPBSupported) {
'the last tab is the opened tab');
assert.equal(browserWindows.length, 1, 'there is only one window');
closeTab(tab);
done();
};
}
+// Test disabled because of bug 855771
+module.exports = {};
+
require('test').run(exports);
--- a/addon-sdk/source/test/test-timer.js
+++ b/addon-sdk/source/test/test-timer.js
@@ -1,177 +1,131 @@
/* 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/. */
var timer = require("sdk/timers");
const { Loader } = require("sdk/test/loader");
-exports.testSetTimeout = function(assert, end) {
+exports.testSetTimeout = function(test) {
timer.setTimeout(function() {
- assert.pass("testSetTimeout passed");
- end();
+ test.pass("testSetTimeout passed");
+ test.done();
}, 1);
+ test.waitUntilDone();
};
-exports.testParamedSetTimeout = function(assert, end) {
+exports.testParamedSetTimeout = function(test) {
let params = [1, 'foo', { bar: 'test' }, null, undefined];
timer.setTimeout.apply(null, [function() {
- assert.equal(arguments.length, params.length);
+ test.assertEqual(arguments.length, params.length);
for (let i = 0, ii = params.length; i < ii; i++)
- assert.equal(params[i], arguments[i]);
- end();
+ test.assertEqual(params[i], arguments[i]);
+ test.done();
}, 1].concat(params));
+ test.waitUntilDone();
};
-exports.testClearTimeout = function(assert, end) {
+exports.testClearTimeout = function(test) {
var myFunc = function myFunc() {
- assert.fail("myFunc() should not be called in testClearTimeout");
+ test.fail("myFunc() should not be called in testClearTimeout");
};
var id = timer.setTimeout(myFunc, 1);
timer.setTimeout(function() {
- assert.pass("testClearTimeout passed");
- end();
+ test.pass("testClearTimeout passed");
+ test.done();
}, 2);
timer.clearTimeout(id);
+ test.waitUntilDone();
};
-exports.testParamedClearTimeout = function(assert, end) {
+exports.testParamedClearTimeout = function(test) {
let params = [1, 'foo', { bar: 'test' }, null, undefined];
var myFunc = function myFunc() {
- assert.fail("myFunc() should not be called in testClearTimeout");
+ test.fail("myFunc() should not be called in testClearTimeout");
};
var id = timer.setTimeout(myFunc, 1);
timer.setTimeout.apply(null, [function() {
- assert.equal(arguments.length, params.length);
+ test.assertEqual(arguments.length, params.length);
for (let i = 0, ii = params.length; i < ii; i++)
- assert.equal(params[i], arguments[i]);
- end();
+ test.assertEqual(params[i], arguments[i]);
+ test.done();
}, 1].concat(params));
timer.clearTimeout(id);
+ test.waitUntilDone();
};
-exports.testSetInterval = function (assert, end) {
+exports.testSetInterval = function (test) {
var count = 0;
var id = timer.setInterval(function () {
count++;
if (count >= 5) {
timer.clearInterval(id);
- assert.pass("testSetInterval passed");
- end();
+ test.pass("testSetInterval passed");
+ test.done();
}
}, 1);
+ test.waitUntilDone();
};
-exports.testParamedSetInerval = function(assert, end) {
+exports.testParamedSetInerval = function(test) {
let params = [1, 'foo', { bar: 'test' }, null, undefined];
let count = 0;
let id = timer.setInterval.apply(null, [function() {
count ++;
if (count < 5) {
- assert.equal(arguments.length, params.length);
+ test.assertEqual(arguments.length, params.length);
for (let i = 0, ii = params.length; i < ii; i++)
- assert.equal(params[i], arguments[i]);
+ test.assertEqual(params[i], arguments[i]);
} else {
timer.clearInterval(id);
- end();
+ test.done();
}
}, 1].concat(params));
+ test.waitUntilDone();
};
-exports.testClearInterval = function (assert, end) {
+exports.testClearInterval = function (test) {
timer.clearInterval(timer.setInterval(function () {
- assert.fail("setInterval callback should not be called");
+ test.fail("setInterval callback should not be called");
}, 1));
var id = timer.setInterval(function () {
timer.clearInterval(id);
- assert.pass("testClearInterval passed");
- end();
+ test.pass("testClearInterval passed");
+ test.done();
}, 2);
+ test.waitUntilDone();
};
-exports.testParamedClearInterval = function(assert, end) {
+exports.testParamedClearInterval = function(test) {
timer.clearInterval(timer.setInterval(function () {
- assert.fail("setInterval callback should not be called");
+ test.fail("setInterval callback should not be called");
}, 1, timer, {}, null));
let id = timer.setInterval(function() {
timer.clearInterval(id);
- assert.equal(3, arguments.length);
- end();
+ test.assertEqual(3, arguments.length);
+ test.done();
}, 2, undefined, 'test', {});
+ test.waitUntilDone();
};
-exports.testImmediate = function(assert, end) {
- let actual = [];
- let ticks = 0;
- timer.setImmediate(function(...params) {
- actual.push(params);
- assert.equal(ticks, 1, "is a next tick");
- assert.deepEqual(actual, [["start", "immediates"]]);
- }, "start", "immediates");
-
- timer.setImmediate(function(...params) {
- actual.push(params);
- assert.deepEqual(actual, [["start", "immediates"],
- ["added"]]);
- assert.equal(ticks, 1, "is a next tick");
- timer.setImmediate(function(...params) {
- actual.push(params);
- assert.equal(ticks, 2, "is second tick");
- assert.deepEqual(actual, [["start", "immediates"],
- ["added"],
- [],
- ["last", "immediate", "handler"],
- ["side-effect"]]);
- end();
- }, "side-effect");
- }, "added");
-
- timer.setImmediate(function(...params) {
- actual.push(params);
- assert.equal(ticks, 1, "is a next tick");
- assert.deepEqual(actual, [["start", "immediates"],
- ["added"],
- []]);
- timer.clearImmediate(removeID);
- });
-
- function removed() {
- assert.fail("should be removed");
- }
- let removeID = timer.setImmediate(removed);
-
- timer.setImmediate(function(...params) {
- actual.push(params);
- assert.equal(ticks, 1, "is a next tick");
- assert.deepEqual(actual, [["start", "immediates"],
- ["added"],
- [],
- ["last", "immediate", "handler"]]);
- ticks = ticks + 1;
- }, "last", "immediate", "handler");
-
-
- ticks = ticks + 1;
-};
-
-exports.testUnload = function(assert, end) {
+exports.testUnload = function(test) {
var loader = Loader(module);
var sbtimer = loader.require("sdk/timers");
var myFunc = function myFunc() {
- assert.fail("myFunc() should not be called in testUnload");
+ test.fail("myFunc() should not be called in testUnload");
};
sbtimer.setTimeout(myFunc, 1);
sbtimer.setTimeout(myFunc, 1, 'foo', 4, {}, undefined);
sbtimer.setInterval(myFunc, 1);
sbtimer.setInterval(myFunc, 1, {}, null, 'bar', undefined, 87);
loader.unload();
timer.setTimeout(function() {
- assert.pass("timer testUnload passed");
- end();
+ test.pass("timer testUnload passed");
+ test.done();
}, 2);
+ test.waitUntilDone();
};
-require("test").run(exports);
\ No newline at end of file
--- a/addon-sdk/source/test/test-window-events.js
+++ b/addon-sdk/source/test/test-window-events.js
@@ -1,11 +1,12 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
"use strict";
const { Loader } = require("sdk/test/loader");
const { open, getMostRecentBrowserWindow, getOuterId } = require("sdk/window/utils");
exports["test browser events"] = function(assert, done) {
let loader = Loader(module);
let { events } = loader.require("sdk/window/events");
@@ -47,9 +48,9 @@ if (require("sdk/system/xul-app").is("Fe
"test Unsupported Test": function UnsupportedTest (assert) {
assert.pass(
"Skipping this test until Fennec support is implemented." +
"See bug 793071");
}
}
}
-require("sdk/test").run(exports);
+require("test").run(exports);
--- a/addon-sdk/source/test/test-window-utils2.js
+++ b/addon-sdk/source/test/test-window-utils2.js
@@ -56,44 +56,16 @@ exports['test new top window with option
assert.equal(window.innerHeight, 100, 'height is set');
assert.equal(window.innerWidth, 200, 'height is set');
assert.equal(window.toolbar.visible, true, 'toolbar was set');
// Wait for the window unload before ending test
close(window).then(done);
};
-exports['test new top window with various URIs'] = function(assert, done) {
- let msg = 'only chrome, resource and data uris are allowed';
- assert.throws(function () {
- open('foo');
- }, msg);
- assert.throws(function () {
- open('http://foo');
- }, msg);
- assert.throws(function () {
- open('https://foo');
- }, msg);
- assert.throws(function () {
- open('ftp://foo');
- }, msg);
- assert.throws(function () {
- open('//foo');
- }, msg);
-
- let chromeWindow = open('chrome://foo/content/');
- assert.ok(~windows().indexOf(chromeWindow), 'chrome URI works');
-
- let resourceWindow = open('resource://foo');
- assert.ok(~windows().indexOf(resourceWindow), 'resource URI works');
-
- // Wait for the window unload before ending test
- close(chromeWindow).then(close.bind(null, resourceWindow)).then(done);
-};
-
exports.testBackgroundify = function(assert, done) {
let window = open('data:text/html;charset=utf-8,backgroundy');
assert.ok(~windows().indexOf(window),
'window is in the list of windows');
let backgroundy = backgroundify(window);
assert.equal(backgroundy, window, 'backgroundify returs give window back');
assert.ok(!~windows().indexOf(window),
'backgroundifyied window is in the list of windows');
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -172,16 +172,18 @@ pref("geo.enabled", true);
// see https://bugzilla.mozilla.org/show_bug.cgi?id=481566#c9
pref("content.sink.enable_perf_mode", 2); // 0 - switch, 1 - interactive, 2 - perf
pref("content.sink.pending_event_mode", 0);
pref("content.sink.perf_deflect_count", 1000000);
pref("content.sink.perf_parse_time", 50000000);
// Maximum scripts runtime before showing an alert
pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome
+// Disable the watchdog thread for B2G. See bug 870043 comment 31.
+pref("dom.use_watchdog", false);
// plugins
pref("plugin.disable", true);
pref("dom.ipc.plugins.enabled", true);
// product URLs
// The breakpad report server to link to in about:crashes
pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
{
- "revision": "755ad2936b1b80db70ecb45cf6798e9ab91a11dd",
+ "revision": "701cd7f0334bf2507c8531f8a1a800cb6f992d39",
"repo_path": "/integration/gaia-central"
}
--- a/browser/devtools/styleeditor/StyleSheetEditor.jsm
+++ b/browser/devtools/styleeditor/StyleSheetEditor.jsm
@@ -533,16 +533,18 @@ function setupBracketCompletion(sourceEd
// We detected an open bracket, sending closing character
let keyCode = pair.closeKeyCode;
let charCode = pair.closeString.charCodeAt(0);
let modifiers = 0;
let utils = editorElement.ownerDocument.defaultView.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
- let handled = utils.sendKeyEvent("keydown", keyCode, 0, modifiers);
- utils.sendKeyEvent("keypress", 0, charCode, modifiers, !handled);
+
+ if (utils.sendKeyEvent("keydown", keyCode, 0, modifiers)) {
+ utils.sendKeyEvent("keypress", 0, charCode, modifiers);
+ }
utils.sendKeyEvent("keyup", keyCode, 0, modifiers);
// and rewind caret
sourceEditor.setCaretOffset(sourceEditor.getCaretOffset() - 1);
}, false);
}
--- a/browser/devtools/tilt/tilt-visualizer.js
+++ b/browser/devtools/tilt/tilt-visualizer.js
@@ -1222,17 +1222,16 @@ TiltVisualizer.Controller.prototype = {
canvas.addEventListener("mousedown", this._onMouseDown, false);
canvas.addEventListener("mouseup", this._onMouseUp, false);
canvas.addEventListener("mousemove", this._onMouseMove, false);
canvas.addEventListener("mouseover", this._onMouseOver, false);
canvas.addEventListener("mouseout", this._onMouseOut, false);
canvas.addEventListener("MozMousePixelScroll", this._onMozScroll, false);
canvas.addEventListener("keydown", this._onKeyDown, false);
canvas.addEventListener("keyup", this._onKeyUp, false);
- canvas.addEventListener("keypress", this._onKeyPress, true);
canvas.addEventListener("blur", this._onBlur, false);
// handle resize events to change the arcball dimensions
presenter.contentWindow.addEventListener("resize", this._onResize, false);
},
/**
* Removes all added events listeners required by this controller.
@@ -1245,17 +1244,16 @@ TiltVisualizer.Controller.prototype = {
canvas.removeEventListener("mousedown", this._onMouseDown, false);
canvas.removeEventListener("mouseup", this._onMouseUp, false);
canvas.removeEventListener("mousemove", this._onMouseMove, false);
canvas.removeEventListener("mouseover", this._onMouseOver, false);
canvas.removeEventListener("mouseout", this._onMouseOut, false);
canvas.removeEventListener("MozMousePixelScroll", this._onMozScroll, false);
canvas.removeEventListener("keydown", this._onKeyDown, false);
canvas.removeEventListener("keyup", this._onKeyUp, false);
- canvas.removeEventListener("keypress", this._onKeyPress, true);
canvas.removeEventListener("blur", this._onBlur, false);
// Closing the tab would result in contentWindow being a dead object,
// so operations like removing event listeners won't work anymore.
if (presenter.contentWindow == presenter.chromeWindow.content) {
presenter.contentWindow.removeEventListener("resize", this._onResize, false);
}
},
@@ -1387,16 +1385,25 @@ TiltVisualizer.Controller.prototype = {
if (!e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
e.preventDefault();
e.stopPropagation();
this.arcball.keyDown(code);
} else {
this.arcball.cancelKeyEvents();
}
+
+ if (e.keyCode === e.DOM_VK_ESCAPE) {
+ let {TiltManager} = require("devtools/tilt/tilt");
+ let tilt =
+ TiltManager.getTiltForBrowser(this.presenter.chromeWindow);
+ e.preventDefault();
+ e.stopPropagation();
+ tilt.destroy(tilt.currentWindowId, true);
+ }
},
/**
* Called when a key is released.
*/
_onKeyUp: function TVC__onKeyUp(e)
{
let code = e.keyCode || e.which;
@@ -1415,31 +1422,16 @@ TiltVisualizer.Controller.prototype = {
if (!e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
e.preventDefault();
e.stopPropagation();
this.arcball.keyUp(code);
}
},
/**
- * Called when a key is pressed.
- */
- _onKeyPress: function TVC__onKeyPress(e)
- {
- if (e.keyCode === e.DOM_VK_ESCAPE) {
- let {TiltManager} = require("devtools/tilt/tilt");
- let tilt =
- TiltManager.getTiltForBrowser(this.presenter.chromeWindow);
- e.preventDefault();
- e.stopPropagation();
- tilt.destroy(tilt.currentWindowId, true);
- }
- },
-
- /**
* Called when the canvas looses focus.
*/
_onBlur: function TVC__onBlur(e) {
this.arcball.cancelKeyEvents();
},
/**
* Called when the content window of the current browser is resized.
--- a/browser/metro/base/content/TopSites.js
+++ b/browser/metro/base/content/TopSites.js
@@ -262,18 +262,16 @@ TopSitesView.prototype = Util.extend(Obj
// default: no action
}
if (nextContextActions.size) {
// at next tick, re-populate the context appbar
setTimeout(function(){
// fire a MozContextActionsChange event to update the context appbar
let event = document.createEvent("Events");
event.actions = [...nextContextActions];
- event.noun = tileGroup.contextNoun;
- event.qty = selectedTiles.length;
event.initEvent("MozContextActionsChange", true, false);
tileGroup.dispatchEvent(event);
},0);
}
},
handleEvent: function(aEvent) {
switch (aEvent.type){
--- a/browser/metro/base/content/appbar.js
+++ b/browser/metro/base/content/appbar.js
@@ -40,20 +40,19 @@ var Appbar = {
this.activeTileset.clearSelection();
}
this.clearContextualActions();
this.activeTileset = null;
break;
case 'MozContextActionsChange':
let actions = aEvent.actions;
- let noun = aEvent.noun;
- let qty = aEvent.qty;
+ let setName = aEvent.target.contextSetName;
// could transition in old, new buttons?
- this.showContextualActions(actions, noun, qty);
+ this.showContextualActions(actions, setName);
break;
case "selectionchange":
let nodeName = aEvent.target.nodeName;
if ('richgrid' === nodeName) {
this._onTileSelectionChanged(aEvent);
}
break;
@@ -156,24 +155,25 @@ var Appbar = {
activeTileset.dispatchEvent(event);
if (!event.defaultPrevented) {
activeTileset.clearSelection();
Elements.contextappbar.dismiss();
}
}
},
- showContextualActions: function(aVerbs, aNoun, aQty) {
+ showContextualActions: function(aVerbs, aSetName) {
// When the appbar is not visible, we want the icons to refresh right away
let immediate = !Elements.contextappbar.isShowing;
- if (aVerbs.length)
+ if (aVerbs.length) {
Elements.contextappbar.show();
- else
+ } else {
Elements.contextappbar.hide();
+ }
// Look up all of the buttons for the verbs that should be visible.
let idsToVisibleVerbs = new Map();
for (let verb of aVerbs) {
let id = verb + "-selected-button";
if (!document.getElementById(id)) {
throw new Error("Appbar.showContextualActions: no button for " + verb);
}
@@ -182,17 +182,17 @@ var Appbar = {
// Sort buttons into 2 buckets - needing showing and needing hiding.
let toHide = [], toShow = [];
let buttons = Elements.contextappbar.getElementsByTagName("toolbarbutton");
for (let button of buttons) {
let verb = idsToVisibleVerbs.get(button.id);
if (verb != undefined) {
// Button should be visible, and may or may not be showing.
- this._updateContextualActionLabel(button, verb, aNoun, aQty);
+ this._updateContextualActionLabel(button, verb, aSetName);
if (button.hidden) {
toShow.push(button);
}
} else if (!button.hidden) {
// Button is visible, but shouldn't be.
toHide.push(button);
}
}
@@ -218,28 +218,22 @@ var Appbar = {
}
});
},
clearContextualActions: function() {
this.showContextualActions([]);
},
- _updateContextualActionLabel: function(aBtnNode, aVerb, aNoun, aQty) {
- // True if action modifies the noun for the grid (bookmark, top site, etc.),
- // causing the label to be pluralized by the number of selected items.
- let modifiesNoun = aBtnNode.getAttribute("modifies-noun") == "true";
- if (modifiesNoun && (!aNoun || isNaN(aQty))) {
- throw new Error("Appbar._updateContextualActionLabel: " +
- "missing noun/quantity for " + aVerb);
- }
-
- let labelName = "contextAppbar." + aVerb + (modifiesNoun ? "." + aNoun : "");
- let label = Strings.browser.GetStringFromName(labelName);
- aBtnNode.label = modifiesNoun ? PluralForm.get(aQty, label) : label;
+ _updateContextualActionLabel: function(aButton, aVerb, aSetName) {
+ // True if the action's label string contains the set name and
+ // thus has to be selected based on the list passed in.
+ let usesSetName = aButton.hasAttribute("label-uses-set-name");
+ let name = "contextAppbar2." + aVerb + (usesSetName ? "." + aSetName : "");
+ aButton.label = Strings.browser.GetStringFromName(name);
},
_onTileSelectionChanged: function _onTileSelectionChanged(aEvent){
let activeTileset = aEvent.target;
// deselect tiles in other tile groups
if (this.activeTileset && this.activeTileset !== activeTileset) {
this.activeTileset.clearSelection();
@@ -250,20 +244,18 @@ var Appbar = {
// ask the view for the list verbs/action-names it thinks are
// appropriate for the tiles selected
let contextActions = activeTileset.contextActions;
let verbs = [v for (v of contextActions)];
// fire event with these verbs as payload
let event = document.createEvent("Events");
event.actions = verbs;
- event.noun = activeTileset.contextNoun;
- event.qty = activeTileset.selectedItems.length;
event.initEvent("MozContextActionsChange", true, false);
- Elements.contextappbar.dispatchEvent(event);
+ activeTileset.dispatchEvent(event);
if (verbs.length) {
Elements.contextappbar.show(); // should be no-op if we're already showing
} else {
Elements.contextappbar.dismiss();
}
},
--- a/browser/metro/base/content/bindings/grid.xml
+++ b/browser/metro/base/content/bindings/grid.xml
@@ -116,18 +116,18 @@
return;
// we'll republish this as a selectionchange event on the grid
aEvent.stopPropagation();
this.toggleItemSelection(aItem);
]]>
</body>
</method>
- <property name="contextNoun" readonly="true"
- onget="return this.getAttribute('noun');"/>
+ <property name="contextSetName" readonly="true"
+ onget="return this.getAttribute('set-name');"/>
<property name="contextActions">
<getter>
<![CDATA[
// return the subset of verbs that apply to all selected tiles
let tileNodes = this.selectedItems;
if (!tileNodes.length) {
return new Set();
--- a/browser/metro/base/content/bookmarks.js
+++ b/browser/metro/base/content/bookmarks.js
@@ -289,18 +289,16 @@ BookmarksView.prototype = Util.extend(Ob
aEvent.preventDefault();
// at next tick, re-populate the context appbar.
setTimeout(function(){
// fire a MozContextActionsChange event to update the context appbar
let event = document.createEvent("Events");
// we need the restore button to show (the tile node will go away though)
event.actions = ["restore"];
- event.noun = tileGroup.contextNoun;
- event.qty = selectedTiles.length;
event.initEvent("MozContextActionsChange", true, false);
tileGroup.dispatchEvent(event);
}, 0);
break;
case "restore":
// clear toRemove and let _sendNeedsRefresh update the items.
this._toRemove = null;
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -191,41 +191,41 @@
</hbox>
<!-- Start UI -->
<hbox id="start-container" flex="1" observes="bcast_windowState" class="meta content-height content-width">
<!-- portrait/landscape/filled view -->
<scrollbox id="start-scrollbox" observes="bcast_preciseInput" flex="1">
<vbox id="start-topsites" class="meta-section">
- <label class="meta-section-title wide-title" value="&startTopSitesHeader.label;"/>
+ <label class="meta-section-title wide-title" value="&topSitesHeader.label;"/>
<label class="meta-section-title narrow-title" value="&snappedTopSitesHeader.label;"
onclick="StartUI.onNarrowTitleClick('start-topsites-grid')"/>
- <richgrid id="start-topsites-grid" noun="topsite" rows="3" columns="3" tiletype="thumbnail" seltype="multiple" flex="1" expanded="true"/>
+ <richgrid id="start-topsites-grid" set-name="topSites" rows="3" columns="3" tiletype="thumbnail" seltype="multiple" flex="1" expanded="true"/>
</vbox>
<vbox id="start-bookmarks" class="meta-section">
- <label class="meta-section-title wide-title" value="&startBookmarksHeader.label;"/>
+ <label class="meta-section-title wide-title" value="&bookmarksHeader.label;"/>
<label class="meta-section-title narrow-title" value="&snappedBookmarksHeader.label;"
onclick="StartUI.onNarrowTitleClick('start-bookmarks-grid')"/>
- <richgrid id="start-bookmarks-grid" noun="bookmark" seltype="multiple" flex="1"/>
+ <richgrid id="start-bookmarks-grid" set-name="bookmarks" seltype="multiple" flex="1"/>
</vbox>
<vbox id="start-history" class="meta-section">
- <label class="meta-section-title wide-title" value="&startHistoryHeader.label;"/>
- <label class="meta-section-title narrow-title" value="&snappedHistoryHeader.label;"
+ <label class="meta-section-title wide-title" value="&recentHistoryHeader.label;"/>
+ <label class="meta-section-title narrow-title" value="&snappedRecentHistoryHeader.label;"
onclick="StartUI.onNarrowTitleClick('start-history-grid')"/>
- <richgrid id="start-history-grid" noun="history" seltype="multiple" flex="1"/>
+ <richgrid id="start-history-grid" set-name="recentHistory" seltype="multiple" flex="1"/>
</vbox>
<vbox id="start-remotetabs" class="meta-section">
- <label class="meta-section-title wide-title" value="&startRemoteTabsHeader.label;"/>
+ <label class="meta-section-title wide-title" value="&remoteTabsHeader.label;"/>
<label id="snappedRemoteTabsLabel" class="meta-section-title narrow-title" value="&snappedRemoteTabsHeader.label;"
onclick="StartUI.onNarrowTitleClick('start-remotetabs-grid')"/>
- <richgrid id="start-remotetabs-grid" noun="tab" seltype="multiple" flex="1"/>
+ <richgrid id="start-remotetabs-grid" set-name="remoteTabs" seltype="multiple" flex="1"/>
</vbox>
<!-- Spacer to take extra space in snapped mode. -->
<spacer flex="999"/>
</scrollbox>
</hbox>
</vbox> <!-- end tray -->
@@ -306,26 +306,26 @@
hidden="true" observes="bcast_windowState">
<hbox id="panel-header">
<toolbarbutton id="panel-close-button" class="appbar-primary"
command="cmd_panel"/>
</hbox>
<deck id="panel-items" selectedIndex="0" flex="1" >
<scrollbox id="bookmarks-container" flex="1">
- <richgrid id="bookmarks-list" noun="bookmark" class="canSnapTiles"
- seltype="multiple" flex="1"/>
+ <richgrid id="bookmarks-list" class="canSnapTiles"
+ set-name="bookmarks" seltype="multiple" flex="1"/>
</scrollbox>
<scrollbox id="history-container" flex="1">
- <richgrid id="history-list" noun="history" class="canSnapTiles"
- seltype="multiple" flex="1"/>
+ <richgrid id="history-list" class="canSnapTiles"
+ set-name="recentHistory" seltype="multiple" flex="1"/>
</scrollbox>
<scrollbox id="remotetabs-container" flex="1">
- <richgrid id="remotetabs-list" noun="tab" class="canSnapTiles"
- seltype="single" flex="1"/>
+ <richgrid id="remotetabs-list" class="canSnapTiles"
+ set-name="remoteTabs" seltype="single" flex="1"/>
</scrollbox>
<vbox id="console-container" flex="1">
<vbox id="console-header" class="panel-list">
<label class="panel-header" value="&consoleHeader.label;"/>
<hbox align="center">
<label value="&consoleCodeEval.label;"
control="console-eval-textbox"/>
<textbox id="console-eval-textbox" class="toolbar search-bar"
@@ -369,28 +369,28 @@
<button class="next-button" command="cmd_findNext"/>
<spacer flex="1"/>
<button id="findbar-close" class="close-button" command="cmd_findClose"/>
</appbar>
<!-- Context button bar -->
<appbar id="contextappbar">
<toolbar id="contextualactions-tray" labelled="true" flex="1">
+ <toolbarbutton id="pin-selected-button" class="appbar-secondary"
+ label-uses-set-name="true" hidden="true" fade="true"
+ oncommand="Appbar.dispatchContextualAction('pin')"/>
+ <toolbarbutton id="unpin-selected-button" class="appbar-secondary"
+ label-uses-set-name="true" hidden="true" fade="true"
+ oncommand="Appbar.dispatchContextualAction('unpin')"/>
<toolbarbutton id="delete-selected-button" class="appbar-secondary"
- modifies-noun="true" hidden="true" fade="true"
+ hidden="true" fade="true"
oncommand="Appbar.dispatchContextualAction('delete')"/>
<toolbarbutton id="restore-selected-button" class="appbar-secondary"
- modifies-noun="true" hidden="true" fade="true"
+ hidden="true" fade="true"
oncommand="Appbar.dispatchContextualAction('restore')"/>
- <toolbarbutton id="pin-selected-button" class="appbar-secondary"
- modifies-noun="true" hidden="true" fade="true"
- oncommand="Appbar.dispatchContextualAction('pin')"/>
- <toolbarbutton id="unpin-selected-button" class="appbar-secondary"
- modifies-noun="true" hidden="true" fade="true"
- oncommand="Appbar.dispatchContextualAction('unpin')"/>
<toolbarbutton id="clear-selected-button" class="appbar-secondary"
hidden="true" fade="true"
oncommand="Appbar.dispatchContextualAction('clear')"/>
</toolbar>
</appbar>
<autoscroller class="autoscroller" id="autoscrollerid"/>
--- a/browser/metro/base/content/history.js
+++ b/browser/metro/base/content/history.js
@@ -143,18 +143,16 @@ HistoryView.prototype = Util.extend(Obje
aEvent.preventDefault();
// at next tick, re-populate the context appbar.
setTimeout(function(){
// fire a MozContextActionsChange event to update the context appbar
let event = document.createEvent("Events");
// we need the restore button to show (the tile node will go away though)
event.actions = ["restore"];
- event.noun = tileGroup.contextNoun;
- event.qty = selectedTiles.length;
event.initEvent("MozContextActionsChange", true, false);
tileGroup.dispatchEvent(event);
}, 0);
break;
case "restore":
// clear toRemove and let _sendNeedsRefresh update the items.
this._toRemove = null;
--- a/browser/metro/locales/en-US/chrome/browser.dtd
+++ b/browser/metro/locales/en-US/chrome/browser.dtd
@@ -1,58 +1,59 @@
<!-- 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/. -->
+<!-- NAVBAR AND AUTOCOMPLETE -->
+
<!ENTITY urlbar.emptytext "Enter Search or Address">
<!ENTITY urlbar.accesskey "d">
<!ENTITY back.label "Back">
<!ENTITY forward.label "Forward">
<!ENTITY newtab.label "New Tab">
<!ENTITY closetab.label "Close Tab">
+<!ENTITY autocompleteResultsHeader.label "Your Results">
+<!ENTITY autocompleteSearchesHeader.label "Internet Searches">
+
<!ENTITY appbarErrorConsole.label "Open error console">
<!ENTITY appbarJSShell.label "Open JavaScript shell">
<!ENTITY appbarFindInPage2.label "Find in page">
<!ENTITY appbarViewOnDesktop2.label "View on desktop">
-<!ENTITY startTopSitesHeader.label "Top Sites">
-<!ENTITY startBookmarksHeader.label "Bookmarks">
-<!ENTITY startHistoryHeader.label "Recent History">
-<!ENTITY startRemoteTabsHeader.label "Tabs from Other Devices">
+<!ENTITY topSitesHeader.label "Top Sites">
+<!ENTITY bookmarksHeader.label "Bookmarks">
+<!ENTITY recentHistoryHeader.label "Recent History">
+<!ENTITY remoteTabsHeader.label "Tabs from Other Devices">
<!-- LOCALIZATION NOTE (snappedRemoteTabsHeader.label): shortened version of startRemoteTabsHeader.label.
Needs to be two words or shorter to fit in narrow vertical space.-->
<!-- LOCALIZATION NOTE (snappedRemoteTabsHeader.label,
snappedBookmarksHeader.label,
snappedHistoryHeader.label,
snappedTopSitesHeader.label )
The '>' character is not part of the name, but is an indicator of more content. Please do not localize the '>' -->
<!ENTITY snappedRemoteTabsHeader.label "Remote Tabs >">
<!ENTITY snappedBookmarksHeader.label "Bookmarks >">
-<!ENTITY snappedHistoryHeader.label "Recent History >">
+<!ENTITY snappedRecentHistoryHeader.label "Recent History >">
<!ENTITY snappedTopSitesHeader.label "Top Sites >">
-<!ENTITY autocompleteResultsHeader.label "Your Results">
-<!ENTITY autocompleteSearchesHeader.label "Internet Searches">
-
<!ENTITY downloadsHeader.label "Downloads">
<!ENTITY downloadShowPage.label "Go to Page">
<!ENTITY downloadShow2.label "Find">
<!ENTITY downloadOpen2.label "Open">
<!ENTITY downloadCancel.label "Cancel">
<!ENTITY downloadPause.label "Pause">
<!ENTITY downloadResume.label "Resume">
<!ENTITY downloadRetry.label "Retry">
<!ENTITY downloadRemove.label "Remove">
<!ENTITY downloadDelete.label "Delete">
<!ENTITY downloadFailed.label "Failed">
-<!ENTITY bookmarksHeader.label "Bookmarks">
<!ENTITY allBookmarks.label "See all bookmarks">
<!ENTITY consoleHeader.label "Error Console">
<!ENTITY consoleAll.label "All">
<!ENTITY consoleErrors.label "Errors">
<!ENTITY consoleWarnings.label "Warnings">
<!ENTITY consoleMessages.label "Messages">
<!ENTITY consoleCodeEval.label "Code:">
--- a/browser/metro/locales/en-US/chrome/browser.properties
+++ b/browser/metro/locales/en-US/chrome/browser.properties
@@ -1,50 +1,52 @@
# 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/.
+# LOCALIZATION NOTE : FILE Capitalized phrases like "Top Sites", "Bookmarks",
+# and "Recent History" are typically used as proper noun phrases to refer to
+# the specific visual set (usually displayed as a grid) of top sites,
+# bookmarks, etc. displayed on screen, rather than those concepts in general.
+# Buttons (like with contextAppbar2.pin.topSites) refer to actions against
+# the specific on-screen sets with similarly-named headings.
+
# Default search engine
browser.search.defaultenginename=Bing
# Search engine order (order displayed in the search bar dropdown)s
browser.search.order.1=Bing
browser.search.order.2=Google
browser.search.order.3=Yahoo
# LOCALIZATION NOTE (browser.search.contextTextSearchLabel2): search context
# menu item text will be: |Search (browser.search.defaultenginename) for "string"|
browser.search.contextTextSearchLabel2=Search %S for "%S"
-# Contextual Appbar - button labels
-# LOCALIZATION NOTE: All of the following represent actions that can be done
-# to items (top sites, bookmarks, history items) that are selected by the user
-# on the start screen. Each string is a semicolon list of plural forms.
-contextAppbar.delete.topsite=Delete top site;Delete top sites
-contextAppbar.restore.topsite=Restore top site;Restore top sites
-contextAppbar.pin.topsite=Pin top site;Pin top sites
-contextAppbar.unpin.topsite=Unpin top site;Unpin top sites
-contextAppbar.delete.bookmark=Delete bookmark;Delete bookmarks
-contextAppbar.restore.bookmark=Restore bookmark;Restore bookmarks
-contextAppbar.pin.bookmark=Pin bookmark;Pin bookmarks
-contextAppbar.unpin.bookmark=Unpin bookmark;Unpin bookmarks
-contextAppbar.delete.history=Delete page;Delete pages
-contextAppbar.restore.history=Restore page;Restore pages
-contextAppbar.pin.history=Pin page;Pin pages
-contextAppbar.unpin.history=Unpin page;Unpin pages
-contextAppbar.delete.tab=Delete tab;Delete tabs
-contextAppbar.restore.tab=Restore tab;Restore tabs
-contextAppbar.pin.tab=Pin tab;Pin tabs
-contextAppbar.unpin.tab=Unpin page;Unpin tabs
-contextAppbar.delete.download=Delete download;Delete downloads
-contextAppbar.restore.download=Restore download;Restore downloads
-contextAppbar.pin.download=Pin download;Pin downloads
-contextAppbar.unpin.download=Unpin page;Unpin downloads
-# LOCALIZATION NOTE (contextAppbar.clear): Unselects items without modification.
-contextAppbar.clear=Clear selection
+# Contextual Appbar - Button Labels
+
+contextAppbar2.pin.topSites=Pin to Top Sites
+contextAppbar2.pin.bookmarks=Pin to Bookmarks
+contextAppbar2.pin.recentHistory=Pin to Recent History
+contextAppbar2.pin.downloads=Pin to Downloads
+
+contextAppbar2.unpin.topSites=Unpin from Top Sites
+contextAppbar2.unpin.bookmarks=Unpin from Bookmarks
+contextAppbar2.unpin.recentHistory=Unpin from Recent History
+contextAppbar2.unpin.downloads=Unpin from Downloads
+
+# LOCALIZATION NOTE (contextAppbar2.delete): Deletes selected pages.
+contextAppbar2.delete=Delete
+
+# LOCALIZATION NOTE (contextAppbar2.restore): Undoes a previous deletion.
+# Button with this label only appears immediately after a deletion.
+contextAppbar2.restore=Undo delete
+
+# LOCALIZATION NOTE (contextAppbar2.clear): Unselects pages without modification.
+contextAppbar2.clear=Clear selection
# Settings Charms
aboutCharm1=About
optionsCharm=Options
syncCharm=Sync
helpOnlineCharm=Help (online)
# General
--- a/configure.in
+++ b/configure.in
@@ -8145,17 +8145,21 @@ dnl ====================================
if test "${OS_TARGET}" = "WINNT"; then
if $PERL -e "exit($MOZ_WINSDK_MAXVER < 0x06020000)"; then
MOZ_ENABLE_DIRECT2D1_1=1
AC_SUBST(MOZ_ENABLE_DIRECT2D1_1)
fi
fi
-if test "${OS_TARGET}" = "WINNT" -o "${OS_ARCH}" = "Darwin" -o "${MOZ_WIDGET_TOOLKIT}" = "android" -o "${MOZ_WIDGET_TOOLKIT}" = "gtk2"; then
+if test "${OS_TARGET}" = "WINNT" -o \
+ "${OS_ARCH}" = "Darwin" -o \
+ "${MOZ_WIDGET_TOOLKIT}" = "android" -o \
+ "${MOZ_WIDGET_TOOLKIT}" = "gonk" -o \
+ "${MOZ_WIDGET_TOOLKIT}" = "gtk2"; then
case "${target_cpu}" in
i*86*|x86_64|arm)
MOZ_ENABLE_SKIA=1
;;
*)
MOZ_ENABLE_SKIA=
;;
esac
--- a/content/events/test/test_dom_keyboard_event.html
+++ b/content/events/test/test_dom_keyboard_event.html
@@ -268,17 +268,20 @@ function testSynthesizedKeyLocation()
var currentTest, description;
var events = { keydown: false, keypress: false, keyup: false };
function handler(aEvent)
{
is(aEvent.location, currentTest.event.location,
description + "location of " + aEvent.type + " was invalid");
events[aEvent.type] = true;
- aEvent.preventDefault();
+ if (aEvent.type != "keydown" ||
+ (currentTest.event.isModifier && aEvent.type == "keydown")) {
+ aEvent.preventDefault();
+ }
}
window.addEventListener("keydown", handler, true);
window.addEventListener("keypress", handler, true);
window.addEventListener("keyup", handler, true);
for (var i = 0; i < kTests.length; i++) {
currentTest = kTests[i];
--- a/content/media/MediaDecoderReader.cpp
+++ b/content/media/MediaDecoderReader.cpp
@@ -1,15 +1,15 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "GonkIOSurfaceImage.h"
+#include "GrallocImages.h"
#include "MediaDecoderReader.h"
#include "AbstractMediaDecoder.h"
#include "MediaDecoderStateMachine.h"
#include "VideoUtils.h"
#include "ImageContainer.h"
#include "mozilla/mozalloc.h"
#include "mozilla/StandardInteger.h"
@@ -343,26 +343,26 @@ VideoData* VideoData::Create(VideoInfo&
nsAutoPtr<VideoData> v(new VideoData(aOffset,
aTime,
aEndTime,
aKeyframe,
aTimecode,
aInfo.mDisplay));
- ImageFormat format = GONK_IO_SURFACE;
+ ImageFormat format = GRALLOC_PLANAR_YCBCR;
v->mImage = aContainer->CreateImage(&format, 1);
if (!v->mImage) {
return nullptr;
}
- NS_ASSERTION(v->mImage->GetFormat() == GONK_IO_SURFACE,
+ NS_ASSERTION(v->mImage->GetFormat() == GRALLOC_PLANAR_YCBCR,
"Wrong format?");
- typedef mozilla::layers::GonkIOSurfaceImage GonkIOSurfaceImage;
- GonkIOSurfaceImage* videoImage = static_cast<GonkIOSurfaceImage*>(v->mImage.get());
- GonkIOSurfaceImage::Data data;
+ typedef mozilla::layers::GrallocImage GrallocImage;
+ GrallocImage* videoImage = static_cast<GrallocImage*>(v->mImage.get());
+ GrallocImage::GrallocData data;
data.mPicSize = gfxIntSize(aPicture.width, aPicture.height);
data.mGraphicBuffer = aBuffer;
videoImage->SetData(data);
return v.forget();
}
--- a/content/media/omx/MPAPI.h
+++ b/content/media/omx/MPAPI.h
@@ -2,17 +2,17 @@
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#if !defined(MPAPI_h_)
#define MPAPI_h_
#include <stdint.h>
-#include "GonkIOSurfaceImage.h"
+#include "GrallocImages.h"
namespace MPAPI {
struct VideoPlane {
VideoPlane() :
mData(nullptr),
mStride(0),
mWidth(0),
--- a/content/media/omx/OmxDecoder.h
+++ b/content/media/omx/OmxDecoder.h
@@ -3,17 +3,17 @@
#include <stagefright/foundation/ALooper.h>
#include <stagefright/MediaSource.h>
#include <stagefright/DataSource.h>
#include <stagefright/MediaSource.h>
#include <utils/RefBase.h>
#include "GonkNativeWindow.h"
#include "GonkNativeWindowClient.h"
-#include "GonkIOSurfaceImage.h"
+#include "GrallocImages.h"
#include "MPAPI.h"
#include "MediaResource.h"
#include "AbstractMediaDecoder.h"
#include "OMXCodecProxy.h"
namespace android {
class OmxDecoder;
};
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -277,32 +277,38 @@ nsPluginArray::EnsurePlugins()
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginElement)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginElement)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginElement)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsPluginElement,
- mMimeTypes)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsPluginElement)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+ // Invalidate before we unlink mMimeTypes
+ tmp->Invalidate();
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mMimeTypes)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsPluginElement)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsPluginElement)
nsPluginElement::nsPluginElement(nsWeakPtr aWindow,
nsPluginTag* aPluginTag)
: mWindow(aWindow),
mPluginTag(aPluginTag)
{
SetIsDOMBinding();
}
nsPluginElement::~nsPluginElement()
{
- for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) {
- mMimeTypes[i]->Invalidate();
- }
+ Invalidate();
}
nsPIDOMWindow*
nsPluginElement::GetParentObject() const
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
MOZ_ASSERT(win);
return win;
@@ -414,8 +420,16 @@ nsPluginElement::EnsureMimeTypes()
return;
}
for (uint32_t i = 0; i < mPluginTag->mMimeTypes.Length(); ++i) {
NS_ConvertUTF8toUTF16 type(mPluginTag->mMimeTypes[i]);
mMimeTypes.AppendElement(new nsMimeType(mWindow, this, i, type));
}
}
+
+void
+nsPluginElement::Invalidate()
+{
+ for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) {
+ mMimeTypes[i]->Invalidate();
+ }
+}
--- a/dom/base/nsPluginArray.h
+++ b/dom/base/nsPluginArray.h
@@ -97,15 +97,16 @@ public:
nsMimeType* NamedGetter(const nsAString& name, bool &found);
uint32_t Length();
void GetSupportedNames(nsTArray< nsString >& retval);
nsTArray<nsRefPtr<nsMimeType> >& MimeTypes();
protected:
void EnsureMimeTypes();
+ void Invalidate();
nsWeakPtr mWindow;
nsRefPtr<nsPluginTag> mPluginTag;
nsTArray<nsRefPtr<nsMimeType> > mMimeTypes;
};
#endif /* nsPluginArray_h___ */
--- a/dom/browser-element/BrowserElementPanning.js
+++ b/dom/browser-element/BrowserElementPanning.js
@@ -211,16 +211,19 @@ const ContentPanning = {
if (this.target && click && (this.panning || this.preventNextClick)) {
let target = this.target;
let view = target.ownerDocument ? target.ownerDocument.defaultView
: target;
view.addEventListener('click', this, true, true);
}
this._finishPanning();
+
+ // Now that we're done, avoid entraining the thing we just panned.
+ this.pointerDownTarget = null;
},
// True when there's an async pan-zoom controll watching the
// outermost scrollable frame, and we're waiting to see whether
// we're going to take over from it and synchronously scroll an
// inner scrollable frame.
detectingScrolling: false,
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -1481,27 +1481,27 @@ AutoFocusComplete(nsGonkCameraControl* g
static void
GonkFrameBuilder(Image* aImage, void* aBuffer, uint32_t aWidth, uint32_t aHeight)
{
/**
* Cast the generic Image back to our platform-specific type and
* populate it.
*/
- GonkIOSurfaceImage* videoImage = static_cast<GonkIOSurfaceImage*>(aImage);
- GonkIOSurfaceImage::Data data;
+ GrallocImage* videoImage = static_cast<GrallocImage*>(aImage);
+ GrallocImage::GrallocData data;
data.mGraphicBuffer = static_cast<layers::GraphicBufferLocked*>(aBuffer);
data.mPicSize = gfxIntSize(aWidth, aHeight);
videoImage->SetData(data);
}
void
ReceiveFrame(nsGonkCameraControl* gc, layers::GraphicBufferLocked* aBuffer)
{
- if (!gc->ReceiveFrame(aBuffer, ImageFormat::GONK_IO_SURFACE, GonkFrameBuilder)) {
+ if (!gc->ReceiveFrame(aBuffer, ImageFormat::GRALLOC_PLANAR_YCBCR, GonkFrameBuilder)) {
aBuffer->Unlock();
}
}
void
OnShutter(nsGonkCameraControl* gc)
{
gc->OnShutter();
--- a/dom/camera/GonkNativeWindow.h
+++ b/dom/camera/GonkNativeWindow.h
@@ -27,17 +27,17 @@
#include <ui/Rect.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/threads.h>
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/ImageBridgeChild.h"
-#include "GonkIOSurfaceImage.h"
+#include "GrallocImages.h"
#include "CameraCommon.h"
namespace android {
// The user of GonkNativeWindow who wants to receive notification of
// new frames should implement this interface.
class GonkNativeWindowNewFrameCallback {
public:
--- a/dom/network/interfaces/nsIDOMMobileConnection.idl
+++ b/dom/network/interfaces/nsIDOMMobileConnection.idl
@@ -376,28 +376,78 @@ interface nsIDOMMozMobileNetworkInfo: ns
/**
* State of this network operator.
*
* Possible values: 'available', 'connected', 'forbidden', or null (unknown)
*/
readonly attribute DOMString state;
};
-[scriptable, uuid(aa546788-4f34-488b-8c3e-2786e02ab992)]
+[scriptable, uuid(9750b3a7-d913-436e-95d4-7ef2973ec6a1)]
interface nsIDOMMozMobileCellInfo: nsISupports
{
/**
* Mobile Location Area Code (LAC) for GSM/WCDMA networks.
+ *
+ * Possible ranges from 0x0000 to 0xffff.
+ * -1 if the LAC is unknown.
*/
- readonly attribute unsigned short gsmLocationAreaCode;
+ readonly attribute long gsmLocationAreaCode;
/**
* Mobile Cell ID for GSM/WCDMA networks.
+ *
+ * Possible ranges from 0x00000000 to 0xffffffff.
+ * -1 if the cell id is unknown.
*/
- readonly attribute unsigned long gsmCellId;
+ readonly attribute long long gsmCellId;
+
+ /**
+ * Base Station ID for CDMA networks.
+ *
+ * Possible ranges from 0 to 65535
+ * -1 if the base station id is unknown.
+ */
+ readonly attribute long cdmaBaseStationId;
+
+ /**
+ * Base Station Latitude for CDMA networks.
+ *
+ * Possible ranges from -1296000 to 1296000.
+ * -2147483648 if the latitude is unknown.
+ *
+ * @see 3GPP2 C.S0005-A v6.0.
+ */
+ readonly attribute long cdmaBaseStationLatitude;
+
+ /**
+ * Base Station Longitude for CDMA networks.
+ *
+ * Possible ranges from -2592000 to 2592000.
+ * -2147483648 if the longitude is unknown.
+ *
+ * @see 3GPP2 C.S0005-A v6.0.
+ */
+ readonly attribute long cdmaBaseStationLongitude;
+
+ /**
+ * System ID for CDMA networks.
+ *
+ * Possible ranges from 0 to 32767.
+ * -1 if the system id is unknown.
+ */
+ readonly attribute long cdmaSystemId;
+
+ /**
+ * Network ID for CDMA networks.
+ *
+ * Possible ranges from 0 to 65535.
+ * -1 if the network id is unknown.
+ */
+ readonly attribute long cdmaNetworkId;
};
[scriptable, uuid(d1b35ad8-99aa-47cc-ab49-2e72b00e39df)]
interface nsIDOMMozMobileCFInfo : nsISupports
{
/**
* Call forwarding rule status.
*
--- a/dom/network/tests/marionette/test_mobile_voice_state.js
+++ b/dom/network/tests/marionette/test_mobile_voice_state.js
@@ -40,32 +40,42 @@ function testConnectionInfo() {
is(voice.state, "registered");
is(voice.emergencyCallsOnly, false);
is(voice.roaming, false);
testCellLocation();
}
function testCellLocation() {
- let voice = connection.voice;
+ let cell = connection.voice.cell;
// Emulator always reports valid lac/cid value because its AT command parser
// insists valid value for every complete response. See source file
// hardare/ril/reference-ril/at_tok.c, function at_tok_nexthexint().
- ok(voice.cell, "location available");
+ ok(cell, "location available");
- // Initial LAC/CID. Android emulator initializes both value to -1.
- is(voice.cell.gsmLocationAreaCode, 65535);
- is(voice.cell.gsmCellId, 268435455);
+ // Initial LAC/CID. Android emulator initializes both value to 0xffff/0xffffffff.
+ is(cell.gsmLocationAreaCode, 65535);
+ is(cell.gsmCellId, 268435455);
+ is(cell.cdmaBaseStationId, -1);
+ is(cell.cdmaBaseStationLatitude, -2147483648);
+ is(cell.cdmaBaseStationLongitude, -2147483648);
+ is(cell.cdmaSystemId, -1);
+ is(cell.cdmaNetworkId, -1);
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
- is(voice.cell.gsmLocationAreaCode, 100);
- is(voice.cell.gsmCellId, 100);
+ is(cell.gsmLocationAreaCode, 100);
+ is(cell.gsmCellId, 100);
+ is(cell.cdmaBaseStationId, -1);
+ is(cell.cdmaBaseStationLatitude, -2147483648);
+ is(cell.cdmaBaseStationLongitude, -2147483648);
+ is(cell.cdmaSystemId, -1);
+ is(cell.cdmaNetworkId, -1);
testUnregistered();
});
setEmulatorGsmLocation(100, 100);
}
function testUnregistered() {
@@ -73,46 +83,49 @@ function testUnregistered() {
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, false);
is(connection.voice.state, "notSearching");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, false);
+ is(connection.voice.cell, null);
testSearching();
});
}
function testSearching() {
setEmulatorVoiceState("searching");
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, false);
is(connection.voice.state, "searching");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, false);
+ is(connection.voice.cell, null);
testDenied();
});
}
function testDenied() {
setEmulatorVoiceState("denied");
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, false);
is(connection.voice.state, "denied");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, false);
+ is(connection.voice.cell, null);
testRoaming();
});
}
function testRoaming() {
setEmulatorVoiceState("roaming");
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -476,18 +476,32 @@ GonkGPSGeolocationProvider::SetReference
}
}
nsCOMPtr<nsIDOMMozMobileConnectionInfo> voice;
rilCtx->GetVoice(getter_AddRefs(voice));
if (voice) {
nsCOMPtr<nsIDOMMozMobileCellInfo> cell;
voice->GetCell(getter_AddRefs(cell));
if (cell) {
- cell->GetGsmLocationAreaCode(&location.u.cellID.lac);
- cell->GetGsmCellId(&location.u.cellID.cid);
+ int32_t lac;
+ int64_t cid;
+
+ cell->GetGsmLocationAreaCode(&lac);
+ // The valid range of LAC is 0x0 to 0xffff which is defined in
+ // hardware/ril/include/telephony/ril.h
+ if (lac >= 0x0 && lac <= 0xffff) {
+ location.u.cellID.lac = lac;
+ }
+
+ cell->GetGsmCellId(&cid);
+ // The valid range of cell id is 0x0 to 0xffffffff which is defined in
+ // hardware/ril/include/telephony/ril.h
+ if (cid >= 0x0 && cid <= 0xffffffff) {
+ location.u.cellID.cid = cid;
+ }
}
}
if (mAGpsRilInterface) {
mAGpsRilInterface->set_ref_location(&location, sizeof(location));
}
}
}
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -47,17 +47,17 @@ const RILCONTENTHELPER_CID =
Components.ID("{472816e1-1fd6-4405-996c-806f9ea68174}");
const ICCINFO_CID =
Components.ID("{fab2c0f0-d73a-11e2-8b8b-0800200c9a66}");
const MOBILECONNECTIONINFO_CID =
Components.ID("{a35cfd39-2d93-4489-ac7d-396475dacb27}");
const MOBILENETWORKINFO_CID =
Components.ID("{a6c8416c-09b4-46d1-bf29-6520d677d085}");
const MOBILECELLINFO_CID =
- Components.ID("{5e809018-68c0-4c54-af0b-2a9b8f748c45}");
+ Components.ID("{ae724dd4-ccaf-4006-98f1-6ce66a092464}");
const VOICEMAILSTATUS_CID=
Components.ID("{5467f2eb-e214-43ea-9b89-67711241ec8e}");
const MOBILECFINFO_CID=
Components.ID("{a4756f16-e728-4d9f-8baa-8464f894888a}");
const CELLBROADCASTMESSAGE_CID =
Components.ID("{29474c96-3099-486f-bb4a-3c9a1da834e4}");
const CELLBROADCASTETWSINFO_CID =
Components.ID("{59f176ee-9dcd-4005-9d47-f6be0cd08e17}");
@@ -221,18 +221,23 @@ MobileCellInfo.prototype = {
classID: MOBILECELLINFO_CID,
classDescription: "MobileCellInfo",
flags: Ci.nsIClassInfo.DOM_OBJECT,
interfaces: [Ci.nsIDOMMozMobileCellInfo]
}),
// nsIDOMMozMobileCellInfo
- gsmLocationAreaCode: null,
- gsmCellId: null
+ gsmLocationAreaCode: -1,
+ gsmCellId: -1,
+ cdmaBaseStationId: -1,
+ cdmaBaseStationLatitude: -2147483648,
+ cdmaBaseStationLongitude: -2147483648,
+ cdmaSystemId: -1,
+ cdmaNetworkId: -1
};
function VoicemailStatus() {}
VoicemailStatus.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozVoicemailStatus]),
classID: VOICEMAILSTATUS_CID,
classInfo: XPCOMUtils.generateCI({
classID: VOICEMAILSTATUS_CID,
@@ -438,18 +443,17 @@ RILContentHelper.prototype = {
if (!srcCell) {
destInfo.cell = null;
} else {
let cell = destInfo.cell;
if (!cell) {
cell = destInfo.cell = new MobileCellInfo();
}
- cell.gsmLocationAreaCode = srcCell.gsmLocationAreaCode;
- cell.gsmCellId = srcCell.gsmCellId;
+ this.updateInfo(srcCell, cell);
}
let srcNetwork = srcInfo.network;
if (!srcNetwork) {
destInfo.network= null;
return;
}
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1170,27 +1170,24 @@ RadioInterface.prototype = {
voiceInfo.state = newInfo.state;
voiceInfo.connected = newInfo.connected;
voiceInfo.roaming = newInfo.roaming;
voiceInfo.emergencyCallsOnly = newInfo.emergencyCallsOnly;
voiceInfo.type = newInfo.type;
// Make sure we also reset the operator and signal strength information
// if we drop off the network.
- if (newInfo.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
+ if (newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_HOME &&
+ newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING) {
+ voiceInfo.cell = null;
voiceInfo.network = null;
voiceInfo.signalStrength = null;
voiceInfo.relSignalStrength = null;
- }
-
- let newCell = newInfo.cell;
- if ((newCell.gsmLocationAreaCode < 0) || (newCell.gsmCellId < 0)) {
- voiceInfo.cell = null;
} else {
- voiceInfo.cell = newCell;
+ voiceInfo.cell = newInfo.cell;
}
if (!newInfo.batch) {
gMessageManager.sendMobileConnectionMessage("RIL:VoiceInfoChanged",
this.clientId, voiceInfo);
}
},
@@ -1206,27 +1203,24 @@ RadioInterface.prototype = {
dataInfo.connected = false;
if (apnSetting) {
dataInfo.connected = (this.getDataCallStateByType("default") ==
RIL.GECKO_NETWORK_STATE_CONNECTED);
}
// Make sure we also reset the operator and signal strength information
// if we drop off the network.
- if (newInfo.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
+ if (newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_HOME &&
+ newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING) {
+ dataInfo.cell = null;
dataInfo.network = null;
dataInfo.signalStrength = null;
dataInfo.relSignalStrength = null;
- }
-
- let newCell = newInfo.cell;
- if ((newCell.gsmLocationAreaCode < 0) || (newCell.gsmCellId < 0)) {
- dataInfo.cell = null;
} else {
- dataInfo.cell = newCell;
+ dataInfo.cell = newInfo.cell;
}
if (!newInfo.batch) {
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
this.clientId, dataInfo);
}
this.updateRILNetworkInterface();
},
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -818,21 +818,16 @@ let RIL = {
this.iccInfo = {};
/**
* CDMA specific information. ex. CDMA Network ID, CDMA System ID... etc.
*/
this.cdmaHome = null;
/**
- * CDMA Subscription information.
- */
- this.cdmaSubscription = {};
-
- /**
* Application identification for apps in ICC.
*/
this.aid = null;
/**
* Application type for apps in ICC.
*/
this.appType = null;
@@ -3398,33 +3393,43 @@ let RIL = {
_processVoiceRegistrationState: function _processVoiceRegistrationState(state) {
let rs = this.voiceRegistrationState;
let stateChanged = this._processCREG(rs, state);
if (stateChanged && rs.connected) {
RIL.getSMSCAddress();
}
+ let cell = rs.cell;
if (this._isCdma) {
// Some variables below are not used. Comment them instead of removing to
// keep the information about state[x].
-
- // let baseStationId = RIL.parseInt(state[4]);
- let baseStationLatitude = RIL.parseInt(state[5]);
- let baseStationLongitude = RIL.parseInt(state[6]);
- if (!baseStationLatitude && !baseStationLongitude) {
- baseStationLatitude = baseStationLongitude = null;
- }
+ let cdmaBaseStationId = RIL.parseInt(state[4], -1);
+ let cdmaBaseStationLatitude = RIL.parseInt(state[5], -2147483648);
+ let cdmaBaseStationLongitude = RIL.parseInt(state[6], -2147483648);
// let cssIndicator = RIL.parseInt(state[7]);
- RIL.cdmaSubscription.systemId = RIL.parseInt(state[8]);
- RIL.cdmaSubscription.networkId = RIL.parseInt(state[9]);
+ let cdmaSystemId = RIL.parseInt(state[8], -1);
+ let cdmaNetworkId = RIL.parseInt(state[9], -1);
// let roamingIndicator = RIL.parseInt(state[10]);
// let systemIsInPRL = RIL.parseInt(state[11]);
// let defaultRoamingIndicator = RIL.parseInt(state[12]);
// let reasonForDenial = RIL.parseInt(state[13]);
+
+ if (cell.cdmaBaseStationId !== cdmaBaseStationId ||
+ cell.cdmaBaseStationLatitude !== cdmaBaseStationLatitude ||
+ cell.cdmaBaseStationLongitude !== cdmaBaseStationLongitude ||
+ cell.cdmaSystemId !== cdmaSystemId ||
+ cell.cdmaNetworkId !== cdmaNetworkId) {
+ stateChanged = true;
+ cell.cdmaBaseStationId = cdmaBaseStationId;
+ cell.cdmaBaseStationLatitude = cdmaBaseStationLatitude;
+ cell.cdmaBaseStationLongitude = cdmaBaseStationLongitude;
+ cell.cdmaSystemId = cdmaSystemId;
+ cell.cdmaNetworkId = cdmaNetworkId;
+ }
}
if (stateChanged) {
rs.rilMessageType = "voiceregistrationstatechange";
this._sendNetworkInfoMessage(NETWORK_INFO_VOICE_REGISTRATION_STATE, rs);
}
},
@@ -11645,18 +11650,19 @@ let ICCUtilsHelper = {
let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
if (displayCondition === undefined) {
iccInfo.isDisplayNetworkNameRequired = true;
iccInfo.isDisplaySpnRequired = false;
} else if (RIL._isCdma) {
// CDMA family display rule.
let cdmaHome = RIL.cdmaHome;
- let sid = RIL.cdmaSubscription.systemId;
- let nid = RIL.cdmaSubscription.networkId;
+ let cell = RIL.voiceRegistrationState.cell;
+ let sid = cell && cell.cdmaSystemId;
+ let nid = cell && cell.cdmaNetworkId;
iccInfo.isDisplayNetworkNameRequired = false;
// If display condition is 0x0, we don't even need to check network id
// or system id.
if (displayCondition === 0x0) {
iccInfo.isDisplaySpnRequired = false;
} else {
--- a/dom/system/gonk/tests/test_ril_worker_ruim.js
+++ b/dom/system/gonk/tests/test_ril_worker_ruim.js
@@ -199,19 +199,19 @@ add_test(function test_cdma_spn_display_
currentSystemId, currentNetworkId,
expectUpdateDisplayCondition,
expectIsDisplaySPNRequired) {
RIL.iccInfoPrivate.spnDisplayCondition = ruimDisplayCondition;
RIL.cdmaHome = {
systemId: homeSystemIds,
networkId: homeNetworkIds
};
- RIL.cdmaSubscription = {
- systemId: currentSystemId,
- networkId: currentNetworkId
+ RIL.voiceRegistrationState.cell = {
+ cdmaSystemId: currentSystemId,
+ cdmaNetworkId: currentNetworkId
};
do_check_eq(ICCUtilsHelper.updateDisplayCondition(), expectUpdateDisplayCondition);
do_check_eq(RIL.iccInfo.isDisplayNetworkNameRequired, false);
do_check_eq(RIL.iccInfo.isDisplaySpnRequired, expectIsDisplaySPNRequired);
};
// SPN is not required when ruimDisplayCondition is false.
deleted file mode 100644
--- a/gfx/layers/GonkIOSurfaceImage.cpp
+++ /dev/null
@@ -1,164 +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/. */
-
-#include "GonkIOSurfaceImage.h"
-
-#include <OMX_IVCommon.h>
-#include <ColorConverter.h>
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-
-#define ALIGN(x, align) ((x + align - 1) & ~(align - 1))
-
-typedef android::GraphicBuffer GraphicBuffer;
-
-namespace mozilla {
-namespace layers {
-
-uint32_t GonkIOSurfaceImage::sColorIdMap[] = {
- HAL_PIXEL_FORMAT_YCbCr_420_P, OMX_COLOR_FormatYUV420Planar,
- HAL_PIXEL_FORMAT_YCbCr_422_P, OMX_COLOR_FormatYUV422Planar,
- HAL_PIXEL_FORMAT_YCbCr_420_SP, OMX_COLOR_FormatYUV420SemiPlanar,
- HAL_PIXEL_FORMAT_YCrCb_420_SP, -1,
- HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO, -1,
- HAL_PIXEL_FORMAT_YV12, OMX_COLOR_FormatYUV420Planar,
- 0, 0
-};
-
-struct GraphicBufferAutoUnlock {
- android::sp<GraphicBuffer> mGraphicBuffer;
-
- GraphicBufferAutoUnlock(android::sp<GraphicBuffer>& aGraphicBuffer)
- : mGraphicBuffer(aGraphicBuffer) { }
-
- ~GraphicBufferAutoUnlock() { mGraphicBuffer->unlock(); }
-};
-
-/**
- * Converts YVU420 semi planar frames to RGB565, possibly taking different
- * stride values.
- * Needed because the Android ColorConverter class assumes that the Y and UV
- * channels have equal stride.
- */
-static void
-ConvertYVU420SPToRGB565(void *aYData, uint32_t aYStride,
- void *aUVData, uint32_t aUVStride,
- void *aOut,
- uint32_t aWidth, uint32_t aHeight)
-{
- uint8_t *y = (uint8_t*)aYData;
- int8_t *uv = (int8_t*)aUVData;
-
- uint16_t *rgb = (uint16_t*)aOut;
-
- for (size_t i = 0; i < aHeight; i++) {
- for (size_t j = 0; j < aWidth; j++) {
- int8_t d = uv[j | 1] - 128;
- int8_t e = uv[j & ~1] - 128;
-
- // Constants taken from https://en.wikipedia.org/wiki/YUV
- int32_t r = (298 * y[j] + 409 * e + 128) >> 11;
- int32_t g = (298 * y[j] - 100 * d - 208 * e + 128) >> 10;
- int32_t b = (298 * y[j] + 516 * d + 128) >> 11;
-
- r = r > 0x1f ? 0x1f : r < 0 ? 0 : r;
- g = g > 0x3f ? 0x3f : g < 0 ? 0 : g;
- b = b > 0x1f ? 0x1f : b < 0 ? 0 : b;
-
- *rgb++ = (uint16_t)(r << 11 | g << 5 | b);
- }
-
- y += aYStride;
- if (i % 2) {
- uv += aUVStride;
- }
- }
-}
-
-already_AddRefed<gfxASurface>
-GonkIOSurfaceImage::GetAsSurface()
-{
- android::sp<GraphicBuffer> graphicBuffer =
- GrallocBufferActor::GetFrom(GetSurfaceDescriptor());
-
- void *buffer;
- int32_t rv =
- graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &buffer);
-
- if (rv) {
- NS_WARNING("Couldn't lock graphic buffer");
- return nullptr;
- }
-
- GraphicBufferAutoUnlock unlock(graphicBuffer);
-
- uint32_t format = graphicBuffer->getPixelFormat();
- uint32_t omxFormat = 0;
-
- for (int i = 0; sColorIdMap[i]; i += 2) {
- if (sColorIdMap[i] == format) {
- omxFormat = sColorIdMap[i + 1];
- break;
- }
- }
-
- if (!omxFormat) {
- NS_WARNING("Unknown color format");
- return nullptr;
- }
-
- nsRefPtr<gfxImageSurface> imageSurface =
- new gfxImageSurface(GetSize(), gfxASurface::ImageFormatRGB16_565);
-
- uint32_t width = GetSize().width;
- uint32_t height = GetSize().height;
-
- if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO) {
- // The Adreno hardware decoder aligns image dimensions to a multiple of 32,
- // so we have to account for that here
- uint32_t alignedWidth = ALIGN(width, 32);
- uint32_t alignedHeight = ALIGN(height, 32);
- uint32_t uvOffset = ALIGN(alignedHeight * alignedWidth, 4096);
- uint32_t uvStride = 2 * ALIGN(width / 2, 32);
- uint8_t* buffer_as_bytes = static_cast<uint8_t*>(buffer);
- ConvertYVU420SPToRGB565(buffer, alignedWidth,
- buffer_as_bytes + uvOffset, uvStride,
- imageSurface->Data(),
- width, height);
-
- return imageSurface.forget();
- }
- else if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
- uint32_t uvOffset = height * width;
- ConvertYVU420SPToRGB565(buffer, width,
- buffer + uvOffset, width,
- imageSurface->Data(),
- width, height);
-
- return imageSurface.forget();
- }
-
- android::ColorConverter colorConverter((OMX_COLOR_FORMATTYPE)omxFormat,
- OMX_COLOR_Format16bitRGB565);
-
- if (!colorConverter.isValid()) {
- NS_WARNING("Invalid color conversion");
- return nullptr;
- }
-
- rv = colorConverter.convert(buffer, width, height,
- 0, 0, width - 1, height - 1 /* source crop */,
- imageSurface->Data(), width, height,
- 0, 0, width - 1, height - 1 /* dest crop */);
-
- if (rv) {
- NS_WARNING("OMX color conversion failed");
- return nullptr;
- }
-
- return imageSurface.forget();
-}
-
-} // namespace layers
-} // namespace mozilla
deleted file mode 100644
--- a/gfx/layers/GonkIOSurfaceImage.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GONKIOSURFACEIMAGE_H
-#define GONKIOSURFACEIMAGE_H
-
-#ifdef MOZ_WIDGET_GONK
-
-#include "mozilla/layers/LayersSurfaces.h"
-#include "ImageContainer.h"
-
-#include <ui/GraphicBuffer.h>
-
-namespace mozilla {
-namespace layers {
-
-/**
- * The gralloc buffer maintained by android GraphicBuffer can be
- * shared between the compositor thread and the producer thread. The
- * mGraphicBuffer is owned by the producer thread, but when it is
- * wrapped by GraphicBufferLocked and passed to the compositor, the
- * buffer content is guaranteed to not change until Unlock() is
- * called. Each producer must maintain their own buffer queue and
- * implement the GraphicBufferLocked::Unlock() interface.
- */
-class GraphicBufferLocked {
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphicBufferLocked)
-
-public:
- GraphicBufferLocked(SurfaceDescriptor aGraphicBuffer)
- : mSurfaceDescriptor(aGraphicBuffer)
- {}
-
- virtual ~GraphicBufferLocked() {}
-
- virtual void Unlock() {}
-
- SurfaceDescriptor GetSurfaceDescriptor()
- {
- return mSurfaceDescriptor;
- }
-
-protected:
- SurfaceDescriptor mSurfaceDescriptor;
-};
-
-class GonkIOSurfaceImage : public Image {
- typedef android::GraphicBuffer GraphicBuffer;
- static uint32_t sColorIdMap[];
-public:
- struct Data {
- nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
- gfxIntSize mPicSize;
- };
- GonkIOSurfaceImage()
- : Image(nullptr, GONK_IO_SURFACE)
- , mSize(0, 0)
- {}
-
- virtual ~GonkIOSurfaceImage()
- {
- mGraphicBuffer->Unlock();
- }
-
- virtual void SetData(const Data& aData)
- {
- mGraphicBuffer = aData.mGraphicBuffer;
- mSize = aData.mPicSize;
- }
-
- virtual gfxIntSize GetSize()
- {
- return mSize;
- }
-
- // From [android 4.0.4]/hardware/msm7k/libgralloc-qsd8k/gralloc_priv.h
- enum {
- /* OEM specific HAL formats */
- HAL_PIXEL_FORMAT_YCbCr_422_P = 0x102,
- HAL_PIXEL_FORMAT_YCbCr_420_P = 0x103,
- HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
- HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x10A,
- };
-
- enum {
- OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
- };
-
- virtual already_AddRefed<gfxASurface> GetAsSurface();
-
- void* GetNativeBuffer()
- {
- return GrallocBufferActor::GetFrom(GetSurfaceDescriptor())->getNativeBuffer();
- }
-
- SurfaceDescriptor GetSurfaceDescriptor()
- {
- return mGraphicBuffer->GetSurfaceDescriptor();
- }
-
-private:
- nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
- gfxIntSize mSize;
-};
-
-} // namespace layers
-} // namespace mozilla
-#endif
-
-#endif /* GONKIOSURFACEIMAGE_H */
--- a/gfx/layers/GrallocImages.cpp
+++ b/gfx/layers/GrallocImages.cpp
@@ -5,55 +5,93 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/ImageBridgeChild.h"
#include "nsDebug.h"
#include "ImageContainer.h"
#include "GrallocImages.h"
+#include <OMX_IVCommon.h>
+#include <ColorConverter.h>
+
using namespace mozilla::ipc;
using namespace android;
+#define ALIGN(x, align) ((x + align - 1) & ~(align - 1))
+
namespace mozilla {
namespace layers {
-GrallocPlanarYCbCrImage::GrallocPlanarYCbCrImage()
- : PlanarYCbCrImage(nullptr)
+uint32_t GrallocImage::sColorIdMap[] = {
+ HAL_PIXEL_FORMAT_YCbCr_420_P, OMX_COLOR_FormatYUV420Planar,
+ HAL_PIXEL_FORMAT_YCbCr_422_P, OMX_COLOR_FormatYUV422Planar,
+ HAL_PIXEL_FORMAT_YCbCr_420_SP, OMX_COLOR_FormatYUV420SemiPlanar,
+ HAL_PIXEL_FORMAT_YCrCb_420_SP, -1,
+ HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO, -1,
+ HAL_PIXEL_FORMAT_YV12, OMX_COLOR_FormatYUV420Planar,
+ 0, 0
+};
+
+struct GraphicBufferAutoUnlock {
+ android::sp<GraphicBuffer> mGraphicBuffer;
+
+ GraphicBufferAutoUnlock(android::sp<GraphicBuffer>& aGraphicBuffer)
+ : mGraphicBuffer(aGraphicBuffer) { }
+
+ ~GraphicBufferAutoUnlock() { mGraphicBuffer->unlock(); }
+};
+
+GrallocImage::GrallocImage()
+ : PlanarYCbCrImage(nullptr),
+ mBufferAllocated(false),
+ mGraphicBuffer(nullptr)
{
mFormat = GRALLOC_PLANAR_YCBCR;
}
-GrallocPlanarYCbCrImage::~GrallocPlanarYCbCrImage()
+GrallocImage::~GrallocImage()
{
- ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
- ibc->DeallocSurfaceDescriptorGralloc(mSurfaceDescriptor);
+ if (mGraphicBuffer.get()) {
+ mGraphicBuffer->Unlock();
+ if (mBufferAllocated) {
+ ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
+ ibc->DeallocSurfaceDescriptorGralloc(mGraphicBuffer->GetSurfaceDescriptor());
+ mBufferAllocated = false;
+ }
+ }
}
void
-GrallocPlanarYCbCrImage::SetData(const Data& aData)
+GrallocImage::SetData(const Data& aData)
{
NS_PRECONDITION(aData.mYSize.width % 2 == 0, "Image should have even width");
NS_PRECONDITION(aData.mYSize.height % 2 == 0, "Image should have even height");
NS_PRECONDITION(aData.mYStride % 16 == 0, "Image should have stride of multiple of 16 pixels");
mData = aData;
mSize = aData.mPicSize;
- if (mSurfaceDescriptor.type() == SurfaceDescriptor::T__None) {
+ if (!mGraphicBuffer.get()) {
+
+ SurfaceDescriptor desc;
ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
ibc->AllocSurfaceDescriptorGralloc(aData.mYSize,
HAL_PIXEL_FORMAT_YV12,
GraphicBuffer::USAGE_SW_READ_OFTEN |
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
GraphicBuffer::USAGE_HW_TEXTURE,
- &mSurfaceDescriptor);
+ &desc);
+ mBufferAllocated = true;
+ mGraphicBuffer = new GraphicBufferLocked(desc);
}
+
sp<GraphicBuffer> graphicBuffer =
- GrallocBufferActor::GetFrom(mSurfaceDescriptor.get_SurfaceDescriptorGralloc());
+ GrallocBufferActor::GetFrom(
+ mGraphicBuffer->GetSurfaceDescriptor().get_SurfaceDescriptorGralloc());
if (!graphicBuffer.get()) {
return;
}
if (graphicBuffer->initCheck() != NO_ERROR) {
return;
}
@@ -99,10 +137,141 @@ GrallocPlanarYCbCrImage::SetData(const D
memcpy(vChannel + i * uvStride,
mData.mCrChannel + i * mData.mCbCrStride,
uvSize.width);
}
}
graphicBuffer->unlock();
}
+void GrallocImage::SetData(const GrallocData& aData)
+{
+ mGraphicBuffer = aData.mGraphicBuffer;
+ mSize = aData.mPicSize;
+}
+
+/**
+ * Converts YVU420 semi planar frames to RGB565, possibly taking different
+ * stride values.
+ * Needed because the Android ColorConverter class assumes that the Y and UV
+ * channels have equal stride.
+ */
+static void
+ConvertYVU420SPToRGB565(void *aYData, uint32_t aYStride,
+ void *aUVData, uint32_t aUVStride,
+ void *aOut,
+ uint32_t aWidth, uint32_t aHeight)
+{
+ uint8_t *y = (uint8_t*)aYData;
+ int8_t *uv = (int8_t*)aUVData;
+
+ uint16_t *rgb = (uint16_t*)aOut;
+
+ for (size_t i = 0; i < aHeight; i++) {
+ for (size_t j = 0; j < aWidth; j++) {
+ int8_t d = uv[j | 1] - 128;
+ int8_t e = uv[j & ~1] - 128;
+
+ // Constants taken from https://en.wikipedia.org/wiki/YUV
+ int32_t r = (298 * y[j] + 409 * e + 128) >> 11;
+ int32_t g = (298 * y[j] - 100 * d - 208 * e + 128) >> 10;
+ int32_t b = (298 * y[j] + 516 * d + 128) >> 11;
+
+ r = r > 0x1f ? 0x1f : r < 0 ? 0 : r;
+ g = g > 0x3f ? 0x3f : g < 0 ? 0 : g;
+ b = b > 0x1f ? 0x1f : b < 0 ? 0 : b;
+
+ *rgb++ = (uint16_t)(r << 11 | g << 5 | b);
+ }
+
+ y += aYStride;
+ if (i % 2) {
+ uv += aUVStride;
+ }
+ }
+}
+
+already_AddRefed<gfxASurface>
+GrallocImage::GetAsSurface()
+{
+ android::sp<GraphicBuffer> graphicBuffer =
+ GrallocBufferActor::GetFrom(GetSurfaceDescriptor());
+
+ void *buffer;
+ int32_t rv =
+ graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &buffer);
+
+ if (rv) {
+ NS_WARNING("Couldn't lock graphic buffer");
+ return nullptr;
+ }
+
+ GraphicBufferAutoUnlock unlock(graphicBuffer);
+
+ uint32_t format = graphicBuffer->getPixelFormat();
+ uint32_t omxFormat = 0;
+
+ for (int i = 0; sColorIdMap[i]; i += 2) {
+ if (sColorIdMap[i] == format) {
+ omxFormat = sColorIdMap[i + 1];
+ break;
+ }
+ }
+
+ if (!omxFormat) {
+ NS_WARNING("Unknown color format");
+ return nullptr;
+ }
+
+ nsRefPtr<gfxImageSurface> imageSurface =
+ new gfxImageSurface(GetSize(), gfxASurface::ImageFormatRGB16_565);
+
+ uint32_t width = GetSize().width;
+ uint32_t height = GetSize().height;
+
+ if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO) {
+ // The Adreno hardware decoder aligns image dimensions to a multiple of 32,
+ // so we have to account for that here
+ uint32_t alignedWidth = ALIGN(width, 32);
+ uint32_t alignedHeight = ALIGN(height, 32);
+ uint32_t uvOffset = ALIGN(alignedHeight * alignedWidth, 4096);
+ uint32_t uvStride = 2 * ALIGN(width / 2, 32);
+ uint8_t* buffer_as_bytes = static_cast<uint8_t*>(buffer);
+ ConvertYVU420SPToRGB565(buffer, alignedWidth,
+ buffer_as_bytes + uvOffset, uvStride,
+ imageSurface->Data(),
+ width, height);
+
+ return imageSurface.forget();
+ }
+ else if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
+ uint32_t uvOffset = height * width;
+ ConvertYVU420SPToRGB565(buffer, width,
+ buffer + uvOffset, width,
+ imageSurface->Data(),
+ width, height);
+
+ return imageSurface.forget();
+ }
+
+ android::ColorConverter colorConverter((OMX_COLOR_FORMATTYPE)omxFormat,
+ OMX_COLOR_Format16bitRGB565);
+
+ if (!colorConverter.isValid()) {
+ NS_WARNING("Invalid color conversion");
+ return nullptr;
+ }
+
+ rv = colorConverter.convert(buffer, width, height,
+ 0, 0, width - 1, height - 1 /* source crop */,
+ imageSurface->Data(), width, height,
+ 0, 0, width - 1, height - 1 /* dest crop */);
+
+ if (rv) {
+ NS_WARNING("OMX color conversion failed");
+ return nullptr;
+ }
+
+ return imageSurface.forget();
+}
+
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/GrallocImages.h
+++ b/gfx/layers/GrallocImages.h
@@ -5,23 +5,54 @@
#ifndef GRALLOCIMAGES_H
#define GRALLOCIMAGES_H
#ifdef MOZ_WIDGET_GONK
#include "mozilla/layers/LayersSurfaces.h"
#include "ImageLayers.h"
+#include "ImageContainer.h"
#include <ui/GraphicBuffer.h>
namespace mozilla {
namespace layers {
/**
+ * The gralloc buffer maintained by android GraphicBuffer can be
+ * shared between the compositor thread and the producer thread. The
+ * mGraphicBuffer is owned by the producer thread, but when it is
+ * wrapped by GraphicBufferLocked and passed to the compositor, the
+ * buffer content is guaranteed to not change until Unlock() is
+ * called. Each producer must maintain their own buffer queue and
+ * implement the GraphicBufferLocked::Unlock() interface.
+ */
+class GraphicBufferLocked {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphicBufferLocked)
+
+public:
+ GraphicBufferLocked(SurfaceDescriptor aGraphicBuffer)
+ : mSurfaceDescriptor(aGraphicBuffer)
+ {}
+
+ virtual ~GraphicBufferLocked() {}
+
+ virtual void Unlock() {}
+
+ SurfaceDescriptor GetSurfaceDescriptor()
+ {
+ return mSurfaceDescriptor;
+ }
+
+protected:
+ SurfaceDescriptor mSurfaceDescriptor;
+};
+
+/**
* The YUV format supported by Android HAL
*
* 4:2:0 - CbCr width and height is half that of Y.
*
* This format assumes
* - an even width
* - an even height
* - a horizontal stride multiple of 16 pixels
@@ -32,39 +63,73 @@ namespace layers {
* size = y_size + c_size * 2
* cr_offset = y_size
* cb_offset = y_size + c_size
*
* The Image that is rendered is the picture region defined by
* mPicX, mPicY and mPicSize. The size of the rendered image is
* mPicSize, not mYSize or mCbCrSize.
*/
-class GrallocPlanarYCbCrImage : public PlanarYCbCrImage {
+class GrallocImage : public PlanarYCbCrImage {
typedef PlanarYCbCrImage::Data Data;
+ static uint32_t sColorIdMap[];
public:
- GrallocPlanarYCbCrImage();
+ struct GrallocData {
+ nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
+ gfxIntSize mPicSize;
+ };
- virtual ~GrallocPlanarYCbCrImage();
+ GrallocImage();
+
+ virtual ~GrallocImage();
/**
* This makes a copy of the data buffers, in order to support functioning
* in all different layer managers.
*/
virtual void SetData(const Data& aData);
- virtual uint32_t GetDataSize() { return 0; }
+ /**
+ * Share the SurfaceDescriptor without making the copy, in order
+ * to support functioning in all different layer managers.
+ */
+ virtual void SetData(const GrallocData& aData);
- virtual bool IsValid() { return mSurfaceDescriptor.type() != SurfaceDescriptor::T__None; }
+ // From [android 4.0.4]/hardware/msm7k/libgralloc-qsd8k/gralloc_priv.h
+ enum {
+ /* OEM specific HAL formats */
+ HAL_PIXEL_FORMAT_YCbCr_422_P = 0x102,
+ HAL_PIXEL_FORMAT_YCbCr_420_P = 0x103,
+ HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
+ HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x10A,
+ };
+
+ virtual already_AddRefed<gfxASurface> GetAsSurface();
+
+ void* GetNativeBuffer()
+ {
+ if (IsValid()) {
+ return GrallocBufferActor::GetFrom(GetSurfaceDescriptor())->getNativeBuffer();
+ } else {
+ return nullptr;
+ }
+ }
+
+ virtual bool IsValid() { return GetSurfaceDescriptor().type() != SurfaceDescriptor::T__None; }
SurfaceDescriptor GetSurfaceDescriptor() {
- return mSurfaceDescriptor;
+ if (mGraphicBuffer.get()) {
+ return mGraphicBuffer->GetSurfaceDescriptor();
+ }
+ return SurfaceDescriptor();
}
private:
- SurfaceDescriptor mSurfaceDescriptor;
+ bool mBufferAllocated;
+ nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
};
} // namespace layers
} // namespace mozilla
#endif
#endif /* GRALLOCIMAGES_H */
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -2,17 +2,16 @@
* 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 "mozilla/layers/ImageBridgeChild.h"
#include "ImageContainer.h"
-#include "GonkIOSurfaceImage.h"
#include "GrallocImages.h"
#include "mozilla/ipc/Shmem.h"
#include "mozilla/ipc/CrossProcessMutex.h"
#include "SharedTextureImage.h"
#include "gfxImageSurface.h"
#include "gfxSharedImageSurface.h"
#include "yuv_convert.h"
#include "gfxUtils.h"
@@ -49,38 +48,32 @@ ImageFactory::CreateImage(const ImageFor
BufferRecycleBin *aRecycleBin)
{
if (!aNumFormats) {
return nullptr;
}
nsRefPtr<Image> img;
#ifdef MOZ_WIDGET_GONK
if (FormatInList(aFormats, aNumFormats, GRALLOC_PLANAR_YCBCR)) {
- img = new GrallocPlanarYCbCrImage();
+ img = new GrallocImage();
return img.forget();
}
#endif
if (FormatInList(aFormats, aNumFormats, PLANAR_YCBCR)) {
img = new PlanarYCbCrImage(aRecycleBin);
return img.forget();
}
if (FormatInList(aFormats, aNumFormats, CAIRO_SURFACE)) {
img = new CairoImage();
return img.forget();
}
if (FormatInList(aFormats, aNumFormats, SHARED_TEXTURE)) {
img = new SharedTextureImage();
return img.forget();
}
-#ifdef MOZ_WIDGET_GONK
- if (FormatInList(aFormats, aNumFormats, GONK_IO_SURFACE)) {
- img = new GonkIOSurfaceImage();
- return img.forget();
- }
-#endif
#ifdef XP_WIN
if (FormatInList(aFormats, aNumFormats, D3D9_RGB32_TEXTURE)) {
img = new D3D9SurfaceImage();
return img.forget();
}
#endif
return nullptr;
}
--- a/gfx/layers/ImageTypes.h
+++ b/gfx/layers/ImageTypes.h
@@ -12,19 +12,19 @@ enum ImageFormat {
/**
* The PLANAR_YCBCR format creates a PlanarYCbCrImage. All backends should
* support this format, because the Ogg video decoder depends on it.
* The maximum image width and height is 16384.
*/
PLANAR_YCBCR,
/**
- * The GRALLOC_PLANAR_YCBCR format creates a GrallocPlanarYCbCrImage, a
- * subtype of PlanarYCbCrImage. It takes a PlanarYCbCrImage data and can be
- * used as a texture by Gonk backend directly.
+ * The GRALLOC_PLANAR_YCBCR format creates a GrallocImage, a subtype of
+ * PlanarYCbCrImage. It takes a PlanarYCbCrImage data or the raw gralloc
+ * data and can be used as a texture by Gonk backend directly.
*/
GRALLOC_PLANAR_YCBCR,
/**
* The SHARED_RGB format creates a DeprecatedSharedRGBImage, which stores RGB data in
* shared memory. Some Android hardware video decoders require this format.
* Currently only used on Android.
*/
@@ -41,23 +41,16 @@ enum ImageFormat {
*
* Images in CAIRO_SURFACE format should only be created and
* manipulated on the main thread, since the underlying cairo surface
* is main-thread-only.
*/
CAIRO_SURFACE,
/**
- * The GONK_IO_SURFACE format creates a GonkIOSurfaceImage.
- *
- * It wraps an GraphicBuffer object and binds it directly to a GL texture.
- */
- GONK_IO_SURFACE,
-
- /**
* An bitmap image that can be shared with a remote process.
*/
REMOTE_IMAGE_BITMAP,
/**
* A OpenGL texture that can be shared across threads or processes
*/
SHARED_TEXTURE,
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -8,17 +8,16 @@
#include "BasicLayers.h"
#include "mozilla/layers/ShadowLayers.h"
#include "SharedTextureImage.h"
#include "ImageContainer.h" // For PlanarYCbCrImage
#include "mozilla/layers/SharedRGBImage.h"
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
#ifdef MOZ_WIDGET_GONK
-#include "GonkIOSurfaceImage.h"
#include "GrallocImages.h"
#endif
namespace mozilla {
namespace layers {
/* static */ TemporaryRef<ImageClient>
ImageClient::CreateImageClient(CompositableType aCompositableHostType,
@@ -147,41 +146,27 @@ DeprecatedImageClientSingle::UpdateImage
AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient);
SurfaceDescriptor desc;
if (!static_cast<DeprecatedSharedRGBImage*>(image)->ToSurfaceDescriptor(desc)) {
return false;
}
mDeprecatedTextureClient->SetDescriptor(desc);
#ifdef MOZ_WIDGET_GONK
- } else if (image->GetFormat() == GONK_IO_SURFACE &&
- EnsureDeprecatedTextureClient(TEXTURE_SHARED_GL_EXTERNAL)) {
- nsIntRect rect(0, 0,
- image->GetSize().width,
- image->GetSize().height);
- UpdatePictureRect(rect);
-
- AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient);
-
- SurfaceDescriptor desc = static_cast<GonkIOSurfaceImage*>(image)->GetSurfaceDescriptor();
- if (!IsSurfaceDescriptorValid(desc)) {
- return false;
- }
- mDeprecatedTextureClient->SetDescriptor(desc);
} else if (image->GetFormat() == GRALLOC_PLANAR_YCBCR) {
EnsureDeprecatedTextureClient(TEXTURE_SHARED_GL_EXTERNAL);
nsIntRect rect(0, 0,
image->GetSize().width,
image->GetSize().height);
UpdatePictureRect(rect);
AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient);
- SurfaceDescriptor desc = static_cast<GrallocPlanarYCbCrImage*>(image)->GetSurfaceDescriptor();
+ SurfaceDescriptor desc = static_cast<GrallocImage*>(image)->GetSurfaceDescriptor();
if (!IsSurfaceDescriptorValid(desc)) {
return false;
}
mDeprecatedTextureClient->SetDescriptor(desc);
#endif
} else {
nsRefPtr<gfxASurface> surface = image->GetAsSurface();
MOZ_ASSERT(surface);
@@ -248,21 +233,18 @@ ImageClient::CreateImage(const uint32_t
switch (aFormats[i]) {
case PLANAR_YCBCR:
img = new DeprecatedSharedPlanarYCbCrImage(GetForwarder());
return img.forget();
case SHARED_RGB:
img = new DeprecatedSharedRGBImage(GetForwarder());
return img.forget();
#ifdef MOZ_WIDGET_GONK
- case GONK_IO_SURFACE:
- img = new GonkIOSurfaceImage();
- return img.forget();
case GRALLOC_PLANAR_YCBCR:
- img = new GrallocPlanarYCbCrImage();
+ img = new GrallocImage();
return img.forget();
#endif
}
}
return nullptr;
}
}
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -5,17 +5,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MODULE = 'thebes'
EXPORTS += [
'CopyableCanvasLayer.h',
'D3D9SurfaceImage.h',
'FrameMetrics.h',
- 'GonkIOSurfaceImage.h',
+ 'GrallocImages.h',
'ImageContainer.h',
'ImageLayers.h',
'ImageTypes.h',
'LayerSorter.h',
'LayerTreeInvalidation.h',
'Layers.h',
'LayersLogging.h',
'ReadbackLayer.h',
@@ -161,17 +161,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
# has full system permissions there.
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXPORTS.mozilla.layers += [
'ipc/ShadowLayerUtilsGralloc.h',
]
CPP_SOURCES += [
'ShadowLayerUtilsGralloc.cpp',
'GrallocImages.cpp',
- 'GonkIOSurfaceImage.cpp',
]
CPP_SOURCES += [
'AsyncCompositionManager.cpp',
'AsyncPanZoomController.cpp',
'Axis.cpp',
'BasicCanvasLayer.cpp',
'BasicColorLayer.cpp',
--- a/gfx/skia/Makefile.in
+++ b/gfx/skia/Makefile.in
@@ -54,17 +54,17 @@ VPATH += \
$(srcdir)/src/effects \
$(srcdir)/src/effects/gradients \
$(srcdir)/src/utils \
$(srcdir)/src/utils/android \
$(srcdir)/src/utils/mac \
$(srcdir)/src/sfnt \
$(NULL)
-ifeq (android,$(MOZ_WIDGET_TOOLKIT))
+ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gonk))
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
DEFINES += -DSK_FONTHOST_CAIRO_STANDALONE=0
endif
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PANGO_CFLAGS) $(CAIRO_FT_CFLAGS)
endif
--- a/gfx/skia/moz.build
+++ b/gfx/skia/moz.build
@@ -202,24 +202,19 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt
'include/ports/SkTypeface_cairo.h',
]
CPP_SOURCES += [
'SkThread_pthread.cpp',
'SkThreadUtils_pthread.cpp',
'SkThreadUtils_pthread_linux.cpp',
'SkTime_Unix.cpp',
]
-elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
- CPP_SOURCES += [
- 'SkThread_pthread.cpp',
- ]
-
# Separate 'if' from above, since the else below applies to all != 'android'
# toolkits.
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
EXPORTS.skia += [
'include/ports/SkTypeface_cairo.h',
]
CPP_SOURCES += [
'ashmem.cpp',
'SkDebug_android.cpp',
'SkFontHost_cairo.cpp',
'SkFontHost_linux.cpp',
--- a/js/public/CharacterEncoding.h
+++ b/js/public/CharacterEncoding.h
@@ -53,16 +53,30 @@ class Latin1CharsZ : public mozilla::Ran
: Base(aBytes, aLength)
{
JS_ASSERT(aBytes[aLength] == '\0');
}
char *c_str() { return reinterpret_cast<char *>(get()); }
};
+class UTF8Chars : public mozilla::Range<unsigned char>
+{
+ typedef mozilla::Range<unsigned char> Base;
+
+ public:
+ UTF8Chars() : Base() {}
+ UTF8Chars(char *aBytes, size_t aLength)
+ : Base(reinterpret_cast<unsigned char *>(aBytes), aLength)
+ {}
+ UTF8Chars(const char *aBytes, size_t aLength)
+ : Base(reinterpret_cast<unsigned char *>(const_cast<char *>(aBytes)), aLength)
+ {}
+};
+
/*
* SpiderMonkey also deals directly with UTF-8 encoded text in some places.
*/
class UTF8CharsZ : public mozilla::RangedPtr<unsigned char>
{
typedef mozilla::RangedPtr<unsigned char> Base;
public:
@@ -119,20 +133,22 @@ class StableTwoByteChars : public mozill
/*
* A TwoByteChars, but \0 terminated for compatibility with JSFlatString.
*/
class TwoByteCharsZ : public mozilla::RangedPtr<jschar>
{
typedef mozilla::RangedPtr<jschar> Base;
public:
+ TwoByteCharsZ() : Base(NULL, 0) {}
+
TwoByteCharsZ(jschar *chars, size_t length)
: Base(chars, length)
{
- JS_ASSERT(chars[length] = '\0');
+ JS_ASSERT(chars[length] == '\0');
}
};
/*
* Convert a 2-byte character sequence to "ISO-Latin-1". This works by
* truncating each 2-byte pair in the sequence to a 1-byte pair. If the source
* contains any UTF-16 extension characters, then this may give invalid Latin1
* output. The returned string is zero terminated. The returned string or the
@@ -142,14 +158,34 @@ class TwoByteCharsZ : public mozilla::Ra
* This method cannot trigger GC.
*/
extern Latin1CharsZ
LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars);
extern UTF8CharsZ
TwoByteCharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars);
+uint32_t
+Utf8ToOneUcs4Char(const uint8_t *utf8Buffer, int utf8Length);
+
+/*
+ * Inflate bytes in UTF-8 encoding to jschars.
+ * - On error, returns an empty TwoByteCharsZ.
+ * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold
+ * its length; the length value excludes the trailing null.
+ */
+extern TwoByteCharsZ
+UTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen);
+
+/*
+ * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 characters
+ * will be replaced by \uFFFD. No exception will be thrown for malformed UTF-8
+ * input.
+ */
+extern TwoByteCharsZ
+LossyUTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen);
+
} // namespace JS
inline void JS_free(JS::Latin1CharsZ &ptr) { js_free((void*)ptr.get()); }
inline void JS_free(JS::UTF8CharsZ &ptr) { js_free((void*)ptr.get()); }
#endif /* js_CharacterEncoding_h */
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -6533,22 +6533,20 @@ CData::GetRuntime(JSContext* cx, unsigne
JSObject* result = CData::Create(cx, targetType, NullPtr(), &data, true);
if (!result)
return JS_FALSE;
args.rval().setObject(*result);
return JS_TRUE;
}
-typedef bool (*InflateUTF8Method)(JSContext *, const char *, size_t,
- jschar *, size_t *);
-
-template <InflateUTF8Method InflateUTF8>
+typedef JS::TwoByteCharsZ (*InflateUTF8Method)(JSContext *, const JS::UTF8Chars, size_t *);
+
static JSBool
-ReadStringCommon(JSContext* cx, unsigned argc, jsval* vp)
+ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 0) {
JS_ReportError(cx, "readString takes zero arguments");
return JS_FALSE;
}
JSObject* obj = CDataFinalizer::GetCData(cx, JS_THIS_OBJECT(cx, vp));
@@ -6591,29 +6589,21 @@ ReadStringCommon(JSContext* cx, unsigned
case TYPE_uint8_t:
case TYPE_char:
case TYPE_signed_char:
case TYPE_unsigned_char: {
char* bytes = static_cast<char*>(data);
size_t length = strnlen(bytes, maxLength);
// Determine the length.
- size_t dstlen;
- if (!InflateUTF8(cx, bytes, length, NULL, &dstlen))
- return JS_FALSE;
-
- jschar* dst =
- static_cast<jschar*>(JS_malloc(cx, (dstlen + 1) * sizeof(jschar)));
+ jschar *dst = inflateUTF8(cx, JS::UTF8Chars(bytes, length), &length).get();
if (!dst)
return JS_FALSE;
- ASSERT_OK(InflateUTF8(cx, bytes, length, dst, &dstlen));
- dst[dstlen] = 0;
-
- result = JS_NewUCString(cx, dst, dstlen);
+ result = JS_NewUCString(cx, dst, length);
break;
}
case TYPE_int16_t:
case TYPE_uint16_t:
case TYPE_short:
case TYPE_unsigned_short:
case TYPE_jschar: {
jschar* chars = static_cast<jschar*>(data);
@@ -6632,23 +6622,23 @@ ReadStringCommon(JSContext* cx, unsigned
args.rval().setString(result);
return JS_TRUE;
}
JSBool
CData::ReadString(JSContext* cx, unsigned argc, jsval* vp)
{
- return ReadStringCommon<InflateUTF8StringToBuffer>(cx, argc, vp);
+ return ReadStringCommon(cx, JS::UTF8CharsToNewTwoByteCharsZ, argc, vp);
}
JSBool
CData::ReadStringReplaceMalformed(JSContext* cx, unsigned argc, jsval* vp)
{
- return ReadStringCommon<InflateUTF8StringToBufferReplaceInvalid>(cx, argc, vp);
+ return ReadStringCommon(cx, JS::LossyUTF8CharsToNewTwoByteCharsZ, argc, vp);
}
JSString *
CData::GetSourceString(JSContext *cx, HandleObject typeObj, void *data)
{
// Walk the types, building up the toSource() string.
// First, we build up the type expression:
// 't.ptr' for pointers;
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -374,16 +374,17 @@ class StoreBuffer
MonoTypeBuffer<CellPtrEdge> bufferCell;
MonoTypeBuffer<SlotEdge> bufferSlot;
MonoTypeBuffer<WholeCellEdges> bufferWholeCell;
RelocatableMonoTypeBuffer<ValueEdge> bufferRelocVal;
RelocatableMonoTypeBuffer<CellPtrEdge> bufferRelocCell;
GenericBuffer bufferGeneric;
JSRuntime *runtime;
+ const Nursery &nursery_;
void *buffer;
bool aboutToOverflow;
bool overflowed;
bool enabled;
/* TODO: profile to find the ideal size for these. */
@@ -395,20 +396,20 @@ class StoreBuffer
static const size_t RelocCellBufferSize = 1 * 1024 * sizeof(CellPtrEdge);
static const size_t GenericBufferSize = 1 * 1024 * sizeof(int);
static const size_t TotalSize = ValueBufferSize + CellBufferSize +
SlotBufferSize + WholeCellBufferSize +
RelocValueBufferSize + RelocCellBufferSize +
GenericBufferSize;
public:
- explicit StoreBuffer(JSRuntime *rt)
+ explicit StoreBuffer(JSRuntime *rt, const Nursery &nursery)
: bufferVal(this), bufferCell(this), bufferSlot(this), bufferWholeCell(this),
bufferRelocVal(this), bufferRelocCell(this), bufferGeneric(this),
- runtime(rt), buffer(NULL), aboutToOverflow(false), overflowed(false),
+ runtime(rt), nursery_(nursery), buffer(NULL), aboutToOverflow(false), overflowed(false),
enabled(false)
{}
bool enable();
void disable();
bool isEnabled() { return enabled; }
bool clear();
@@ -448,17 +449,17 @@ class StoreBuffer
/* Insert an entry into the generic buffer. */
template <typename T>
void putGeneric(const T &t) {
bufferGeneric.put(t);
}
/* Insert or update a callback entry. */
void putCallback(CallbackRef::MarkCallback callback, Cell *key, void *data) {
- if (!key->isTenured())
+ if (nursery_.isInside(key))
bufferGeneric.put(CallbackRef(callback, key, data));
}
/* Mark the source of all edges in the store buffer. */
void mark(JSTracer *trc);
/* We cannot call InParallelSection directly because of a circular dependency. */
bool inParallelSection() const;
--- a/js/src/ion/AliasAnalysis.cpp
+++ b/js/src/ion/AliasAnalysis.cpp
@@ -1,22 +1,23 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/AliasAnalysis.h"
+
#include <stdio.h>
-#include "ion/MIR.h"
-#include "ion/AliasAnalysis.h"
-#include "ion/MIRGraph.h"
#include "ion/Ion.h"
#include "ion/IonBuilder.h"
#include "ion/IonSpewer.h"
+#include "ion/MIR.h"
+#include "ion/MIRGraph.h"
using namespace js;
using namespace js::ion;
using mozilla::Array;
// Iterates over the flags in an AliasSet.
class AliasSetIterator
--- a/js/src/ion/AsmJS.cpp
+++ b/js/src/ion/AsmJS.cpp
@@ -3,41 +3,37 @@
* 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 "ion/AsmJS.h"
#include "mozilla/Move.h"
+#ifdef MOZ_VTUNE
+# include "jitprofiling.h"
+#endif
+
#include "jsmath.h"
#include "jsworkers.h"
#include "jswrapper.h"
#include "prmjtime.h"
-#ifdef MOZ_VTUNE
-# include "jitprofiling.h"
-#endif
-
#include "frontend/Parser.h"
#include "ion/AsmJSModule.h"
-#include "ion/PerfSpewer.h"
#include "ion/CodeGenerator.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
+#include "ion/PerfSpewer.h"
#include "jsfuninlines.h"
#include "frontend/ParseMaps-inl.h"
#include "frontend/ParseNode-inl.h"
-#ifdef MOZ_VTUNE
-# include "jitprofiling.h"
-#endif
-
using namespace js;
using namespace js::frontend;
using namespace js::ion;
using mozilla::AddToHash;
using mozilla::ArrayLength;
using mozilla::DebugOnly;
using mozilla::HashGeneric;
--- a/js/src/ion/AsmJS.h
+++ b/js/src/ion/AsmJS.h
@@ -3,18 +3,18 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_AsmJS_h
#define ion_AsmJS_h
#ifdef XP_MACOSX
+# include <mach/mach.h>
# include <pthread.h>
-# include <mach/mach.h>
#endif
#include "jstypes.h"
#include "ds/LifoAlloc.h"
#include "js/CallArgs.h"
struct JSContext;
--- a/js/src/ion/AsmJSLink.cpp
+++ b/js/src/ion/AsmJSLink.cpp
@@ -1,31 +1,29 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "jsmath.h"
-#include "jscntxt.h"
-
-#include "ion/AsmJS.h"
-#include "ion/AsmJSModule.h"
-#include "frontend/BytecodeCompiler.h"
-
#ifdef MOZ_VTUNE
# include "jitprofiling.h"
#endif
+#include "jscntxt.h"
+#include "jsmath.h"
+
+#include "frontend/BytecodeCompiler.h"
+#include "ion/AsmJS.h"
+#include "ion/AsmJSModule.h"
+#include "ion/Ion.h"
#ifdef JS_ION_PERF
# include "ion/PerfSpewer.h"
#endif
-#include "ion/Ion.h"
-
#include "jsfuninlines.h"
using namespace js;
using namespace js::ion;
using namespace mozilla;
static bool
LinkFail(JSContext *cx, const char *str)
--- a/js/src/ion/AsmJSModule.h
+++ b/js/src/ion/AsmJSModule.h
@@ -2,30 +2,28 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_AsmJSModule_h
#define ion_AsmJSModule_h
-#include "mozilla/MathAlgorithms.h"
-
#ifdef JS_ION
-#include "gc/Marking.h"
-#include "ion/RegisterSets.h"
+#include "mozilla/MathAlgorithms.h"
#include "jsscript.h"
+#include "gc/Marking.h"
+#include "ion/IonMacroAssembler.h"
#if defined(JS_ION_PERF)
# include "ion/PerfSpewer.h"
#endif
-
-#include "ion/IonMacroAssembler.h"
+#include "ion/RegisterSets.h"
namespace js {
// These EcmaScript-defined coercions form the basis of the asm.js type system.
enum AsmJSCoercion
{
AsmJS_ToInt32,
AsmJS_ToNumber
--- a/js/src/ion/AsmJSSignalHandlers.cpp
+++ b/js/src/ion/AsmJSSignalHandlers.cpp
@@ -1,19 +1,19 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "jscntxt.h"
+#include "assembler/assembler/MacroAssembler.h"
#include "ion/AsmJS.h"
#include "ion/AsmJSModule.h"
-#include "assembler/assembler/MacroAssembler.h"
#include "vm/ObjectImpl-inl.h"
using namespace js;
using namespace js::ion;
using namespace mozilla;
#if defined(XP_WIN)
--- a/js/src/ion/BacktrackingAllocator.h
+++ b/js/src/ion/BacktrackingAllocator.h
@@ -4,20 +4,19 @@
* 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 ion_BacktrackingAllocator_h
#define ion_BacktrackingAllocator_h
#include "mozilla/Array.h"
-#include "ion/LiveRangeAllocator.h"
-
#include "ds/PriorityQueue.h"
#include "ds/SplayTree.h"
+#include "ion/LiveRangeAllocator.h"
// Backtracking priority queue based register allocator based on that described
// in the following blog post:
//
// http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html
namespace js {
namespace ion {
--- a/js/src/ion/Bailouts.cpp
+++ b/js/src/ion/Bailouts.cpp
@@ -1,26 +1,27 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/Bailouts.h"
+
#include "jsanalyze.h"
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsinfer.h"
-#include "ion/Bailouts.h"
-#include "ion/SnapshotReader.h"
+#include "ion/BaselineJIT.h"
#include "ion/Ion.h"
#include "ion/IonCompartment.h"
#include "ion/IonSpewer.h"
+#include "ion/SnapshotReader.h"
#include "vm/Interpreter.h"
-#include "ion/BaselineJIT.h"
#include "vm/Stack-inl.h"
using namespace js;
using namespace js::ion;
// These constructor are exactly the same except for the type of the iterator
// which is given to the SnapshotIterator constructor. Doing so avoid the
--- a/js/src/ion/Bailouts.h
+++ b/js/src/ion/Bailouts.h
@@ -3,19 +3,20 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_Bailouts_h
#define ion_Bailouts_h
#include "jstypes.h"
-#include "vm/Stack.h"
+
#include "ion/IonFrameIterator.h"
#include "ion/IonFrames.h"
+#include "vm/Stack.h"
namespace js {
namespace ion {
// A "bailout" is a condition in which we need to recover an interpreter frame
// from an IonFrame. Bailouts can happen for the following reasons:
// (1) A deoptimization guard, for example, an add overflows or a type check
// fails.
--- a/js/src/ion/BaselineBailouts.cpp
+++ b/js/src/ion/BaselineBailouts.cpp
@@ -4,20 +4,21 @@
* 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 "ion/BaselineCompiler.h"
#include "ion/BaselineIC.h"
#include "ion/BaselineJIT.h"
#include "ion/CompileInfo.h"
#include "ion/IonSpewer.h"
-#include "ion/IonFrames-inl.h"
#include "jsfuninlines.h"
+#include "ion/IonFrames-inl.h"
+
using namespace js;
using namespace js::ion;
// BaselineStackBuilder may reallocate its buffer if the current one is too
// small. To avoid dangling pointers, BufferPointer represents a pointer into
// this buffer as a pointer to the header and a fixed offset.
template <typename T>
class BufferPointer
@@ -377,17 +378,17 @@ IsInlinableFallback(ICFallbackStub *icEn
static inline void*
GetStubReturnAddress(JSContext *cx, jsbytecode *pc)
{
if (IsGetterPC(pc))
return cx->compartment()->ionCompartment()->baselineGetPropReturnAddr();
if (IsSetterPC(pc))
return cx->compartment()->ionCompartment()->baselineSetPropReturnAddr();
// This should be a call op of some kind, now.
- JS_ASSERT(js_CodeSpec[JSOp(*pc)].format & JOF_INVOKE);
+ JS_ASSERT(IsCallPC(pc));
return cx->compartment()->ionCompartment()->baselineCallReturnAddr();
}
// For every inline frame, we write out the following data:
//
// | ... |
// +---------------+
// | Descr(???) | --- Descr size here is (PREV_FRAME_SIZE)
@@ -764,17 +765,17 @@ InitFromBailout(JSContext *cx, HandleScr
else if (op == JSOP_LOOPENTRY || op == JSOP_NOP || op == JSOP_LOOPHEAD)
pc = GetNextPc(pc);
else
break;
}
}
uint32_t pcOff = pc - script->code;
- bool isCall = js_CodeSpec[op].format & JOF_INVOKE;
+ bool isCall = IsCallPC(pc);
BaselineScript *baselineScript = script->baselineScript();
#ifdef DEBUG
uint32_t expectedDepth = js_ReconstructStackDepth(cx, script,
resumeAfter ? GetNextPc(pc) : pc);
if (op != JSOP_FUNAPPLY || !iter.moreFrames() || resumeAfter) {
if (op == JSOP_FUNCALL) {
// For fun.call(this, ...); the reconstructStackDepth will
@@ -1002,17 +1003,17 @@ InitFromBailout(JSContext *cx, HandleScr
// Write previous frame pointer (saved earlier).
if (!builder.writePtr(prevFramePtr, "PrevFramePtr"))
return false;
prevFramePtr = builder.virtualPointerAtStackOffset(0);
// Write out actual arguments (and thisv), copied from unpacked stack of BaselineJS frame.
// Arguments are reversed on the BaselineJS frame's stack values.
- JS_ASSERT(isCall || IsGetterPC(pc) || IsSetterPC(pc));
+ JS_ASSERT(IsIonInlinablePC(pc));
unsigned actualArgc;
if (needToSaveArgs) {
// For FUNAPPLY or an accessor, the arguments are not on the stack anymore,
// but they are copied in a vector and are written here.
if (op == JSOP_FUNAPPLY)
actualArgc = blFrame->numActualArgs();
else
actualArgc = IsSetterPC(pc);
--- a/js/src/ion/BaselineCompiler.cpp
+++ b/js/src/ion/BaselineCompiler.cpp
@@ -1,18 +1,19 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineJIT.h"
+#include "ion/BaselineCompiler.h"
+
+#include "ion/BaselineHelpers.h"
#include "ion/BaselineIC.h"
-#include "ion/BaselineHelpers.h"
-#include "ion/BaselineCompiler.h"
+#include "ion/BaselineJIT.h"
#include "ion/FixedList.h"
#include "ion/IonLinker.h"
#include "ion/IonSpewer.h"
#include "ion/VMFunctions.h"
#include "vm/Interpreter-inl.h"
using namespace js;
@@ -2183,17 +2184,17 @@ BaselineCompiler::emit_JSOP_SETARG()
{
uint32_t arg = GET_SLOTNO(pc);
return emitFormalArgAccess(arg, /* get = */ false);
}
bool
BaselineCompiler::emitCall()
{
- JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE);
+ JS_ASSERT(IsCallPC(pc));
uint32_t argc = GET_ARGC(pc);
frame.syncStack(0);
masm.mov(Imm32(argc), R0.scratchReg());
// Call IC
ICCall_Fallback::Compiler stubCompiler(cx, /* isConstructing = */ JSOp(*pc) == JSOP_NEW);
--- a/js/src/ion/BaselineCompiler.h
+++ b/js/src/ion/BaselineCompiler.h
@@ -6,34 +6,32 @@
#ifndef ion_BaselineCompiler_h
#define ion_BaselineCompiler_h
#ifdef JS_ION
#include "jscntxt.h"
#include "jscompartment.h"
-#include "ion/IonCode.h"
#include "jsinfer.h"
-#include "vm/Interpreter.h"
-
-#include "ion/IonAllocPolicy.h"
#include "ion/BaselineJIT.h"
#include "ion/BaselineIC.h"
+#include "ion/BytecodeAnalysis.h"
#include "ion/FixedList.h"
-#include "ion/BytecodeAnalysis.h"
-
+#include "ion/IonAllocPolicy.h"
+#include "ion/IonCode.h"
#if defined(JS_CPU_X86)
# include "ion/x86/BaselineCompiler-x86.h"
#elif defined(JS_CPU_X64)
# include "ion/x64/BaselineCompiler-x64.h"
#else
# include "ion/arm/BaselineCompiler-arm.h"
#endif
+#include "vm/Interpreter.h"
namespace js {
namespace ion {
#define OPCODE_LIST(_) \
_(JSOP_NOP) \
_(JSOP_LABEL) \
_(JSOP_NOTEARG) \
--- a/js/src/ion/BaselineFrame-inl.h
+++ b/js/src/ion/BaselineFrame-inl.h
@@ -10,16 +10,17 @@
#ifdef JS_ION
#include "ion/BaselineFrame.h"
#include "jscntxt.h"
#include "jscompartment.h"
#include "ion/IonFrames.h"
+
#include "vm/ScopeObject-inl.h"
namespace js {
namespace ion {
inline void
BaselineFrame::pushOnScopeChain(ScopeObject &scope)
{
--- a/js/src/ion/BaselineFrame.cpp
+++ b/js/src/ion/BaselineFrame.cpp
@@ -1,23 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineFrame.h"
+#include "ion/BaselineFrame-inl.h"
+
#include "ion/BaselineIC.h"
#include "ion/BaselineJIT.h"
#include "ion/Ion.h"
-
#include "vm/Debugger.h"
#include "vm/ScopeObject.h"
-#include "ion/BaselineFrame-inl.h"
#include "ion/IonFrames-inl.h"
#include "vm/Stack-inl.h"
using namespace js;
using namespace js::ion;
void
BaselineFrame::trace(JSTracer *trc)
--- a/js/src/ion/BaselineFrameInfo.cpp
+++ b/js/src/ion/BaselineFrameInfo.cpp
@@ -1,20 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineFrameInfo.h"
+
+#include "jsanalyze.h"
+
#include "ion/IonSpewer.h"
#include "ion/shared/BaselineCompiler-shared.h"
-#include "jsanalyze.h"
-
using namespace js;
using namespace js::ion;
bool
FrameInfo::init() {
// One slot is always needed for this/arguments type checks.
size_t nstack = Max(script->nslots - script->nfixed, 1);
if (!stack.init(nstack))
--- a/js/src/ion/BaselineFrameInfo.h
+++ b/js/src/ion/BaselineFrameInfo.h
@@ -7,22 +7,22 @@
#ifndef ion_BaselineFrameInfo_h
#define ion_BaselineFrameInfo_h
#ifdef JS_ION
#include "jscntxt.h"
#include "jscompartment.h"
+#include "ion/BaselineFrame.h"
#include "ion/BaselineJIT.h"
-#include "ion/BaselineFrame.h"
#include "ion/BaselineRegisters.h"
#include "ion/BytecodeAnalysis.h"
+#include "ion/FixedList.h"
#include "ion/IonMacroAssembler.h"
-#include "ion/FixedList.h"
namespace js {
namespace ion {
// FrameInfo overview.
//
// FrameInfo is used by the compiler to track values stored in the frame. This
// includes locals, arguments and stack values. Locals and arguments are always
--- a/js/src/ion/BaselineIC.cpp
+++ b/js/src/ion/BaselineIC.cpp
@@ -1,20 +1,20 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineJIT.h"
+#include "ion/BaselineIC.h"
#include "builtin/Eval.h"
#include "ion/BaselineCompiler.h"
#include "ion/BaselineHelpers.h"
-#include "ion/BaselineIC.h"
+#include "ion/BaselineJIT.h"
#include "ion/IonLinker.h"
#include "ion/IonSpewer.h"
#include "ion/VMFunctions.h"
#include "vm/Interpreter-inl.h"
namespace js {
namespace ion {
--- a/js/src/ion/BaselineIC.h
+++ b/js/src/ion/BaselineIC.h
@@ -9,21 +9,21 @@
#ifdef JS_ION
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsgc.h"
#include "jsopcode.h"
#include "jsproxy.h"
+
+#include "gc/Heap.h"
#include "ion/BaselineJIT.h"
#include "ion/BaselineRegisters.h"
-#include "gc/Heap.h"
-
namespace js {
namespace ion {
//
// Baseline Inline Caches are polymorphic caches that aggressively
// share their stub code.
//
// Every polymorphic site contains a linked list of stubs which are
--- a/js/src/ion/BaselineInspector.cpp
+++ b/js/src/ion/BaselineInspector.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineInspector.h"
+
#include "ion/BaselineIC.h"
-#include "ion/BaselineInspector.h"
using namespace js;
using namespace js::ion;
bool
SetElemICInspector::sawOOBDenseWrite() const
{
if (!icEntry_)
--- a/js/src/ion/BaselineInspector.h
+++ b/js/src/ion/BaselineInspector.h
@@ -7,18 +7,18 @@
#ifndef ion_BaselineInspector_h
#define ion_BaselineInspector_h
#ifdef JS_ION
#include "jscntxt.h"
#include "jscompartment.h"
+#include "ion/BaselineIC.h"
#include "ion/BaselineJIT.h"
-#include "ion/BaselineIC.h"
#include "ion/MIR.h"
namespace js {
namespace ion {
class BaselineInspector;
class ICInspector
--- a/js/src/ion/BaselineJIT.cpp
+++ b/js/src/ion/BaselineJIT.cpp
@@ -1,27 +1,28 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineJIT.h"
+
#include "mozilla/MemoryReporting.h"
#include "ion/BaselineCompiler.h"
#include "ion/BaselineIC.h"
-#include "ion/BaselineJIT.h"
#include "ion/CompileInfo.h"
#include "ion/IonSpewer.h"
-#include "ion/IonFrames-inl.h"
-
-#include "vm/Stack-inl.h"
#include "jsopcodeinlines.h"
+#include "ion/IonFrames-inl.h"
+#include "vm/Stack-inl.h"
+
using namespace js;
using namespace js::ion;
/* static */ PCMappingSlotInfo::SlotLocation
PCMappingSlotInfo::ToSlotLocation(const StackValue *stackVal)
{
if (stackVal->kind() == StackValue::Register) {
if (stackVal->reg() == R0)
--- a/js/src/ion/BaselineJIT.h
+++ b/js/src/ion/BaselineJIT.h
@@ -9,21 +9,20 @@
#ifdef JS_ION
#include "mozilla/MemoryReporting.h"
#include "jscntxt.h"
#include "jscompartment.h"
+#include "ds/LifoAlloc.h"
+#include "ion/Bailouts.h"
#include "ion/IonCode.h"
#include "ion/IonMacroAssembler.h"
-#include "ion/Bailouts.h"
-
-#include "ds/LifoAlloc.h"
namespace js {
namespace ion {
class StackValue;
class ICEntry;
class ICStub;
--- a/js/src/ion/BitSet.cpp
+++ b/js/src/ion/BitSet.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BitSet.h"
+
#include "jsutil.h"
-#include "ion/BitSet.h"
using namespace js;
using namespace js::ion;
BitSet *
BitSet::New(unsigned int max)
{
BitSet *result = new BitSet(max);
--- a/js/src/ion/BytecodeAnalysis.cpp
+++ b/js/src/ion/BytecodeAnalysis.cpp
@@ -1,16 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BytecodeAnalysis.h"
+
#include "jsopcode.h"
+
#include "jsopcodeinlines.h"
using namespace js;
using namespace js::ion;
BytecodeAnalysis::BytecodeAnalysis(JSScript *script)
: script_(script),
infos_()
--- a/js/src/ion/C1Spewer.cpp
+++ b/js/src/ion/C1Spewer.cpp
@@ -1,25 +1,26 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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/. */
#ifdef DEBUG
+#include "ion/C1Spewer.h"
+
#include <stdarg.h>
#include <time.h>
+#include "ion/Ion.h"
#include "ion/IonBuilder.h"
-#include "ion/Ion.h"
-#include "ion/C1Spewer.h"
+#include "ion/LinearScan.h"
+#include "ion/LIR.h"
#include "ion/MIRGraph.h"
-#include "ion/LIR.h"
-#include "ion/LinearScan.h"
using namespace js;
using namespace js::ion;
bool
C1Spewer::init(const char *path)
{
spewout_ = fopen(path, "w");
--- a/js/src/ion/CodeGenerator.cpp
+++ b/js/src/ion/CodeGenerator.cpp
@@ -1,35 +1,37 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/CodeGenerator.h"
+
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Util.h"
-#include "ion/PerfSpewer.h"
-#include "ion/CodeGenerator.h"
+#include "jsmath.h"
+#include "jsnum.h"
+
+#include "builtin/Eval.h"
+#include "gc/Nursery.h"
+#include "ion/ExecutionModeInlines.h"
#include "ion/IonLinker.h"
#include "ion/IonSpewer.h"
#include "ion/MIRGenerator.h"
-#include "ion/shared/CodeGenerator-shared-inl.h"
#include "ion/MoveEmitter.h"
-#include "jsnum.h"
-#include "jsmath.h"
#include "ion/ParallelFunctions.h"
-#include "ion/ExecutionModeInlines.h"
-#include "builtin/Eval.h"
-#include "gc/Nursery.h"
+#include "ion/ParallelSafetyAnalysis.h"
+#include "ion/PerfSpewer.h"
#include "vm/ForkJoin.h"
-#include "ion/ParallelSafetyAnalysis.h"
-
+
+#include "ion/shared/CodeGenerator-shared-inl.h"
#include "vm/Interpreter-inl.h"
using namespace js;
using namespace js::ion;
using mozilla::DebugOnly;
using mozilla::Maybe;
--- a/js/src/ion/CodeGenerator.h
+++ b/js/src/ion/CodeGenerator.h
@@ -2,16 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_CodeGenerator_h
#define ion_CodeGenerator_h
+#include "ion/PerfSpewer.h"
+
#if defined(JS_CPU_X86)
# include "ion/x86/CodeGenerator-x86.h"
#elif defined(JS_CPU_X64)
# include "ion/x64/CodeGenerator-x64.h"
#elif defined(JS_CPU_ARM)
# include "ion/arm/CodeGenerator-arm.h"
#else
#error "CPU Not Supported"
--- a/js/src/ion/CompactBuffer.h
+++ b/js/src/ion/CompactBuffer.h
@@ -2,19 +2,20 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_Compactbuffer_h
#define ion_Compactbuffer_h
+#include "jsalloc.h"
+
+#include "ion/IonTypes.h"
#include "js/Vector.h"
-#include "jsalloc.h"
-#include "ion/IonTypes.h"
namespace js {
namespace ion {
class CompactBufferWriter;
// CompactBuffers are byte streams designed for compressable integers. It has
// helper functions for writing bytes, fixed-size integers, and variable-sized
--- a/js/src/ion/CompileInfo-inl.h
+++ b/js/src/ion/CompileInfo-inl.h
@@ -3,16 +3,17 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_CompileInfo_inl_h
#define ion_CompileInfo_inl_h
#include "ion/CompileInfo.h"
+
#include "jsscriptinlines.h"
using namespace js;
using namespace ion;
inline RegExpObject *
CompileInfo::getRegExp(jsbytecode *pc) const
{
--- a/js/src/ion/CompileInfo.h
+++ b/js/src/ion/CompileInfo.h
@@ -2,16 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_CompileInfo_h
#define ion_CompileInfo_h
+#include "jsfun.h"
+
#include "ion/Registers.h"
namespace js {
namespace ion {
inline unsigned
StartArgSlot(JSScript *script, JSFunction *fun)
{
--- a/js/src/ion/CompilerRoot.h
+++ b/js/src/ion/CompilerRoot.h
@@ -6,16 +6,18 @@
#ifndef ion_CompilerRoot_h
#define ion_CompilerRoot_h
#ifdef JS_ION
#include "jscntxt.h"
+#include "ion/Ion.h"
+#include "ion/IonAllocPolicy.h"
#include "js/RootingAPI.h"
namespace js {
namespace ion {
// Roots a read-only GCThing for the lifetime of a single compilation.
// Each root is maintained in a linked list that is walked over during tracing.
// The CompilerRoot must be heap-allocated and may not go out of scope.
--- a/js/src/ion/EdgeCaseAnalysis.cpp
+++ b/js/src/ion/EdgeCaseAnalysis.cpp
@@ -1,20 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/EdgeCaseAnalysis.h"
+
#include <stdio.h>
#include "ion/Ion.h"
#include "ion/IonBuilder.h"
#include "ion/IonSpewer.h"
-#include "ion/EdgeCaseAnalysis.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
using namespace js;
using namespace js::ion;
EdgeCaseAnalysis::EdgeCaseAnalysis(MIRGenerator *mir, MIRGraph &graph)
: mir(mir), graph(graph)
--- a/js/src/ion/EdgeCaseAnalysis.h
+++ b/js/src/ion/EdgeCaseAnalysis.h
@@ -2,16 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_EdgeCaseAnalysis_h
#define ion_EdgeCaseAnalysis_h
+#include "ion/MIRGenerator.h"
+
namespace js {
namespace ion {
class MIRGraph;
class EdgeCaseAnalysis
{
MIRGenerator *mir;
--- a/js/src/ion/ExecutionModeInlines.h
+++ b/js/src/ion/ExecutionModeInlines.h
@@ -4,16 +4,18 @@
* 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 ion_ExecutionModeInlines_h
#define ion_ExecutionModeInlines_h
#ifdef JS_ION
+#include "ion/CompileInfo.h"
+
namespace js {
namespace ion {
static inline bool
HasIonScript(JSScript *script, ExecutionMode cmode)
{
switch (cmode) {
case SequentialExecution: return script->hasIonScript();
--- a/js/src/ion/FixedList.h
+++ b/js/src/ion/FixedList.h
@@ -2,16 +2,21 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_FixedList_h
#define ion_FixedList_h
+#include <stddef.h>
+
+#include "ion/Ion.h"
+#include "ion/IonAllocPolicy.h"
+
namespace js {
namespace ion {
// List of a fixed length, but the length is unknown until runtime.
template <typename T>
class FixedList
{
size_t length_;
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -1,66 +1,66 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/Ion.h"
+
#include "mozilla/MemoryReporting.h"
-#include "ion/BaselineJIT.h"
+#include "jscompartment.h"
+#include "jsworkers.h"
+#if JS_TRACE_LOGGING
+#include "TraceLogging.h"
+#endif
+
+#include "gc/Marking.h"
+#include "ion/AliasAnalysis.h"
+#include "ion/AsmJS.h"
+#include "ion/AsmJSModule.h"
+#include "ion/BacktrackingAllocator.h"
#include "ion/BaselineCompiler.h"
#include "ion/BaselineInspector.h"
-#include "ion/Ion.h"
+#include "ion/BaselineJIT.h"
+#include "ion/CodeGenerator.h"
+#include "ion/CompilerRoot.h"
+#include "ion/EdgeCaseAnalysis.h"
+#include "ion/EffectiveAddressAnalysis.h"
+#include "ion/ExecutionModeInlines.h"
#include "ion/IonAnalysis.h"
#include "ion/IonBuilder.h"
+#include "ion/IonCompartment.h"
#include "ion/IonLinker.h"
#include "ion/IonSpewer.h"
+#include "ion/LICM.h"
+#include "ion/LinearScan.h"
#include "ion/LIR.h"
-#include "ion/AliasAnalysis.h"
-#include "ion/LICM.h"
-#include "ion/ValueNumbering.h"
-#include "ion/EdgeCaseAnalysis.h"
-#include "ion/RangeAnalysis.h"
-#include "ion/LinearScan.h"
#include "ion/ParallelSafetyAnalysis.h"
-#include "jscompartment.h"
-#include "vm/ThreadPool.h"
-#include "vm/ForkJoin.h"
-#include "ion/IonCompartment.h"
#include "ion/PerfSpewer.h"
-#include "ion/CodeGenerator.h"
-#include "jsworkers.h"
-#include "ion/BacktrackingAllocator.h"
+#include "ion/RangeAnalysis.h"
#include "ion/StupidAllocator.h"
#include "ion/UnreachableCodeElimination.h"
-#include "ion/EffectiveAddressAnalysis.h"
-
+#include "ion/ValueNumbering.h"
#if defined(JS_CPU_X86)
# include "ion/x86/Lowering-x86.h"
#elif defined(JS_CPU_X64)
# include "ion/x64/Lowering-x64.h"
#elif defined(JS_CPU_ARM)
# include "ion/arm/Lowering-arm.h"
#endif
-#include "gc/Marking.h"
+#include "vm/ForkJoin.h"
+#include "vm/ThreadPool.h"
#include "jscompartmentinlines.h"
#include "jsgcinlines.h"
#include "jsinferinlines.h"
#include "vm/Stack-inl.h"
-#include "ion/CompilerRoot.h"
-#include "ion/ExecutionModeInlines.h"
-#include "ion/AsmJS.h"
-#include "ion/AsmJSModule.h"
-
-#if JS_TRACE_LOGGING
-#include "TraceLogging.h"
-#endif
using namespace js;
using namespace js::ion;
// Global variables.
IonOptions ion::js_IonOptions;
// Assert that IonCode is gc::Cell aligned.
--- a/js/src/ion/Ion.h
+++ b/js/src/ion/Ion.h
@@ -8,20 +8,20 @@
#define ion_Ion_h
#ifdef JS_ION
#include "mozilla/MemoryReporting.h"
#include "jscntxt.h"
#include "jscompartment.h"
-#include "ion/IonCode.h"
-#include "ion/CompileInfo.h"
#include "jsinfer.h"
+#include "ion/CompileInfo.h"
+#include "ion/IonCode.h"
#include "vm/Interpreter.h"
namespace js {
namespace ion {
class TempAllocator;
// Possible register allocators which may be used.
@@ -341,16 +341,24 @@ void FinishOffThreadBuilder(IonBuilder *
static inline bool
IsEnabled(JSContext *cx)
{
return cx->hasOption(JSOPTION_ION) &&
cx->hasOption(JSOPTION_BASELINE) &&
cx->typeInferenceEnabled();
}
+inline bool
+IsIonInlinablePC(jsbytecode *pc) {
+ // CALL, FUNCALL, FUNAPPLY, EVAL, NEW (Normal Callsites)
+ // GETPROP, CALLPROP, and LENGTH. (Inlined Getters)
+ // SETPROP, SETNAME, SETGNAME (Inlined Setters)
+ return IsCallPC(pc) || IsGetterPC(pc) || IsSetterPC(pc);
+}
+
void ForbidCompilation(JSContext *cx, JSScript *script);
void ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode);
uint32_t UsesBeforeIonRecompile(JSScript *script, jsbytecode *pc);
void PurgeCaches(JSScript *script, JS::Zone *zone);
size_t SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf);
void DestroyIonScripts(FreeOp *fop, JSScript *script);
void TraceIonScripts(JSTracer* trc, JSScript *script);
--- a/js/src/ion/IonAllocPolicy.h
+++ b/js/src/ion/IonAllocPolicy.h
@@ -5,20 +5,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_IonAllocPolicy_h
#define ion_IonAllocPolicy_h
#include "mozilla/GuardObjects.h"
#include "jscntxt.h"
+
#include "ds/LifoAlloc.h"
-
+#include "ion/InlineList.h"
#include "ion/Ion.h"
-#include "ion/InlineList.h"
namespace js {
namespace ion {
class TempAllocator
{
LifoAllocScope lifoScope_;
--- a/js/src/ion/IonAnalysis.cpp
+++ b/js/src/ion/IonAnalysis.cpp
@@ -1,21 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/IonAnalysis.h"
+
#include "jsanalyze.h"
+#include "ion/Ion.h"
#include "ion/IonBuilder.h"
+#include "ion/LIR.h"
#include "ion/MIRGraph.h"
-#include "ion/Ion.h"
-#include "ion/IonAnalysis.h"
-#include "ion/LIR.h"
using namespace js;
using namespace js::ion;
// A critical edge is an edge which is neither its successor's only predecessor
// nor its predecessor's only successor. Critical edges must be split to
// prevent copy-insertion and code motion from affecting other edges.
bool
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -7,29 +7,28 @@
#include "ion/IonBuilder.h"
#include "mozilla/DebugOnly.h"
#include "builtin/Eval.h"
#include "frontend/SourceNotes.h"
#include "ion/BaselineFrame.h"
#include "ion/BaselineInspector.h"
+#include "ion/ExecutionModeInlines.h"
#include "ion/Ion.h"
#include "ion/IonAnalysis.h"
-#include "ion/IonAnalysis.h"
#include "ion/IonSpewer.h"
#include "ion/Lowering.h"
#include "ion/MIRGraph.h"
#include "jsinferinlines.h"
#include "jsobjinlines.h"
#include "jsscriptinlines.h"
#include "ion/CompileInfo-inl.h"
-#include "ion/ExecutionModeInlines.h"
using namespace js;
using namespace js::ion;
using mozilla::DebugOnly;
IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
BaselineInspector *inspector, CompileInfo *info, BaselineFrame *baselineFrame,
@@ -3424,17 +3423,17 @@ class AutoAccumulateExits
graph_.setExitAccumulator(prev_);
}
};
bool
IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
{
JS_ASSERT(target->isInterpreted());
- JS_ASSERT(types::IsInlinableCall(pc));
+ JS_ASSERT(IsIonInlinablePC(pc));
// Remove any MPassArgs.
if (callInfo.isWrapped())
callInfo.unwrapArgs();
// Ensure sufficient space in the slots: needed for inlining from FUNAPPLY.
uint32_t depth = current->stackDepth() + callInfo.numFormals();
if (depth > current->nslots()) {
@@ -4090,17 +4089,17 @@ IonBuilder::inlineTypeObjectFallback(Cal
}
bool
IonBuilder::inlineCalls(CallInfo &callInfo, AutoObjectVector &targets,
AutoObjectVector &originals, Vector<bool> &choiceSet,
MGetPropertyCache *maybeCache)
{
// Only handle polymorphic inlining.
- JS_ASSERT(types::IsInlinableCall(pc));
+ JS_ASSERT(IsIonInlinablePC(pc));
JS_ASSERT(choiceSet.length() == targets.length());
JS_ASSERT_IF(!maybeCache, targets.length() >= 2);
JS_ASSERT_IF(maybeCache, targets.length() >= 1);
MBasicBlock *dispatchBlock = current;
// Unwrap the arguments.
JS_ASSERT(callInfo.isWrapped());
--- a/js/src/ion/IonCaches.cpp
+++ b/js/src/ion/IonCaches.cpp
@@ -1,24 +1,24 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/IonCaches.h"
+
#include "mozilla/DebugOnly.h"
-#include "ion/PerfSpewer.h"
#include "ion/CodeGenerator.h"
#include "ion/Ion.h"
-#include "ion/IonCaches.h"
#include "ion/IonLinker.h"
#include "ion/IonSpewer.h"
+#include "ion/PerfSpewer.h"
#include "ion/VMFunctions.h"
-
#include "vm/Shape.h"
#include "vm/Interpreter-inl.h"
using namespace js;
using namespace js::ion;
using mozilla::DebugOnly;
--- a/js/src/ion/IonCaches.h
+++ b/js/src/ion/IonCaches.h
@@ -4,17 +4,20 @@
* 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 ion_IonCaches_h
#define ion_IonCaches_h
#include "ion/IonCode.h"
#include "ion/Registers.h"
-
+#include "ion/shared/Assembler-shared.h"
+#ifdef JS_CPU_ARM
+# include "ion/arm/Assembler-arm.h"
+#endif
#include "vm/ForkJoin.h"
class JSFunction;
class JSScript;
namespace js {
class TypedArrayObject;
--- a/js/src/ion/IonCode.h
+++ b/js/src/ion/IonCode.h
@@ -5,22 +5,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_IonCode_h
#define ion_IonCode_h
#include "mozilla/MemoryReporting.h"
#include "mozilla/PodOperations.h"
-#include "ion/IonTypes.h"
-#include "ion/AsmJS.h"
+#include "jsinfer.h"
+
#include "gc/Heap.h"
-
-// For RecompileInfo
-#include "jsinfer.h"
+#include "ion/AsmJS.h"
+#include "ion/IonTypes.h"
namespace JSC {
class ExecutablePool;
}
class JSScript;
namespace js {
--- a/js/src/ion/IonCompartment.h
+++ b/js/src/ion/IonCompartment.h
@@ -6,22 +6,23 @@
#ifndef ion_IonCompartment_h
#define ion_IonCompartment_h
#ifdef JS_ION
#include "mozilla/MemoryReporting.h"
+#include "jsweakcache.h"
+
+#include "ion/CompileInfo.h"
#include "ion/IonCode.h"
-#include "jsweakcache.h"
+#include "ion/IonFrames.h"
#include "js/Value.h"
#include "vm/Stack.h"
-#include "ion/IonFrames.h"
-#include "ion/CompileInfo.h"
namespace js {
namespace ion {
class FrameSizeClass;
enum EnterJitType {
EnterJitBaseline = 0,
--- a/js/src/ion/IonFrameIterator-inl.h
+++ b/js/src/ion/IonFrameIterator-inl.h
@@ -4,19 +4,20 @@
* 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 ion_IonFrameIterator_inl_h
#define ion_IonFrameIterator_inl_h
#ifdef JS_ION
+#include "ion/IonFrameIterator.h"
+
+#include "ion/Bailouts.h"
#include "ion/BaselineFrame.h"
-#include "ion/IonFrameIterator.h"
-#include "ion/Bailouts.h"
namespace js {
namespace ion {
template <AllowGC allowGC>
inline
InlineFrameIteratorMaybeGC<allowGC>::InlineFrameIteratorMaybeGC(
JSContext *cx, const IonBailoutIterator *iter)
--- a/js/src/ion/IonFrameIterator.h
+++ b/js/src/ion/IonFrameIterator.h
@@ -4,23 +4,22 @@
* 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 ion_IonFrameIterator_h
#define ion_IonFrameIterator_h
#ifdef JS_ION
+#include "jsscript.h"
#include "jstypes.h"
+
#include "ion/IonCode.h"
#include "ion/SnapshotReader.h"
-class JSFunction;
-class JSScript;
-
namespace js {
class ActivationIterator;
};
namespace js {
namespace ion {
enum FrameType
--- a/js/src/ion/IonFrames-inl.h
+++ b/js/src/ion/IonFrames-inl.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_IonFrames_inl_h
#define ion_IonFrames_inl_h
#ifdef JS_ION
#include "ion/IonFrames.h"
+
#include "ion/IonFrameIterator.h"
#include "ion/LIR.h"
#include "ion/IonFrameIterator-inl.h"
namespace js {
namespace ion {
--- a/js/src/ion/IonFrames.cpp
+++ b/js/src/ion/IonFrames.cpp
@@ -1,36 +1,36 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/IonFrames.h"
+#include "ion/IonFrames-inl.h"
+#include "jsfun.h"
#include "jsobj.h"
#include "jsscript.h"
-#include "jsfun.h"
+
#include "gc/Marking.h"
#include "ion/BaselineFrame.h"
#include "ion/BaselineIC.h"
#include "ion/BaselineJIT.h"
#include "ion/Ion.h"
#include "ion/IonCompartment.h"
#include "ion/IonMacroAssembler.h"
#include "ion/IonSpewer.h"
#include "ion/PcScriptCache.h"
#include "ion/Safepoints.h"
#include "ion/SnapshotReader.h"
#include "ion/VMFunctions.h"
#include "jsfuninlines.h"
#include "ion/IonFrameIterator-inl.h"
-#include "ion/IonFrames-inl.h"
#include "vm/Probes-inl.h"
namespace js {
namespace ion {
IonFrameIterator::IonFrameIterator(const ActivationIterator &activations)
: current_(activations.jitTop()),
type_(IonFrame_Exit),
@@ -1308,17 +1308,17 @@ InlineFrameIteratorMaybeGC<allowGC>::fin
#ifdef DEBUG
numActualArgs_ = 0xbadbad;
#endif
// This unfortunately is O(n*m), because we must skip over outer frames
// before reading inner ones.
unsigned remaining = start_.frameCount() - framesRead_ - 1;
for (unsigned i = 0; i < remaining; i++) {
- JS_ASSERT(js_CodeSpec[*pc_].format & JOF_INVOKE);
+ JS_ASSERT(IsIonInlinablePC(pc_));
// Recover the number of actual arguments from the script.
if (JSOp(*pc_) != JSOP_FUNAPPLY)
numActualArgs_ = GET_ARGC(pc_);
if (JSOp(*pc_) == JSOP_FUNCALL) {
JS_ASSERT(GET_ARGC(pc_) > 0);
numActualArgs_ = GET_ARGC(pc_) - 1;
} else if (IsGetterPC(pc_)) {
@@ -1389,17 +1389,17 @@ InlineFrameIteratorMaybeGC<allowGC>::isC
InlineFrameIteratorMaybeGC<allowGC> parent(GetIonContext()->cx, this);
++parent;
// Inlined Getters and Setters are never constructing.
if (IsGetterPC(parent.pc()) || IsSetterPC(parent.pc()))
return false;
// In the case of a JS frame, look up the pc from the snapshot.
- JS_ASSERT(js_CodeSpec[*parent.pc()].format & JOF_INVOKE);
+ JS_ASSERT(IsCallPC(parent.pc()));
return (JSOp)*parent.pc() == JSOP_NEW;
}
return frame_->isConstructing();
}
template bool InlineFrameIteratorMaybeGC<NoGC>::isConstructing() const;
template bool InlineFrameIteratorMaybeGC<CanGC>::isConstructing() const;
@@ -1417,30 +1417,30 @@ IonFrameIterator::isConstructing() const
if (parent.isOptimizedJS()) {
// In the case of a JS frame, look up the pc from the snapshot.
InlineFrameIterator inlinedParent(GetIonContext()->cx, &parent);
//Inlined Getters and Setters are never constructing.
if (IsGetterPC(inlinedParent.pc()) || IsSetterPC(inlinedParent.pc()))
return false;
- JS_ASSERT(js_CodeSpec[*inlinedParent.pc()].format & JOF_INVOKE);
+ JS_ASSERT(IsCallPC(inlinedParent.pc()));
return (JSOp)*inlinedParent.pc() == JSOP_NEW;
}
if (parent.isBaselineJS()) {
jsbytecode *pc;
parent.baselineScriptAndPc(NULL, &pc);
//Inlined Getters and Setters are never constructing.
if (IsGetterPC(pc) || IsSetterPC(pc))
return false;
- JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE);
+ JS_ASSERT(IsCallPC(pc));
return JSOp(*pc) == JSOP_NEW;
}
JS_ASSERT(parent.done());
return activation_->firstFrameIsConstructing();
}
--- a/js/src/ion/IonFrames.h
+++ b/js/src/ion/IonFrames.h
@@ -10,19 +10,20 @@
#ifdef JS_ION
#include "mozilla/DebugOnly.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jstypes.h"
#include "jsutil.h"
-#include "ion/Registers.h"
+
#include "ion/IonCode.h"
#include "ion/IonFrameIterator.h"
+#include "ion/Registers.h"
class JSFunction;
class JSScript;
namespace js {
namespace ion {
typedef void * CalleeToken;
--- a/js/src/ion/IonLinker.h
+++ b/js/src/ion/IonLinker.h
@@ -5,19 +5,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_IonLinker_h
#define ion_IonLinker_h
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsgc.h"
+
+#include "assembler/jit/ExecutableAllocator.h"
#include "ion/IonCode.h"
#include "ion/IonCompartment.h"
-#include "assembler/jit/ExecutableAllocator.h"
#include "ion/IonMacroAssembler.h"
namespace js {
namespace ion {
class Linker
{
MacroAssembler &masm;
--- a/js/src/ion/IonMacroAssembler.cpp
+++ b/js/src/ion/IonMacroAssembler.cpp
@@ -9,17 +9,16 @@
#include "jsinfer.h"
#include "ion/AsmJS.h"
#include "ion/Bailouts.h"
#include "ion/BaselineFrame.h"
#include "ion/BaselineIC.h"
#include "ion/BaselineJIT.h"
#include "ion/BaselineRegisters.h"
-#include "ion/IonMacroAssembler.h"
#include "ion/MIR.h"
#include "js/RootingAPI.h"
#include "vm/ForkJoin.h"
#include "jsgcinlines.h"
#include "jsinferinlines.h"
#include "vm/Shape-inl.h"
--- a/js/src/ion/IonSpewer.cpp
+++ b/js/src/ion/IonSpewer.cpp
@@ -1,18 +1,19 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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/. */
#ifdef DEBUG
+#include "ion/IonSpewer.h"
+
#include "ion/Ion.h"
-#include "ion/IonSpewer.h"
#ifndef ION_SPEW_DIR
# if defined(_WIN32)
# define ION_SPEW_DIR ""
# elif defined(__ANDROID__)
# define ION_SPEW_DIR "/data/local/tmp/"
# else
# define ION_SPEW_DIR "/tmp/"
--- a/js/src/ion/IonSpewer.h
+++ b/js/src/ion/IonSpewer.h
@@ -2,19 +2,19 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_IonSpewer_h
#define ion_IonSpewer_h
-#include <stdarg.h>
+#include "mozilla/DebugOnly.h"
-#include "mozilla/DebugOnly.h"
+#include <stdarg.h>
#include "ion/C1Spewer.h"
#include "ion/JSONSpewer.h"
namespace js {
namespace ion {
// New channels may be added below.
--- a/js/src/ion/IonTypes.h
+++ b/js/src/ion/IonTypes.h
@@ -2,18 +2,19 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_IonTypes_h
#define ion_IonTypes_h
+#include "jstypes.h"
+
#include "js/Value.h"
-#include "jstypes.h"
namespace js {
namespace ion {
typedef uint32_t SnapshotOffset;
typedef uint32_t BailoutId;
static const SnapshotOffset INVALID_SNAPSHOT_OFFSET = uint32_t(-1);
--- a/js/src/ion/JSONSpewer.cpp
+++ b/js/src/ion/JSONSpewer.cpp
@@ -1,21 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/JSONSpewer.h"
+
#include <stdarg.h>
-#include "ion/JSONSpewer.h"
+#include "ion/LinearScan.h"
#include "ion/LIR.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/LinearScan.h"
#include "ion/RangeAnalysis.h"
using namespace js;
using namespace js::ion;
JSONSpewer::~JSONSpewer()
{
if (fp_)
--- a/js/src/ion/LICM.cpp
+++ b/js/src/ion/LICM.cpp
@@ -1,20 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/LICM.h"
+
#include <stdio.h>
#include "ion/Ion.h"
#include "ion/IonBuilder.h"
#include "ion/IonSpewer.h"
-#include "ion/LICM.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
using namespace js;
using namespace js::ion;
namespace {
--- a/js/src/ion/LICM.h
+++ b/js/src/ion/LICM.h
@@ -6,16 +6,17 @@
#ifndef ion_LICM_h
#define ion_LICM_h
#include "ion/IonAllocPolicy.h"
#include "ion/IonAnalysis.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
+
// This file represents the Loop Invariant Code Motion optimization pass
namespace js {
namespace ion {
class LICM
{
MIRGenerator *mir;
--- a/js/src/ion/LIR.cpp
+++ b/js/src/ion/LIR.cpp
@@ -1,20 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/LIR.h"
+
#include "jsprf.h"
+#include "ion/IonSpewer.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/LIR.h"
-#include "ion/IonSpewer.h"
#include "ion/shared/CodeGenerator-shared.h"
using namespace js;
using namespace js::ion;
LIRGraph::LIRGraph(MIRGraph *mir)
: numVirtualRegisters_(0),
numInstructions_(1), // First id is 1.
--- a/js/src/ion/LIR.h
+++ b/js/src/ion/LIR.h
@@ -9,25 +9,25 @@
// This file declares the core data structures for LIR: storage allocations for
// inputs and outputs, as well as the interface instructions must conform to.
#include "mozilla/Array.h"
#include "jscntxt.h"
-#include "ion/IonAllocPolicy.h"
+#include "ion/Bailouts.h"
#include "ion/InlineList.h"
+#include "ion/IonAllocPolicy.h"
#include "ion/LOpcodes.h"
-#include "ion/Registers.h"
+#include "ion/MIRGraph.h"
#include "ion/MIR.h"
-#include "ion/MIRGraph.h"
+#include "ion/Registers.h"
+#include "ion/Safepoints.h"
#include "ion/shared/Assembler-shared.h"
-#include "ion/Safepoints.h"
-#include "ion/Bailouts.h"
#include "ion/VMFunctions.h"
namespace js {
namespace ion {
class LUse;
class LGeneralReg;
class LFloatReg;
--- a/js/src/ion/LinearScan.cpp
+++ b/js/src/ion/LinearScan.cpp
@@ -1,20 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 <limits.h>
+#include "ion/LinearScan.h"
#include "mozilla/DebugOnly.h"
+#include <limits.h>
+
#include "ion/BitSet.h"
-#include "ion/LinearScan.h"
#include "ion/IonBuilder.h"
#include "ion/IonSpewer.h"
using namespace js;
using namespace js::ion;
using mozilla::DebugOnly;
--- a/js/src/ion/LinearScan.h
+++ b/js/src/ion/LinearScan.h
@@ -2,19 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_LinearScan_h
#define ion_LinearScan_h
+#include "ion/BitSet.h"
#include "ion/LiveRangeAllocator.h"
-#include "ion/BitSet.h"
-
#include "js/Vector.h"
namespace js {
namespace ion {
class LinearScanVirtualRegister : public VirtualRegister
{
private:
--- a/js/src/ion/LiveRangeAllocator.cpp
+++ b/js/src/ion/LiveRangeAllocator.cpp
@@ -1,17 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "mozilla/DebugOnly.h"
+#include "ion/LiveRangeAllocator.h"
-#include "ion/LiveRangeAllocator.h"
+#include "mozilla/DebugOnly.h"
#include "ion/BacktrackingAllocator.h"
#include "ion/LinearScan.h"
using namespace js;
using namespace js::ion;
using mozilla::DebugOnly;
--- a/js/src/ion/Lowering.cpp
+++ b/js/src/ion/Lowering.cpp
@@ -1,28 +1,32 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/LIR.h"
#include "ion/Lowering.h"
-#include "ion/MIR.h"
-#include "ion/MIRGraph.h"
-#include "ion/IonSpewer.h"
-#include "ion/RangeAnalysis.h"
+
+#include "mozilla/DebugOnly.h"
+
#include "jsanalyze.h"
#include "jsbool.h"
#include "jsnum.h"
-#include "ion/shared/Lowering-shared-inl.h"
-#include "mozilla/DebugOnly.h"
+
+#include "ion/IonSpewer.h"
+#include "ion/LIR.h"
+#include "ion/MIR.h"
+#include "ion/MIRGraph.h"
+#include "ion/RangeAnalysis.h"
#include "jsinferinlines.h"
+#include "ion/shared/Lowering-shared-inl.h"
+
using namespace js;
using namespace ion;
bool
LIRGenerator::visitParameter(MParameter *param)
{
ptrdiff_t offset;
if (param->index() == MParameter::THIS_SLOT)
--- a/js/src/ion/Lowering.h
+++ b/js/src/ion/Lowering.h
@@ -8,17 +8,16 @@
#define ion_Lowering_h
// This file declares the structures that are used for attaching LIR to a
// MIRGraph.
#include "ion/IonAllocPolicy.h"
#include "ion/LIR.h"
#include "ion/MOpcodes.h"
-
#if defined(JS_CPU_X86)
# include "ion/x86/Lowering-x86.h"
#elif defined(JS_CPU_X64)
# include "ion/x64/Lowering-x64.h"
#elif defined(JS_CPU_ARM)
# include "ion/arm/Lowering-arm.h"
#else
# error "CPU!"
--- a/js/src/ion/MCallOptimize.cpp
+++ b/js/src/ion/MCallOptimize.cpp
@@ -1,22 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "jslibmath.h"
#include "jsmath.h"
+
#include "builtin/ParallelArray.h"
#include "builtin/TestingFunctions.h"
-
+#include "ion/IonBuilder.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/IonBuilder.h"
#include "jsscriptinlines.h"
#include "vm/StringObject-inl.h"
namespace js {
namespace ion {
--- a/js/src/ion/MIR.cpp
+++ b/js/src/ion/MIR.cpp
@@ -3,25 +3,26 @@
* 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 "ion/MIR.h"
#include "mozilla/FloatingPoint.h"
+#include "jsnum.h"
+#include "jsstr.h"
+
#include "ion/BaselineInspector.h"
+#include "ion/EdgeCaseAnalysis.h"
#include "ion/IonBuilder.h"
+#include "ion/IonSpewer.h"
#include "ion/LICM.h" // For LinearSum
#include "ion/MIRGraph.h"
-#include "ion/EdgeCaseAnalysis.h"
#include "ion/RangeAnalysis.h"
-#include "ion/IonSpewer.h"
-#include "jsnum.h"
-#include "jsstr.h"
#include "jsatominlines.h"
#include "jsinferinlines.h"
#include "vm/Shape-inl.h"
using namespace js;
using namespace js::ion;
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -13,24 +13,24 @@
#define ion_MIR_h
#include "mozilla/Array.h"
#include "jscntxt.h"
#include "jsinfer.h"
#include "jslibmath.h"
-#include "ion/TypePolicy.h"
+#include "ion/Bailouts.h"
+#include "ion/CompilerRoot.h"
+#include "ion/FixedList.h"
+#include "ion/InlineList.h"
#include "ion/IonAllocPolicy.h"
-#include "ion/InlineList.h"
+#include "ion/IonMacroAssembler.h"
#include "ion/MOpcodes.h"
-#include "ion/IonMacroAssembler.h"
-#include "ion/Bailouts.h"
-#include "ion/FixedList.h"
-#include "ion/CompilerRoot.h"
+#include "ion/TypePolicy.h"
#include "vm/ScopeObject.h"
namespace js {
class StringObject;
namespace ion {
--- a/js/src/ion/MIRGenerator.h
+++ b/js/src/ion/MIRGenerator.h
@@ -4,29 +4,29 @@
* 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 ion_MIRGenerator_h
#define ion_MIRGenerator_h
// This file declares the data structures used to build a control-flow graph
// containing MIR.
+
#include <stdarg.h>
#include "jscntxt.h"
#include "jscompartment.h"
+
+#include "ion/CompileInfo.h"
#include "ion/IonAllocPolicy.h"
#include "ion/IonCompartment.h"
-#include "ion/CompileInfo.h"
-#include "ion/RegisterSets.h"
-
#if defined(JS_ION_PERF)
# include "ion/PerfSpewer.h"
#endif
-
+#include "ion/RegisterSets.h"
namespace js {
namespace ion {
class MBasicBlock;
class MIRGraph;
class MStart;
--- a/js/src/ion/MIRGraph.cpp
+++ b/js/src/ion/MIRGraph.cpp
@@ -1,21 +1,23 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/MIRGraph.h"
+
#include "jsanalyze.h"
#include "ion/Ion.h"
+#include "ion/IonBuilder.h"
#include "ion/IonSpewer.h"
#include "ion/MIR.h"
-#include "ion/MIRGraph.h"
-#include "ion/IonBuilder.h"
+
#include "jsinferinlines.h"
using namespace js;
using namespace js::ion;
MIRGenerator::MIRGenerator(JSCompartment *compartment,
TempAllocator *temp, MIRGraph *graph, CompileInfo *info)
: compartment(compartment),
--- a/js/src/ion/MIRGraph.h
+++ b/js/src/ion/MIRGraph.h
@@ -5,19 +5,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_MIRGraph_h
#define ion_MIRGraph_h
// This file declares the data structures used to build a control-flow graph
// containing MIR.
+#include "ion/FixedList.h"
#include "ion/IonAllocPolicy.h"
+#include "ion/MIR.h"
#include "ion/MIRGenerator.h"
-#include "ion/FixedList.h"
namespace js {
namespace ion {
class MBasicBlock;
class MIRGraph;
class MStart;
--- a/js/src/ion/MoveResolver.h
+++ b/js/src/ion/MoveResolver.h
@@ -2,19 +2,19 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_MoveResolver_h
#define ion_MoveResolver_h
-#include "ion/Registers.h"
#include "ion/InlineList.h"
#include "ion/IonAllocPolicy.h"
+#include "ion/Registers.h"
namespace js {
namespace ion {
class MoveResolver
{
public:
// This is similar to Operand, but carries more information. We're also not
--- a/js/src/ion/ParallelFunctions.h
+++ b/js/src/ion/ParallelFunctions.h
@@ -2,19 +2,19 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_ParallelFunctions_h
#define ion_ParallelFunctions_h
-#include "vm/ThreadPool.h"
+#include "gc/Heap.h"
#include "vm/ForkJoin.h"
-#include "gc/Heap.h"
+#include "vm/ThreadPool.h"
namespace js {
namespace ion {
ForkJoinSlice *ForkJoinSlicePar();
JSObject *NewGCThingPar(gc::AllocKind allocKind);
bool IsThreadLocalObject(ForkJoinSlice *context, JSObject *object);
bool CheckOverRecursedPar(ForkJoinSlice *slice);
--- a/js/src/ion/ParallelSafetyAnalysis.cpp
+++ b/js/src/ion/ParallelSafetyAnalysis.cpp
@@ -1,23 +1,24 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/ParallelSafetyAnalysis.h"
+
#include <stdio.h>
#include "ion/Ion.h"
+#include "ion/IonAnalysis.h"
+#include "ion/IonSpewer.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/ParallelSafetyAnalysis.h"
-#include "ion/IonSpewer.h"
#include "ion/UnreachableCodeElimination.h"
-#include "ion/IonAnalysis.h"
#include "vm/Stack.h"
#include "jsinferinlines.h"
using namespace js;
using namespace ion;
using parallel::Spew;
--- a/js/src/ion/ParallelSafetyAnalysis.h
+++ b/js/src/ion/ParallelSafetyAnalysis.h
@@ -2,18 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_ParallelSafetyAnalysis_h
#define ion_ParallelSafetyAnalysis_h
+#include "ion/CompileInfo.h"
#include "ion/MIR.h"
-#include "ion/CompileInfo.h"
namespace js {
class StackFrame;
namespace ion {
class MIRGraph;
--- a/js/src/ion/PerfSpewer.cpp
+++ b/js/src/ion/PerfSpewer.cpp
@@ -1,25 +1,27 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/PerfSpewer.h"
+
#include <stdarg.h>
+
#if defined(__linux__)
# include <unistd.h>
#endif
-#include "ion/PerfSpewer.h"
#include "ion/IonSpewer.h"
+#include "ion/LinearScan.h"
#include "ion/LIR.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/LinearScan.h"
#include "ion/RangeAnalysis.h"
using namespace js;
using namespace js::ion;
#define PERF_MODE_NONE 1
#define PERF_MODE_FUNC 2
#define PERF_MODE_BLOCK 3
--- a/js/src/ion/PerfSpewer.h
+++ b/js/src/ion/PerfSpewer.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_PerfSpewer_h
#define ion_PerfSpewer_h
#include <stdio.h>
#include "jsscript.h"
+
#include "ion/IonMacroAssembler.h"
#include "js/RootingAPI.h"
class JSScript;
namespace js {
namespace ion {
--- a/js/src/ion/RangeAnalysis.cpp
+++ b/js/src/ion/RangeAnalysis.cpp
@@ -1,29 +1,29 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/RangeAnalysis.h"
+
#include "mozilla/MathAlgorithms.h"
#include <math.h>
#include <stdio.h>
#include "jsanalyze.h"
-#include "vm/NumericConversions.h"
-
#include "ion/Ion.h"
#include "ion/IonAnalysis.h"
+#include "ion/IonSpewer.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/RangeAnalysis.h"
-#include "ion/IonSpewer.h"
+#include "vm/NumericConversions.h"
using namespace js;
using namespace js::ion;
using mozilla::Abs;
using mozilla::CountLeadingZeroes32;
using mozilla::ExponentComponent;
using mozilla::IsInfinite;
--- a/js/src/ion/RangeAnalysis.h
+++ b/js/src/ion/RangeAnalysis.h
@@ -5,19 +5,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_RangeAnalysis_h
#define ion_RangeAnalysis_h
#include "mozilla/FloatingPoint.h"
#include "mozilla/MathAlgorithms.h"
-#include "ion/MIR.h"
#include "ion/CompileInfo.h"
#include "ion/IonAnalysis.h"
+#include "ion/MIR.h"
namespace js {
namespace ion {
class MBasicBlock;
class MIRGraph;
// An upper bound computed on the number of backedges a loop will take.
--- a/js/src/ion/RegisterAllocator.h
+++ b/js/src/ion/RegisterAllocator.h
@@ -4,22 +4,22 @@
* 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 ion_RegisterAllocator_h
#define ion_RegisterAllocator_h
#include "mozilla/Attributes.h"
+#include "ion/InlineList.h"
#include "ion/Ion.h"
+#include "ion/LIR.h"
+#include "ion/Lowering.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/InlineList.h"
-#include "ion/LIR.h"
-#include "ion/Lowering.h"
// Generic structures and functions for use by register allocators.
namespace js {
namespace ion {
// Structure for running a liveness analysis on a finished register allocation.
// This analysis can be used for two purposes:
--- a/js/src/ion/RegisterSets.h
+++ b/js/src/ion/RegisterSets.h
@@ -4,18 +4,18 @@
* 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 ion_RegisterSets_h
#define ion_RegisterSets_h
#include "mozilla/MathAlgorithms.h"
+#include "ion/IonAllocPolicy.h"
#include "ion/Registers.h"
-#include "ion/IonAllocPolicy.h"
namespace js {
namespace ion {
struct AnyRegister {
typedef uint32_t Code;
static const uint32_t Total = Registers::Total + FloatRegisters::Total;
--- a/js/src/ion/Registers.h
+++ b/js/src/ion/Registers.h
@@ -5,30 +5,30 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_Registers_h
#define ion_Registers_h
#include "mozilla/Array.h"
#include "jsutil.h"
+
+// ARM defines the RegisterID within Architecture-arm.h
+#if !defined(JS_CPU_ARM)
+#include "assembler/assembler/MacroAssembler.h"
+#endif
#include "ion/IonTypes.h"
#if defined(JS_CPU_X86)
# include "ion/x86/Architecture-x86.h"
#elif defined(JS_CPU_X64)
# include "ion/x64/Architecture-x64.h"
#elif defined(JS_CPU_ARM)
# include "ion/arm/Architecture-arm.h"
#endif
-// ARM defines the RegisterID within Architecture-arm.h
-#if !defined(JS_CPU_ARM)
-#include "assembler/assembler/MacroAssembler.h"
-#endif
-
namespace js {
namespace ion {
struct Register {
typedef Registers Codes;
typedef Codes::Code Code;
typedef js::ion::Registers::RegisterID RegisterID;
Code code_;
--- a/js/src/ion/Safepoints.h
+++ b/js/src/ion/Safepoints.h
@@ -2,20 +2,19 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_Safepoints_h
#define ion_Safepoints_h
-#include "ion/Registers.h"
+#include "ion/BitSet.h"
#include "ion/CompactBuffer.h"
-#include "ion/BitSet.h"
-
+#include "ion/Registers.h"
#include "ion/shared/Assembler-shared.h"
namespace js {
namespace ion {
struct SafepointNunboxEntry;
class LAllocation;
class LSafepoint;
--- a/js/src/ion/SnapshotReader.h
+++ b/js/src/ion/SnapshotReader.h
@@ -2,20 +2,20 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_SnapshotReader_h
#define ion_SnapshotReader_h
-#include "ion/IonTypes.h"
+#include "ion/CompactBuffer.h"
#include "ion/IonCode.h"
+#include "ion/IonTypes.h"
#include "ion/Registers.h"
-#include "ion/CompactBuffer.h"
namespace js {
namespace ion {
#ifdef TRACK_SNAPSHOTS
class LInstruction;
#endif
--- a/js/src/ion/SnapshotWriter.h
+++ b/js/src/ion/SnapshotWriter.h
@@ -2,21 +2,21 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_SnapshotWriter_h
#define ion_SnapshotWriter_h
+#include "ion/Bailouts.h"
+#include "ion/CompactBuffer.h"
#include "ion/Ion.h"
#include "ion/IonCode.h"
#include "ion/Registers.h"
-#include "ion/CompactBuffer.h"
-#include "ion/Bailouts.h"
namespace js {
namespace ion {
// Collects snapshots in a contiguous buffer, which is copied into IonScript
// memory after code generation.
class SnapshotWriter
{
--- a/js/src/ion/Snapshots.cpp
+++ b/js/src/ion/Snapshots.cpp
@@ -1,27 +1,27 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/MIRGenerator.h"
+#include "jsscript.h"
+
#include "ion/IonFrames.h"
-#include "jsscript.h"
#include "ion/IonLinker.h"
#include "ion/IonSpewer.h"
+#ifdef TRACK_SNAPSHOTS
+#include "ion/LIR.h"
+#include "ion/MIR.h"
+#endif
+#include "ion/MIRGenerator.h"
#include "ion/SnapshotReader.h"
#include "ion/SnapshotWriter.h"
-#ifdef TRACK_SNAPSHOTS
-#include "ion/MIR.h"
-#include "ion/LIR.h"
-#endif
-
using namespace js;
using namespace js::ion;
// Snapshot header:
//
// [vwu] bits (n-31]: frame count
// bits [0,n): bailout kind (n = BAILOUT_KIND_BITS)
//
--- a/js/src/ion/TypePolicy.cpp
+++ b/js/src/ion/TypePolicy.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/TypePolicy.h"
+
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
using namespace js;
using namespace js::ion;
MDefinition *
BoxInputsPolicy::boxAt(MInstruction *at, MDefinition *operand)
--- a/js/src/ion/UnreachableCodeElimination.cpp
+++ b/js/src/ion/UnreachableCodeElimination.cpp
@@ -1,17 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/UnreachableCodeElimination.h"
+
+#include "ion/AliasAnalysis.h"
#include "ion/IonAnalysis.h"
-#include "ion/AliasAnalysis.h"
#include "ion/ValueNumbering.h"
using namespace js;
using namespace ion;
bool
UnreachableCodeElimination::analyze()
{
--- a/js/src/ion/VMFunctions.cpp
+++ b/js/src/ion/VMFunctions.cpp
@@ -1,32 +1,31 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/VMFunctions.h"
+
+#include "builtin/ParallelArray.h"
+#include "frontend/BytecodeCompiler.h"
+#include "ion/BaselineIC.h"
#include "ion/Ion.h"
#include "ion/IonCompartment.h"
-#include "ion/BaselineFrame-inl.h"
-#include "ion/BaselineIC.h"
#include "ion/IonFrames.h"
-
#include "vm/ArrayObject.h"
#include "vm/Debugger.h"
#include "vm/Interpreter.h"
-#include "vm/StringObject-inl.h"
-
-#include "builtin/ParallelArray.h"
-
-#include "frontend/BytecodeCompiler.h"
#include "jsboolinlines.h"
+#include "ion/BaselineFrame-inl.h"
#include "vm/Interpreter-inl.h"
+#include "vm/StringObject-inl.h"
using namespace js;
using namespace js::ion;
namespace js {
namespace ion {
// Don't explicitly initialize, it's not guaranteed that this initializer will
--- a/js/src/ion/VMFunctions.h
+++ b/js/src/ion/VMFunctions.h
@@ -4,16 +4,20 @@
* 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 ion_VMFunctions_h
#define ion_VMFunctions_h
#include "jspubtd.h"
+#include "ion/CompileInfo.h"
+#include "ion/Ion.h"
+#include "ion/IonFrames.h"
+
namespace js {
class DeclEnvObject;
class ForkJoinSlice;
namespace ion {
enum DataType {
--- a/js/src/ion/ValueNumbering.cpp
+++ b/js/src/ion/ValueNumbering.cpp
@@ -1,19 +1,20 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/ValueNumbering.h"
+
+#include "ion/CompileInfo.h"
#include "ion/Ion.h"
#include "ion/IonBuilder.h"
#include "ion/IonSpewer.h"
-#include "ion/CompileInfo.h"
-#include "ion/ValueNumbering.h"
using namespace js;
using namespace js::ion;
ValueNumberer::ValueNumberer(MIRGenerator *mir, MIRGraph &graph, bool optimistic)
: mir(mir),
graph_(graph),
pessimisticPass_(!optimistic),
--- a/js/src/ion/ValueNumbering.h
+++ b/js/src/ion/ValueNumbering.h
@@ -2,19 +2,19 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_ValueNumbering_h
#define ion_ValueNumbering_h
+#include "ion/CompileInfo.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/CompileInfo.h"
namespace js {
namespace ion {
class ValueNumberer
{
protected:
struct ValueHasher
--- a/js/src/ion/shared/Assembler-shared.h
+++ b/js/src/ion/shared/Assembler-shared.h
@@ -2,24 +2,25 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_Assembler_shared_h
#define ion_shared_Assembler_shared_h
-#include <limits.h>
-
#include "mozilla/DebugOnly.h"
#include "mozilla/PodOperations.h"
+#include <limits.h>
+
#include "ion/IonAllocPolicy.h"
#include "ion/Registers.h"
#include "ion/RegisterSets.h"
+
#if defined(JS_CPU_X64) || defined(JS_CPU_ARM)
// JS_SMALL_BRANCH means the range on a branch instruction
// is smaller than the whole address space
# define JS_SMALL_BRANCH
#endif
namespace js {
namespace ion {
--- a/js/src/ion/shared/Assembler-x86-shared.cpp
+++ b/js/src/ion/shared/Assembler-x86-shared.cpp
@@ -1,16 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "gc/Marking.h"
#include "ion/IonMacroAssembler.h"
-#include "gc/Marking.h"
using namespace js;
using namespace js::ion;
void
AssemblerX86Shared::copyJumpRelocationTable(uint8_t *dest)
{
if (jumpRelocations_.length())
--- a/js/src/ion/shared/Assembler-x86-shared.h
+++ b/js/src/ion/shared/Assembler-x86-shared.h
@@ -1,18 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_Assembler_x86_shared_h
#define ion_shared_Assembler_x86_shared_h
+
#include <cstddef>
+
#include "assembler/assembler/X86Assembler.h"
+#include "ion/shared/Assembler-shared.h"
namespace js {
namespace ion {
class AssemblerX86Shared
{
protected:
struct RelativePatch {
--- a/js/src/ion/shared/BaselineCompiler-shared.cpp
+++ b/js/src/ion/shared/BaselineCompiler-shared.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/shared/BaselineCompiler-shared.h"
+
#include "ion/BaselineIC.h"
#include "ion/VMFunctions.h"
using namespace js;
using namespace js::ion;
BaselineCompilerShared::BaselineCompilerShared(JSContext *cx, HandleScript script)
: cx(cx),
--- a/js/src/ion/shared/BaselineCompiler-shared.h
+++ b/js/src/ion/shared/BaselineCompiler-shared.h
@@ -3,21 +3,22 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_BaselineCompiler_shared_h
#define ion_shared_BaselineCompiler_shared_h
#include "jscntxt.h"
+
#include "ion/BaselineFrameInfo.h"
-#include "ion/IonSpewer.h"
#include "ion/BaselineIC.h"
#include "ion/IonInstrumentation.h"
#include "ion/IonMacroAssembler.h"
+#include "ion/IonSpewer.h"
namespace js {
namespace ion {
class BaselineCompilerShared
{
protected:
JSContext *cx;
--- a/js/src/ion/shared/BaselineIC-x86-shared.cpp
+++ b/js/src/ion/shared/BaselineIC-x86-shared.cpp
@@ -1,18 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineJIT.h"
-#include "ion/BaselineIC.h"
#include "ion/BaselineCompiler.h"
#include "ion/BaselineHelpers.h"
+#include "ion/BaselineIC.h"
+#include "ion/BaselineJIT.h"
#include "ion/IonLinker.h"
using namespace js;
using namespace js::ion;
bool
ICCompare_Double::Compiler::generateStubCode(MacroAssembler &masm)
{
--- a/js/src/ion/shared/CodeGenerator-shared-inl.h
+++ b/js/src/ion/shared/CodeGenerator-shared-inl.h
@@ -2,16 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_CodeGenerator_shared_inl_h
#define ion_shared_CodeGenerator_shared_inl_h
+#include "ion/shared/CodeGenerator-shared.h"
+
namespace js {
namespace ion {
static inline int32_t
ToInt32(const LAllocation *a)
{
if (a->isConstantValue())
return a->toConstant()->toInt32();
--- a/js/src/ion/shared/CodeGenerator-shared.cpp
+++ b/js/src/ion/shared/CodeGenerator-shared.cpp
@@ -1,25 +1,26 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/shared/CodeGenerator-shared-inl.h"
+
#include "mozilla/DebugOnly.h"
-#include "ion/shared/CodeGenerator-shared.h"
-#include "ion/MIRGenerator.h"
-#include "ion/IonFrames-inl.h"
+#include "builtin/ParallelArray.h"
+#include "ion/IonMacroAssembler.h"
+#include "ion/IonSpewer.h"
#include "ion/MIR.h"
-#include "ion/shared/CodeGenerator-shared-inl.h"
-#include "ion/IonSpewer.h"
-#include "ion/IonMacroAssembler.h"
+#include "ion/MIRGenerator.h"
#include "ion/ParallelFunctions.h"
-#include "builtin/ParallelArray.h"
+
+#include "ion/IonFrames-inl.h"
using namespace js;
using namespace js::ion;
using mozilla::DebugOnly;
namespace js {
namespace ion {
--- a/js/src/ion/shared/CodeGenerator-shared.h
+++ b/js/src/ion/shared/CodeGenerator-shared.h
@@ -2,26 +2,25 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_CodeGenerator_shared_h
#define ion_shared_CodeGenerator_shared_h
+#include "ion/IonCaches.h"
+#include "ion/IonFrames.h"
+#include "ion/IonMacroAssembler.h"
+#include "ion/LIR.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/LIR.h"
-#include "ion/IonCaches.h"
-#include "ion/IonMacroAssembler.h"
-#include "ion/IonFrames.h"
-#include "ion/IonMacroAssembler.h"
#include "ion/Safepoints.h"
+#include "ion/SnapshotWriter.h"
#include "ion/VMFunctions.h"
-#include "ion/SnapshotWriter.h"
namespace js {
namespace ion {
class OutOfLineCode;
class CodeGenerator;
class MacroAssembler;
class IonCache;
--- a/js/src/ion/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/ion/shared/CodeGenerator-x86-shared.cpp
@@ -1,26 +1,29 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/shared/CodeGenerator-x86-shared.h"
+
#include "mozilla/DebugOnly.h"
#include "mozilla/MathAlgorithms.h"
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsmath.h"
-#include "ion/shared/CodeGenerator-x86-shared.h"
-#include "ion/shared/CodeGenerator-shared-inl.h"
+
+#include "ion/IonCompartment.h"
#include "ion/IonFrames.h"
-#include "ion/IonCompartment.h"
#include "ion/ParallelFunctions.h"
+#include "ion/shared/CodeGenerator-shared-inl.h"
+
using namespace js;
using namespace js::ion;
using mozilla::FloorLog2;
namespace js {
namespace ion {
--- a/js/src/ion/shared/IonAssemblerBuffer.h
+++ b/js/src/ion/shared/IonAssemblerBuffer.h
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_IonAssemblerBuffer_h
#define ion_shared_IonAssemblerBuffer_h
+
// needed for the definition of Label :(
#include "ion/shared/Assembler-shared.h"
namespace js {
namespace ion {
// This should theoretically reside inside of AssemblerBuffer, but that won't be nice
// AssemblerBuffer is templated, BufferOffset would be indirectly.
--- a/js/src/ion/shared/IonAssemblerBufferWithConstantPools.h
+++ b/js/src/ion/shared/IonAssemblerBufferWithConstantPools.h
@@ -1,19 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_IonAssemblerBufferWithConstantPools_h
#define ion_shared_IonAssemblerBufferWithConstantPools_h
-#include "ion/shared/IonAssemblerBuffer.h"
+
#include "assembler/wtf/SegmentedVector.h"
#include "ion/IonSpewer.h"
+#include "ion/shared/IonAssemblerBuffer.h"
+
namespace js {
namespace ion {
typedef Vector<BufferOffset, 512, IonAllocPolicy> LoadOffsets;
struct Pool
: public IonAllocPolicy
{
const int maxOffset;
--- a/js/src/ion/shared/IonFrames-x86-shared.h
+++ b/js/src/ion/shared/IonFrames-x86-shared.h
@@ -2,16 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_IonFrames_x86_shared_h
#define ion_shared_IonFrames_x86_shared_h
+#include "mozilla/StandardInteger.h"
+
#include "ion/shared/IonFrames-shared.h"
namespace js {
namespace ion {
class IonCommonFrameLayout
{
private:
--- a/js/src/ion/shared/Lowering-shared-inl.h
+++ b/js/src/ion/shared/Lowering-shared-inl.h
@@ -2,16 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_Lowering_shared_inl_h
#define ion_shared_Lowering_shared_inl_h
+#include "ion/shared/Lowering-shared.h"
+
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
namespace js {
namespace ion {
bool
LIRGeneratorShared::emitAtUses(MInstruction *mir)
--- a/js/src/ion/shared/Lowering-shared.cpp
+++ b/js/src/ion/shared/Lowering-shared.cpp
@@ -1,19 +1,19 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/shared/Lowering-shared-inl.h"
+
#include "ion/LIR.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/shared/Lowering-shared.h"
-#include "ion/shared/Lowering-shared-inl.h"
using namespace js;
using namespace ion;
bool
LIRGeneratorShared::visitConstant(MConstant *ins)
{
const Value &v = ins->value();
--- a/js/src/ion/shared/Lowering-x86-shared.cpp
+++ b/js/src/ion/shared/Lowering-x86-shared.cpp
@@ -1,19 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/shared/Lowering-x86-shared.h"
+
#include "mozilla/MathAlgorithms.h"
+#include "ion/Lowering.h"
#include "ion/MIR.h"
-#include "ion/Lowering.h"
-#include "ion/shared/Lowering-x86-shared.h"
+
#include "ion/shared/Lowering-shared-inl.h"
using namespace js;
using namespace js::ion;
using mozilla::FloorLog2;
LTableSwitch *
--- a/js/src/ion/shared/MacroAssembler-x86-shared.h
+++ b/js/src/ion/shared/MacroAssembler-x86-shared.h
@@ -5,25 +5,25 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_shared_MacroAssembler_x86_shared_h
#define ion_shared_MacroAssembler_x86_shared_h
#include "mozilla/Casting.h"
#include "mozilla/DebugOnly.h"
+#include "jsopcode.h"
+
+#include "ion/IonCaches.h"
+#include "ion/IonFrames.h"
#ifdef JS_CPU_X86
# include "ion/x86/Assembler-x86.h"
#elif JS_CPU_X64
# include "ion/x64/Assembler-x64.h"
#endif
-#include "ion/IonFrames.h"
-#include "jsopcode.h"
-
-#include "ion/IonCaches.h"
namespace js {
namespace ion {
class MacroAssemblerX86Shared : public Assembler
{
protected:
// Bytes pushed onto the frame by the callee; includes frameDepth_. This is
--- a/js/src/ion/shared/MoveEmitter-x86-shared.h
+++ b/js/src/ion/shared/MoveEmitter-x86-shared.h
@@ -2,18 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_MoveEmitter_x86_shared_h
#define ion_MoveEmitter_x86_shared_h
+#include "ion/IonMacroAssembler.h"
#include "ion/MoveResolver.h"
-#include "ion/IonMacroAssembler.h"
namespace js {
namespace ion {
class CodeGenerator;
class MoveEmitterX86
{
--- a/js/src/ion/x64/Assembler-x64.cpp
+++ b/js/src/ion/x64/Assembler-x64.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x64/Assembler-x64.h"
+
#include "gc/Marking.h"
#include "ion/LIR.h"
using namespace js;
using namespace js::ion;
ABIArgGenerator::ABIArgGenerator()
:
--- a/js/src/ion/x64/Assembler-x64.h
+++ b/js/src/ion/x64/Assembler-x64.h
@@ -2,20 +2,21 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x64_Assembler_x64_h
#define ion_x64_Assembler_x64_h
-#include "ion/shared/Assembler-shared.h"
+#include "mozilla/Util.h"
+
#include "ion/CompactBuffer.h"
#include "ion/IonCode.h"
-#include "mozilla/Util.h"
+#include "ion/shared/Assembler-shared.h"
namespace js {
namespace ion {
static MOZ_CONSTEXPR_VAR Register rax = { JSC::X86Registers::eax };
static MOZ_CONSTEXPR_VAR Register rbx = { JSC::X86Registers::ebx };
static MOZ_CONSTEXPR_VAR Register rcx = { JSC::X86Registers::ecx };
static MOZ_CONSTEXPR_VAR Register rdx = { JSC::X86Registers::edx };
--- a/js/src/ion/x64/Bailouts-x64.cpp
+++ b/js/src/ion/x64/Bailouts-x64.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "jscntxt.h"
#include "jscompartment.h"
+
#include "ion/Bailouts.h"
#include "ion/IonCompartment.h"
using namespace js;
using namespace js::ion;
#if defined(_WIN32)
# pragma pack(push, 1)
--- a/js/src/ion/x64/BaselineHelpers-x64.h
+++ b/js/src/ion/x64/BaselineHelpers-x64.h
@@ -3,21 +3,20 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x64_BaselineHelpers_x64_h
#define ion_x64_BaselineHelpers_x64_h
#ifdef JS_ION
-
+#include "ion/BaselineFrame.h"
+#include "ion/BaselineIC.h"
+#include "ion/BaselineRegisters.h"
#include "ion/IonMacroAssembler.h"
-#include "ion/BaselineFrame.h"
-#include "ion/BaselineRegisters.h"
-#include "ion/BaselineIC.h"
namespace js {
namespace ion {
// Distance from Stack top to the top Value inside an IC stub (this is the return address).
static const size_t ICStackValueOffset = sizeof(void *);
inline void
--- a/js/src/ion/x64/BaselineIC-x64.cpp
+++ b/js/src/ion/x64/BaselineIC-x64.cpp
@@ -1,18 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineJIT.h"
+#include "ion/BaselineCompiler.h"
+#include "ion/BaselineHelpers.h"
#include "ion/BaselineIC.h"
-#include "ion/BaselineHelpers.h"
-#include "ion/BaselineCompiler.h"
+#include "ion/BaselineJIT.h"
#include "ion/IonLinker.h"
using namespace js;
using namespace js::ion;
namespace js {
namespace ion {
--- a/js/src/ion/x64/CodeGenerator-x64.cpp
+++ b/js/src/ion/x64/CodeGenerator-x64.cpp
@@ -1,17 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x64/CodeGenerator-x64.h"
+
#include "jsnum.h"
-#include "ion/x64/CodeGenerator-x64.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
#include "vm/Shape.h"
#include "jsscriptinlines.h"
#include "ion/shared/CodeGenerator-shared-inl.h"
--- a/js/src/ion/x64/CodeGenerator-x64.h
+++ b/js/src/ion/x64/CodeGenerator-x64.h
@@ -2,18 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x64_CodeGenerator_x64_h
#define ion_x64_CodeGenerator_x64_h
+#include "ion/shared/CodeGenerator-x86-shared.h"
#include "ion/x64/Assembler-x64.h"
-#include "ion/shared/CodeGenerator-x86-shared.h"
namespace js {
namespace ion {
class CodeGeneratorX64 : public CodeGeneratorX86Shared
{
CodeGeneratorX64 *thisFromCtor() {
return this;
--- a/js/src/ion/x64/Lowering-x64.cpp
+++ b/js/src/ion/x64/Lowering-x64.cpp
@@ -2,18 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x64/Lowering-x64.h"
#include "ion/MIR.h"
+#include "ion/shared/Lowering-shared-inl.h"
#include "ion/x64/Assembler-x64.h"
-#include "ion/shared/Lowering-shared-inl.h"
using namespace js;
using namespace js::ion;
bool
LIRGeneratorX64::useBox(LInstruction *lir, size_t n, MDefinition *mir,
LUse::Policy policy, bool useAtStart)
{
--- a/js/src/ion/x64/MacroAssembler-x64.cpp
+++ b/js/src/ion/x64/MacroAssembler-x64.cpp
@@ -1,19 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x64/MacroAssembler-x64.h"
+
+#include "mozilla/Casting.h"
+
#include "ion/BaselineFrame.h"
+#include "ion/IonFrames.h"
#include "ion/MoveEmitter.h"
-#include "ion/IonFrames.h"
-#include "mozilla/Casting.h"
using namespace js;
using namespace js::ion;
void
MacroAssemblerX64::loadConstantDouble(double d, const FloatRegister &dest)
{
if (maybeInlineDouble(d, dest))
--- a/js/src/ion/x64/MacroAssembler-x64.h
+++ b/js/src/ion/x64/MacroAssembler-x64.h
@@ -2,20 +2,21 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x64_MacroAssembler_x64_h
#define ion_x64_MacroAssembler_x64_h
-#include "ion/shared/MacroAssembler-x86-shared.h"
+#include "jsnum.h"
+
+#include "ion/IonFrames.h"
#include "ion/MoveResolver.h"
-#include "ion/IonFrames.h"
-#include "jsnum.h"
+#include "ion/shared/MacroAssembler-x86-shared.h"
namespace js {
namespace ion {
struct ImmShiftedTag : public ImmWord
{
ImmShiftedTag(JSValueShiftedTag shtag)
: ImmWord((uintptr_t)shtag)
--- a/js/src/ion/x64/Trampoline-x64.cpp
+++ b/js/src/ion/x64/Trampoline-x64.cpp
@@ -1,24 +1,25 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "jscompartment.h"
+
#include "assembler/assembler/MacroAssembler.h"
-#include "ion/IonCompartment.h"
-#include "ion/IonLinker.h"
-#include "ion/IonFrames.h"
#include "ion/Bailouts.h"
-#include "ion/VMFunctions.h"
+#include "ion/ExecutionModeInlines.h"
+#include "ion/IonCompartment.h"
+#include "ion/IonFrames.h"
+#include "ion/IonLinker.h"
#include "ion/IonSpewer.h"
+#include "ion/VMFunctions.h"
#include "ion/x64/BaselineHelpers-x64.h"
-#include "ion/ExecutionModeInlines.h"
using namespace js;
using namespace js::ion;
// All registers to save and restore. This includes the stack pointer, since we
// use the ability to reference register values on the stack by index.
static const RegisterSet AllRegs =
RegisterSet(GeneralRegisterSet(Registers::AllMask),
--- a/js/src/ion/x86/Assembler-x86.cpp
+++ b/js/src/ion/x86/Assembler-x86.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x86/Assembler-x86.h"
+
#include "gc/Marking.h"
using namespace js;
using namespace js::ion;
ABIArgGenerator::ABIArgGenerator()
: stackOffset_(0),
current_()
--- a/js/src/ion/x86/Assembler-x86.h
+++ b/js/src/ion/x86/Assembler-x86.h
@@ -2,21 +2,22 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x86_Assembler_x86_h
#define ion_x86_Assembler_x86_h
-#include "ion/shared/Assembler-shared.h"
+#include "mozilla/Util.h"
+
#include "assembler/assembler/X86Assembler.h"
#include "ion/CompactBuffer.h"
#include "ion/IonCode.h"
-#include "mozilla/Util.h"
+#include "ion/shared/Assembler-shared.h"
namespace js {
namespace ion {
static MOZ_CONSTEXPR_VAR Register eax = { JSC::X86Registers::eax };
static MOZ_CONSTEXPR_VAR Register ecx = { JSC::X86Registers::ecx };
static MOZ_CONSTEXPR_VAR Register edx = { JSC::X86Registers::edx };
static MOZ_CONSTEXPR_VAR Register ebx = { JSC::X86Registers::ebx };
--- a/js/src/ion/x86/Bailouts-x86.cpp
+++ b/js/src/ion/x86/Bailouts-x86.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "jscntxt.h"
#include "jscompartment.h"
+
#include "ion/Bailouts.h"
#include "ion/IonCompartment.h"
using namespace js;
using namespace js::ion;
#if defined(_WIN32)
# pragma pack(push, 1)
--- a/js/src/ion/x86/BaselineHelpers-x86.h
+++ b/js/src/ion/x86/BaselineHelpers-x86.h
@@ -3,21 +3,20 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x86_BaselineHelpers_x86_h
#define ion_x86_BaselineHelpers_x86_h
#ifdef JS_ION
-
+#include "ion/BaselineFrame.h"
+#include "ion/BaselineIC.h"
+#include "ion/BaselineRegisters.h"
#include "ion/IonMacroAssembler.h"
-#include "ion/BaselineFrame.h"
-#include "ion/BaselineRegisters.h"
-#include "ion/BaselineIC.h"
namespace js {
namespace ion {
// Distance from stack top to the top Value inside an IC stub (this is the return address).
static const size_t ICStackValueOffset = sizeof(void *);
inline void
--- a/js/src/ion/x86/BaselineIC-x86.cpp
+++ b/js/src/ion/x86/BaselineIC-x86.cpp
@@ -1,18 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/BaselineJIT.h"
-#include "ion/BaselineIC.h"
#include "ion/BaselineCompiler.h"
#include "ion/BaselineHelpers.h"
+#include "ion/BaselineIC.h"
+#include "ion/BaselineJIT.h"
#include "ion/IonLinker.h"
using namespace js;
using namespace js::ion;
namespace js {
namespace ion {
--- a/js/src/ion/x86/CodeGenerator-x86.cpp
+++ b/js/src/ion/x86/CodeGenerator-x86.cpp
@@ -1,26 +1,28 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x86/CodeGenerator-x86.h"
+
#include "mozilla/DebugOnly.h"
#include "jsnum.h"
-#include "ion/x86/CodeGenerator-x86.h"
+#include "ion/ExecutionModeInlines.h"
#include "ion/MIR.h"
#include "ion/MIRGraph.h"
-#include "ion/shared/CodeGenerator-shared-inl.h"
#include "vm/Shape.h"
#include "jsscriptinlines.h"
-#include "ion/ExecutionModeInlines.h"
+
+#include "ion/shared/CodeGenerator-shared-inl.h"
using namespace js;
using namespace js::ion;
using mozilla::DebugOnly;
using mozilla::DoubleExponentBias;
using mozilla::DoubleExponentShift;
--- a/js/src/ion/x86/CodeGenerator-x86.h
+++ b/js/src/ion/x86/CodeGenerator-x86.h
@@ -2,18 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x86_CodeGenerator_x86_h
#define ion_x86_CodeGenerator_x86_h
+#include "ion/shared/CodeGenerator-x86-shared.h"
#include "ion/x86/Assembler-x86.h"
-#include "ion/shared/CodeGenerator-x86-shared.h"
namespace js {
namespace ion {
class OutOfLineLoadTypedArrayOutOfBounds;
class OutOfLineTruncate;
class CodeGeneratorX86 : public CodeGeneratorX86Shared
--- a/js/src/ion/x86/Lowering-x86.cpp
+++ b/js/src/ion/x86/Lowering-x86.cpp
@@ -2,18 +2,18 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x86/Lowering-x86.h"
#include "ion/MIR.h"
+#include "ion/shared/Lowering-shared-inl.h"
#include "ion/x86/Assembler-x86.h"
-#include "ion/shared/Lowering-shared-inl.h"
using namespace js;
using namespace js::ion;
bool
LIRGeneratorX86::useBox(LInstruction *lir, size_t n, MDefinition *mir,
LUse::Policy policy, bool useAtStart)
{
--- a/js/src/ion/x86/MacroAssembler-x86.cpp
+++ b/js/src/ion/x86/MacroAssembler-x86.cpp
@@ -1,19 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "ion/x86/MacroAssembler-x86.h"
+
+#include "mozilla/Casting.h"
+
#include "ion/BaselineFrame.h"
+#include "ion/IonFrames.h"
#include "ion/MoveEmitter.h"
-#include "ion/IonFrames.h"
-#include "mozilla/Casting.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;
void
MacroAssemblerX86::loadConstantDouble(double d, const FloatRegister &dest)
--- a/js/src/ion/x86/MacroAssembler-x86.h
+++ b/js/src/ion/x86/MacroAssembler-x86.h
@@ -2,21 +2,21 @@
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ion_x86_MacroAssembler_x86_h
#define ion_x86_MacroAssembler_x86_h
-#include "ion/shared/MacroAssembler-x86-shared.h"
+#include "jscompartment.h"
+
#include "ion/IonFrames.h"
#include "ion/MoveResolver.h"
-
-#include "jscompartment.h"
+#include "ion/shared/MacroAssembler-x86-shared.h"
namespace js {
namespace ion {
class MacroAssemblerX86 : public MacroAssemblerX86Shared
{
// Number of bytes the stack is adjusted inside a call to C. Calls to C may
// not be nested.
--- a/js/src/ion/x86/Trampoline-x86.cpp
+++ b/js/src/ion/x86/Trampoline-x86.cpp
@@ -1,25 +1,26 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 "jscompartment.h"
+
#include "assembler/assembler/MacroAssembler.h"
+#include "ion/Bailouts.h"
#include "ion/BaselineJIT.h"
+#include "ion/ExecutionModeInlines.h"
#include "ion/IonCompartment.h"
+#include "ion/IonFrames.h"
#include "ion/IonLinker.h"
-#include "ion/IonFrames.h"
#include "ion/IonSpewer.h"
-#include "ion/Bailouts.h"
#include "ion/VMFunctions.h"
#include "ion/x86/BaselineHelpers-x86.h"
-#include "ion/ExecutionModeInlines.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;
// All registers to save and restore. This includes the stack pointer, since we
// use the ability to reference register values on the stack by index.
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug867946.js
@@ -0,0 +1,7 @@
+// |jit-test| error: InternalError: too much recursion
+b = {};
+b.__proto__ = evalcx("lazy");
+function g() {
+ g(b.toString())
+}
+g();
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -820,17 +820,17 @@ JSRuntime::JSRuntime(JSUseHelperThreads
gcIncrementalEnabled(true),
gcGenerationalEnabled(true),
gcManipulatingDeadZones(false),
gcObjectsMarkedInDeadZones(0),
gcPoke(false),
heapState(Idle),
#ifdef JSGC_GENERATIONAL
gcNursery(thisFromCtor()),
- gcStoreBuffer(thisFromCtor()),
+ gcStoreBuffer(thisFromCtor(), gcNursery),
#endif
#ifdef JS_GC_ZEAL
gcZeal_(0),
gcZealFrequency(0),
gcNextScheduled(0),