merge mozilla-inbound to mozilla-central a=merge

--HG--
rename : media/gmp-clearkey/0.1/ClearKeyCencParser.cpp => media/psshparser/PsshParser.cpp
rename : media/gmp-clearkey/0.1/ClearKeyCencParser.h => media/psshparser/PsshParser.h
rename : media/gmp-clearkey/0.1/gtest/TestClearKeyUtils.cpp => media/psshparser/gtest/TestPsshParser.cpp
rename : media/gmp-clearkey/0.1/gtest/moz.build => media/psshparser/gtest/moz.build
This commit is contained in:
Carsten "Tomcat" Book 2016-10-12 12:01:48 +02:00
commit 2844380bd4
212 changed files with 3408 additions and 1530 deletions

View File

@ -9,7 +9,7 @@ support-files =
worker.js
[browser_aboutURLs.js]
skip-if = (debug && (os == "win" || os == "linux")) # intermittent negative leak bug 1271182
skip-if = debug && os == "linux" # Assertion. See bug 1271182.
[browser_eme.js]
[browser_favicon.js]
[browser_forgetaboutsite.js]

View File

@ -93,7 +93,9 @@ function focusTag(PlacesOrganizer) {
let fooTag = tags.getChild(0);
let tagNode = fooTag;
PlacesOrganizer._places.selectNode(fooTag);
is(tagNode.title, 'foo', "tagNode title is foo");
// Bug 1283076: Nightly has a default 'bug' tag already set
let tagValue = AppConstants.NIGHTLY_BUILD ? 'bug' : 'foo';
is(tagNode.title, tagValue, "tagNode title is " + tagValue);
let ip = PlacesOrganizer._places.insertionPoint;
ok(ip.isTag, "IP is a tag");
}

View File

@ -152,7 +152,9 @@ function test() {
var tagsNode = PlacesUtils.history.executeQuery(query, options).root;
tagsNode.containerOpen = true;
is(tagsNode.childCount, 1, "has new tag");
// Bug 1283076: Nightly already has 7 tags set
let tagsCount = AppConstants.NIGHTLY_BUILD ? 8 : 1;
is(tagsNode.childCount, tagsCount, "has new tag");
var tagNode = tagsNode.getChild(0);

View File

@ -23,9 +23,10 @@ add_task(function* () {
let tree = PlacesOrganizer._places;
let tagsContainer = tree.selectedNode;
tagsContainer.containerOpen = true;
let fooTag = tagsContainer.getChild(0);
let tagNode = fooTag;
tree.selectNode(fooTag);
// Bug 1283076: Nightly already has several tags set, position changes
let tagPosition = AppConstants.NIGHTLY_BUILD ? 7 : 0;
let tagNode = tagsContainer.getChild(tagPosition);
tree.selectNode(tagNode);
is(tagNode.title, 'tag1', "tagNode title is correct");
ok(tree.controller.isCommandEnabled("placesCmd_show:info"),

View File

@ -205,8 +205,9 @@ add_task(function* test_tags() {
// Now select the tag.
PlacesUtils.asContainer(tagsNode).containerOpen = true;
let tag = tagsNode.getChild(0);
PO._places.selectNode(tag);
// Bug 1283076: Nightly already has several tags set, position changes
let tagPosition = AppConstants.NIGHTLY_BUILD ? 7 : 0;
PO._places.selectNode(tagsNode.getChild(tagPosition));
is(PO._places.selectedNode.title, "test",
"The created tag has been properly selected");

View File

@ -9,6 +9,8 @@
* corrupt, nor a JSON backup nor bookmarks.html are available.
*/
Components.utils.import("resource://gre/modules/AppConstants.jsm");
function run_test() {
// Remove bookmarks.html from profile.
remove_bookmarks_html();
@ -46,5 +48,8 @@ add_task(function* () {
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
index: SMART_BOOKMARKS_ON_TOOLBAR
});
do_check_eq(bm.title, "Getting Started");
// Bug 1283076: Nightly bookmark points to Get Involved page, not Getting Started one
let chanTitle = AppConstants.NIGHTLY_BUILD ? "Get Involved" : "Getting Started";
do_check_eq(bm.title, chanTitle);
});

View File

@ -610,7 +610,7 @@ var pktApi = (function() {
* Helper function to get current signup AB group the user is in
*/
function getSignupPanelTabTestVariant() {
return getMultipleTestOption('panelSignUp', {control: 1, v1: 2, v2: 7 })
return getMultipleTestOption('panelSignUp', {control: 1, v1: 8, v2: 1 })
}
function getMultipleTestOption(testName, testOptions) {

View File

@ -37,4 +37,36 @@
# link title for https://www.mozilla.org/en-US/about/
#define firefox_about About Us
# LOCALIZATION NOTE (nightly_heading):
# Firefox Nightly links folder name
#define nightly_heading Firefox Nightly Resources
# LOCALIZATION NOTE (nightly_blog):
# Nightly builds only, link title for https://blog.nightly.mozilla.org/
#define nightly_blog Firefox Nightly blog
# LOCALIZATION NOTE (bugzilla):
# Nightly builds only, link title for https://bugzilla.mozilla.org/
#define bugzilla Mozilla Bug Tracker
# LOCALIZATION NOTE (mdn):
# Nightly builds only, link title for https://developer.mozilla.org/
#define mdn Mozilla Developer Network
# LOCALIZATION NOTE (nightly_tester_tools):
# Nightly builds only, link title for https://addons.mozilla.org/en-US/firefox/addon/nightly-tester-tools/
#define nightly_tester_tools Nightly Tester Tools
# LOCALIZATION NOTE (crashes):
# Nightly builds only, link title for about:crashes
#define crashes All your crashes
# LOCALIZATION NOTE (irc):
# Nightly builds only, link title for ircs://irc.mozilla.org/nightly
#define irc Discuss Nightly on IRC
# LOCALIZATION NOTE (planet):
# Nightly builds only, link title for https://planet.mozilla.org/
#define planet Planet Mozilla
#unfilter emptyLines

View File

@ -4,29 +4,53 @@
#if AB_CD == ja_jp_mac
#define AB_CD ja
#endif
#define mozilla_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=
#define nightly_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA01JREFUeNpkk01oXFUUx//vzp33ZiaTzkwnyUwmsbbNRpp0GhuVKiVgQIUiLmoX7lyIG10I6qIUrG6KGyuYZbMwiATqxipSMVhQYwWhiwSJwUxKkzbz8ZJ5H/M+7/vunUIE7Vnc1f3/zjn/c46wsCbjIOI4Rlfew+Zf6/h9+RYYYzj70hymZp7GULUCSin+H8IBwLYsfLOwiOfffndK1c2LmhO84jl+2e5ZCTN6Xer0fpp5dmq+frxy5zGAY9n49IOLuHDls8uqE3y07YV0ywwQGA6oZsJRFRT0FnK2Hpw8PTl/7tXZDw8ApF/29YUvufjqxxqLPrnLQBUiQRUI4EcQHQ+EgwbjENl8Pv3H9W/f//m7W9cOAKkXzr+J4pm5umy6S/uEkiAEOlzscWHG5jTbhcsrDJiHsN1CIScJTlc5JaSlldEna9uk8fcGHNO6tOMGqfssQjNFoHOxyAXU9xF5HiRXw2AqhuUEsLs6giCkjbXG549a+O3mMhQneLnthOh0NBiaAdozkTEdpC0Hnm2hKAKR3ESJRigNFZBHCF2zn+p7SMIwRM9kRcI/D5g2xAcd1PQeMtw8xkGuafIRGRgZKfHfCbKlIu5t3IVASYYDDtMzL85il2fLuh6qIkFkWtjrARY3zjENJLwCKgqwOjLcnW30Qh/HnpmGYTJhT1bSdPL0NBpr+6rbs8qhIiPivQtRhDDJQuCViI4BxdJRrx/jBopob25BDmIMnzgZjFTK+2R4tAo4+q8iM9Ba3wBTuxirHELeM5AxFO6FCsnSsHNnFfL9XUiFIo7ypNmB9D3eQkT665nS5Xm72Q5r3KCo04be2MIRKULOUlEkPnJpAbn8AI7XJyEUy/CBhIrJlUdT6D/rP3x1u1yQFjP5bFIbH4HdbHG2j/GJMfiqzneCwVI0oFrD8OgTiKLgl5Ubi0v/uYV3ZqcrE2ff+Do2/LlUxAi/HKQZH9eegupzpxDztL4gIfTU9d3VG+ev/nh7s6/797wiz1K3VpYuDU3MvFWunXg9ly2WTNVNDZaPgIU08V3NMNXVZfmfP68lvt187Br78d5r52hoKaUkiWspQqqHx4+OCQLhFu3KAXNbCYQWzR5SBCr5X3x/M+lrHgowAMP2wWqd+FzxAAAAAElFTkSuQmCC
#define firefox_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAz5JREFUeNpcU0toXFUY/s49596588ikySSmM8rk0UkJEirVTVEjYk1NUdRFFgouXZQI2k2hUCjdiYIuCi4Kuig0DbqQYgU3Yi0iFRuRCBMwaZvMZDTNY95z3/fM8b8jldpzOeeee/i/737n+/+f4ZExf730rkiaZ9NJMx/nmk5HypMqqLr+ZuD4F67N5ZYejmfRsnvhyKsLhSs3zP70SubgYKHSdFENu+gXAprQIGnvBi5ez0m1b6u7M399+PTx+UvtCKtFi2F6195qXK2byir88esy5ksfYND5DhuhRCtUKBNB0Q7w5Z8ee2GgWdjOn250fn5v5j8F5dOHlZD0kWRgAwp3hrKY0S9BJWKIcQ5PShhNG4+1bHx+IocT+RXcrRSDMfFNRvvt3Oyp/icIrRhUl9hoO4kt3F55Bxf3LkLV20jWOohbDjzXxyc/lMH0cRSyCd1xq+dFhu986t7T0CUwIzB8EkW3O5ibhj44ib7NJhiBKRoB/aS4ZWHjbxtjGQYP7nGRTjim1SaQqYiAVAREpHG8vzWJn+6PQ6CF0HPR7nQQczpYeEWHyWMUkwU8MSECGwgJxAWp9xWKNzkuH3oet+JDlIE9Momedh1G4CN0bfhVG9nsS0BQQthJx0V7j3elq7ihqV5ezQTwZmodP9ZGkU/bOPr4Nr53xtDYsaD7Dg4nNqFaH5OCYSSdGhf7daNmuv6wEKqXk/yExKGBHSznFsH6FFpKQ/JAA0ulUejWLt44lkHXsqDaX6C6Nl4Rnq8vK8s/KThDMlJhkI91YOO+iR3XwEelCdTCBLSgijNzd6DLNfhlHfZ6FtWiWBQpq/V2LdSrrNPljBQkoOjuCiPxAMutOIbkPqYSEqeequGZaTLzdhZhS0PlnlB9bvhtr5CuHj3y2Qj8hVQ/kEopxONEEsO/0yATDYXYAdWrE69JEElXq7Hyk0tro+xBU1yZmr4xrIcvptIRCZlJJAYBmRGRkD08aivA7VDvWPqt564Xn41w/AHB1/u7l1/uGxGU8mNcgodUNDIq0JDeLnpzc1uo1Qr76rWbqyf/142PjsXJqdkmN2YDnQ9oGkJNU+t57q7qUv4y9/t64+HYfwQYAN7OczrzUDvGAAAAAElFTkSuQmCC
#define bugzilla_icon data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnYCL7J0pY9wwETY9kYEM9AAAAAEBAYAhVVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1bjTOS1Vb/wAA2/8JEqT/Q0g8kQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJnMqoiJtJ/0haST/NEkp/yQnW/8AAPD8AAHY/RsgP/JZUI+GKitih4ObUEAAAAAAAAAAAAAAAAAAAAAAKnouwip5Lv9ooW//a6Jz/y9GIv8JBXb/AADO/gEBvf8AAK7/FRJp/z9BfP8iLGj1AAAAAAAAAAAAAAAAL4YzwiB0I/+UwJ3/bK+C/02eZ/9CTjz/DBa1/wABxf8BAOj/AACp/w8Oc/sJCv//EhCN9AAAAAAAAAAANJA6iC2MMv93tYL/TZ5U/3mzjP9NoWr/NEss/wYIU/8CBOn/ARCX/wwNqP0TD6X/Cgyex5qacDAAAAAAAAAAADKUN/ZirWj/d76R/0SgXf9Ln1P/eLSM/1mda/8rOkb/CQiD/wMQvf8UEnT/MTAt4P//MwUhZyN8AAAAAAAAAAAznDf5UqlZ/228jP9NqnD/Qp9c/0yiVP+Dv5b/VaVw/0VxXf9PZXD/S3pQ/y54Nf8jcCf/I2wn/wAAAAA0ozjIM6E4/zOeOP+Uz6z/XLR+/06scv9BoV3/TqZX/4XBmP9XqHP/hr6Z/yp+Lf8leSr1JXUqbQAAAAA3rTz7Nqo7/zWmOqM3oz7rUK1W/43Mpf9etYD/T61z/0KjXf9Rqln/msup/46/lf8pgy7/JFg6sAAAAAAAAAAAOK8+8jqvOiMAAAAAAAAAADSlOv85pT//kM6o/2K5hP9Ysnv/YLJ2/ziXPv8piS3/V6Ri/yZQQ9wAAAAAAAAAAAAAAAAAAAAAAAAAADetP0E2qzz/OKg98UWsS/+e1K3/pNe4/4XDjv8ojy3/T7df/5fIqv8sjTH/K4kw/yqFLv8AAAAAAAAAAAAAAAA4sT3xN7A8+QAAAAA4qz3yNag6/zSlOf80oTn/csJ+/6/jwv9fjHj/MmRMdQAAAAAAAAAAAAAAAAAAAAAAAAAAOrdA/zm0QHQAAAAAAAAAADasO/k2qTvuRX5lpjqGT/gznDr/O3FXigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADq9QiMAAAAAAAAAAAAAAAA4sj7/Nq09s0uOaSI1qTplM6U68wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrc//zu0P0EAAAAAOK4+UjWsPPgAAAAAAAAAAAAAAAAAAAAA/48AAP8HAAD4AQAA8AAAAOAAAADAAQAAwAMAAMAAAACAAwAAAAMAAHADAADwAAAA5AcAAO4HAAD+bwAA/u8AAA==
#define mdn_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAACYklEQVQ4y3WSTYjNYRTGf+f9/+/NuDN3GKMxt1mYpKR8RT6zEk1iyUo2IysSNspCxEIZRSN07YiUJSWkaUIZizELMzIZlO9h3MzXvf/341jcmTGa69RZvKfnPOc5z3mhQlRd651Ry17tqQQl5uR9ONHC3EtdiPPxWKZ24bhJvQV0OlBHhiV7pTs3WpUdEmeLrnWJAhhOtJA5/3RjqZg8Lrnwy4bQT/DvTb73Qt3N9ymATNvTU15Mvx8vfvTWDrmgT0y+dzuAZM527lM0Xx6jFKvnEKIYvIIqVeMFRCfEiDBWMw9UQUBUT8fBWvmrU9HEUpUWDq2cT23a0P6kQEqEwTFLQCBJpm9mYrV+6lW0ngNr62jb0kw6KvMeXJohZYSLzz9xvOMDJG6aPUKMtZPDObq+iXPbmoG/ooJC0QVaVy2g5AI3Bkq8/jYCkQEBo9ah1hESS1N1Gu9DxXNFRji0oYm+/Stoaa4tK0kcRq1HE4fxHqOKEf4bk16ubphd9iKxGKxFrcOWLB1vvuOCzmg0Irig1MxKMfBznPbOd2DLCmJNHKgSIdzr/kjXhwKbFtVPNQ+NJiw7+YDh0YTFuVr6CwLpaNJDjCYOtR61DldyHL7975c9dqeH4ZESscC7r79BFBI7kY5YrZsCC8qL/kFyR+6yY0UjS3M1PHz5ich71IOIQGSn0cskwdTeryTyfV9+jGzOP3rTQAiIHUNQEBkCeUbkcqguB2JEMGqt4sJlg8lGIsv0+p5dON8YaVgn3veJ85/F61YNtn5uXf3OCF0TQVacP0PiXMVzpfbemlnbna+I/QPSFTsRLd+hHAAAAABJRU5ErkJggg==
#define addon_icon data:image/vndmicrosofticon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKoSURBVDiNjZNLaJRnFIaf75vvy2UGTWr8NYkxl0IFUYkNXSSZQNWFWlxIEVy1FLLo0i4adddVXRnS4kJwYxci2GaRTWlSFGKFGRXNmFBF62VMO4TENBdjMv9k5p//Oy4SLzgqHs7yPc95eTlHiQjvqniPbVYRzuBoR+FQDEvId4neIPNCY945DayNVff/8NUvn9XXNJMv5hhKnTvYP3ymHmj/IMBSbmHjjP8fycxv+MEzGqtatUI1vK7R7wM4J32XUv3Li/l5imGBkbtXlsMw/PF1jXozg3iP3aM0Z8XRBFDr1fl7Og9EnTguXx30p/6fjAIozb/i6C4BdB2z6QOfH27ZUFNL0QUELs/tycs4J2zdGEerCADTM1P8df3PxyUZiKPF8zyGHpwGFLC6QCCRuYA4QQQ6mw4hjhYT77GN2qiBWFnV5sXc0xMAgfKx5foVYKURB2vLPbxoM8auODE6ws/fH+77dHtjhxp5OHzywpWf/IIsRk25Rq0CRFY4UVNNndkmqZFRf3YuWaYUS0aE3RP5MXX3/iCOgu3Y1WYfL90sdSDgxRoYTY5mZ2anjwC/AqEBdM4tMJ4dwYs1YiOGSBkYrVHqlQNxoC34OV8BdxK9gQ+guo7bwdYdrXu92nU6nR7Pzc/PSXxfazTj30IpRaWpIqbX4UQoBDkWJlRwLzVeLBTyGs2UcUX5duzvsfPqNpvDovQhnBIdELGaWFk1hclYmLx2fxmFbNm5qXJNvdi2DQ1WAsO1P/5petshyf6v25gJ0nxUUUeiP531s/kvAcor7MDOL2pjz3JzVKpqUoMTpb8QsSqdeTT98fomjyDv8LP5aKI3uAgQP2orCkGAVRVMZxbQhnQJIAzkm3s3Js6GSfkEQEd4+bpa8+TW71P1ANqoB65I93OA2DgV+Z+omgAAAABJRU5ErkJggg==
<!-- 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/. -->
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>@bookmarks_title@</TITLE>
<H1>@bookmarks_heading@</H1>
<meta charset="UTF-8">
<title>@bookmarks_title@</title>
<h1>@bookmarks_heading@</h1>
<DL><p>
<DT><H3 PERSONAL_TOOLBAR_FOLDER="true" ID="rdf:#$FvPhC3">@bookmarks_toolbarfolder@</H3>
<DD>@bookmarks_toolbarfolder_description@
<DL><p>
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/central/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAz5JREFUeNpcU0toXFUY/s49596588ikySSmM8rk0UkJEirVTVEjYk1NUdRFFgouXZQI2k2hUCjdiYIuCi4Kuig0DbqQYgU3Yi0iFRuRCBMwaZvMZDTNY95z3/fM8b8jldpzOeeee/i/737n+/+f4ZExf730rkiaZ9NJMx/nmk5HypMqqLr+ZuD4F67N5ZYejmfRsnvhyKsLhSs3zP70SubgYKHSdFENu+gXAprQIGnvBi5ez0m1b6u7M399+PTx+UvtCKtFi2F6195qXK2byir88esy5ksfYND5DhuhRCtUKBNB0Q7w5Z8ee2GgWdjOn250fn5v5j8F5dOHlZD0kWRgAwp3hrKY0S9BJWKIcQ5PShhNG4+1bHx+IocT+RXcrRSDMfFNRvvt3Oyp/icIrRhUl9hoO4kt3F55Bxf3LkLV20jWOohbDjzXxyc/lMH0cRSyCd1xq+dFhu986t7T0CUwIzB8EkW3O5ibhj44ib7NJhiBKRoB/aS4ZWHjbxtjGQYP7nGRTjim1SaQqYiAVAREpHG8vzWJn+6PQ6CF0HPR7nQQczpYeEWHyWMUkwU8MSECGwgJxAWp9xWKNzkuH3oet+JDlIE9Momedh1G4CN0bfhVG9nsS0BQQthJx0V7j3elq7ihqV5ezQTwZmodP9ZGkU/bOPr4Nr53xtDYsaD7Dg4nNqFaH5OCYSSdGhf7daNmuv6wEKqXk/yExKGBHSznFsH6FFpKQ/JAA0ulUejWLt44lkHXsqDaX6C6Nl4Rnq8vK8s/KThDMlJhkI91YOO+iR3XwEelCdTCBLSgijNzd6DLNfhlHfZ6FtWiWBQpq/V2LdSrrNPljBQkoOjuCiPxAMutOIbkPqYSEqeequGZaTLzdhZhS0PlnlB9bvhtr5CuHj3y2Qj8hVQ/kEopxONEEsO/0yATDYXYAdWrE69JEElXq7Hyk0tro+xBU1yZmr4xrIcvptIRCZlJJAYBmRGRkD08aivA7VDvWPqt564Xn41w/AHB1/u7l1/uGxGU8mNcgodUNDIq0JDeLnpzc1uo1Qr76rWbqyf/142PjsXJqdkmN2YDnQ9oGkJNU+t57q7qUv4y9/t64+HYfwQYAN7OczrzUDvGAAAAAElFTkSuQmCC" ID="rdf:#$GvPhC3">@getting_started@</A>
</DL><p>
<DT><H3 ID="rdf:#$ZvPhC3">@firefox_heading@</H3>
<DL><p>
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$22iCK1">@firefox_help@</A>
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$32iCK1">@firefox_customize@</A>
<DT><A HREF="https://www.mozilla.org/@AB_CD@/contribute/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$42iCK1">@firefox_community@</A>
<DT><A HREF="https://www.mozilla.org/@AB_CD@/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gwMDAsTBZbkNwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABNElEQVQ4y8WSsU0DURBE3yyWIaAJaqAAN4DPSL6AlIACKIEOyJEgRsIgOOkiInJqgAKowNg7BHdn7MOksNl+zZ//dvbDf5cAiklp22BdVtXdeTEpDYDB9m1VzU6OJuVp2NdEQCaI96fH2YHG4+mDduKYNMYINTcjcGbXzQVDEAphG0k48zUsajIbnAiMIXThpW8EICE0RAK4dvoKg9NIcTiQ589otyHOZLnwqK5nLwBFUZ4igc3iM0d1ff8CMC6mZ6Ihiaqq3gi1aUAnArD00SW1fq5OLBg0ymYmSZsR2/t4e/rGyCLW0sbp3oq+yTYqVgytQWui2FS7XYF7GFprY921T4CNQt8zr47dNzCkIX7y/jBtH+v+RGMQrc828W8pApnZbmEVQp/Ae7BlOy2ttib81/UFc+WRWEbjckIAAAAASUVORK5CYII=" ID="rdf:#$52iCK1">@firefox_about@</A>
</DL><p>
</DL><p>
<dl><p>
<dt><h3 personal_toolbar_folder="true">@bookmarks_toolbarfolder@</h3></dt>
<dd>@bookmarks_toolbarfolder_description@
#ifndef NIGHTLY_BUILD
<dl>
<p><dt><a href="https://www.mozilla.org/@AB_CD@/firefox/central/" icon="@firefox_icon@">@getting_started@</a></dt>
</dl>
<p><dt><h3>@firefox_heading@</h3></dt>
<dl><p>
<dt><a href="https://www.mozilla.org/@AB_CD@/firefox/help/" icon="@mozilla_icon@">@firefox_help@</a>
<dt><a href="https://www.mozilla.org/@AB_CD@/firefox/customize/" icon="@mozilla_icon@">@firefox_customize@</a>
<dt><a href="https://www.mozilla.org/@AB_CD@/contribute/" icon="@mozilla_icon@">@firefox_community@</a>
<dt><a href="https://www.mozilla.org/@AB_CD@/about/" icon="@mozilla_icon@">@firefox_about@</a>
</dl>
#else
<dl>
<p><dt><a href="https://www.mozilla.org/@AB_CD@/contribute/" icon="@mozilla_icon@">@firefox_community@</a>
</dl>
<p><dt><h3>@nightly_heading@</h3></dt>
<dl><p>
<dt><a href="https://blog.nightly.mozilla.org/" icon="@nightly_icon@">@nightly_blog@</a>
<dt><a href="https://bugzilla.mozilla.org/" icon="@bugzilla_icon@" shortcuturl="bz" tags="bug,issue">@bugzilla@</a>
<dt><a href="https://developer.mozilla.org/" icon="@mdn_icon@" shortcuturl="mdn">@mdn@</a>
<dt><a href="https://addons.mozilla.org/@AB_CD@/firefox/addon/nightly-tester-tools/" icon="@addon_icon@">@nightly_tester_tools@</a>
<dt><a href="about:crashes" icon="@mozilla_icon@" tags="crash">@crashes@</a>
<dt><a href="https://mibbit.com/?server=irc.mozilla.org&channel=%23nightly" icon="@mozilla_icon@" tags="chat,irc">@irc@</a>
<dt><a href="https://planet.mozilla.org/" icon="@mozilla_icon@" tags="planet,news">@planet@</a>
</dl>
#endif
</dl>

View File

@ -71,13 +71,6 @@
]
}
},
"be": {
"default": {
"visibleDefaultEngines": [
"yandex.by", "yahoo", "google", "ddg", "be-x-old.wikipedia.org", "be.wikipedia.org", "ru.wikipedia.org-be", "tut.by"
]
}
},
"bg": {
"default": {
"visibleDefaultEngines": [
@ -106,13 +99,6 @@
]
}
},
"brx": {
"default": {
"visibleDefaultEngines": [
"google", "yahoo-in", "bing", "ddg", "wikipedia-hi"
]
}
},
"bs": {
"default": {
"visibleDefaultEngines": [
@ -393,6 +379,13 @@
]
}
},
"kab": {
"default": {
"visibleDefaultEngines": [
"google", "yahoo-france", "bing", "ddg", "wikipedia-kab"
]
}
},
"kk": {
"default": {
"visibleDefaultEngines": [
@ -421,20 +414,6 @@
]
}
},
"kok": {
"default": {
"visibleDefaultEngines": [
"google", "yahoo-in", "bing", "ddg", "wikipedia-hi"
]
}
},
"ks": {
"default": {
"visibleDefaultEngines": [
"google", "yahoo-in", "bing", "ddg", "wikipedia-hi"
]
}
},
"lij": {
"default": {
"visibleDefaultEngines": [
@ -589,13 +568,6 @@
]
}
},
"sat": {
"default": {
"visibleDefaultEngines": [
"google", "yahoo-in", "bing", "wikipedia-hi", "ddg"
]
}
},
"si": {
"default": {
"visibleDefaultEngines": [
@ -666,6 +638,13 @@
]
}
},
"tl": {
"default": {
"visibleDefaultEngines": [
"google", "yahoo-tl", "bing", "amazondotcom", "ddg", "twitter", "wikipedia-tl"
]
}
},
"tr": {
"default": {
"visibleDefaultEngines": [
@ -725,7 +704,7 @@
"zh-TW": {
"default": {
"visibleDefaultEngines": [
"google", "yahoo-zh-TW", "ddg", "findbook-zh-TW", "wikipedia-zh-TW", "yahoo-zh-TW-HK", "yahoo-bid-zh-TW", "yahoo-answer-zh-TW"
"yahoo-zh-TW", "google", "ddg", "findbook-zh-TW", "wikipedia-zh-TW", "yahoo-zh-TW-HK", "yahoo-bid-zh-TW", "yahoo-answer-zh-TW"
]
}
}

View File

@ -58,6 +58,7 @@ external_dirs += [
'media/libspeex_resampler',
'media/libstagefright',
'media/libsoundtouch',
'media/psshparser'
]
DIRS += ['../../' + i for i in external_dirs]

View File

@ -1023,7 +1023,7 @@ public:
}
enum ETabFocusType {
//eTabFocus_textControlsMask = (1<<0), // unused - textboxes always tabbable
eTabFocus_textControlsMask = (1<<0), // textboxes and lists always tabbable
eTabFocus_formElementsMask = (1<<1), // non-text form elements
eTabFocus_linksMask = (1<<2), // links
eTabFocus_any = 1 + (1<<1) + (1<<2) // everything that can be focused

View File

@ -892,6 +892,10 @@ nsXMLContentSerializer::AppendElementStart(Element* aElement,
bool forceFormat = false;
nsresult rv = NS_OK;
if (!CheckElementStart(content, forceFormat, aStr, rv)) {
// When we go to AppendElementEnd for this element, we're going to
// MaybeLeaveFromPreContent(). So make sure to MaybeEnterInPreContent()
// now, so our PreLevel() doesn't get confused.
MaybeEnterInPreContent(content);
return rv;
}
@ -1040,8 +1044,11 @@ nsXMLContentSerializer::AppendElementEnd(Element* aElement,
}
if (!outputElementEnd) {
// Keep this in sync with the cleanup at the end of this method.
PopNameSpaceDeclsFor(aElement);
MaybeLeaveFromPreContent(content);
MaybeFlagNewlineForRootNode(aElement);
AfterElementEnd(content, aStr);
return NS_OK;
}
@ -1085,6 +1092,7 @@ nsXMLContentSerializer::AppendElementEnd(Element* aElement,
NS_ENSURE_TRUE(AppendToString(tagLocalName, aStr), NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(AppendToString(kGreaterThan, aStr), NS_ERROR_OUT_OF_MEMORY);
// Keep what follows in sync with the cleanup in the !outputElementEnd case.
PopNameSpaceDeclsFor(aElement);
MaybeLeaveFromPreContent(content);

View File

@ -35,10 +35,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -45,14 +45,11 @@ var d = a < b && a > c;
<!-- test on
comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla
at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />
leo ut libero
<!-- empty element: end tag should be generated for backward compatibility with HTML -->

View File

@ -43,10 +43,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -43,10 +43,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -43,10 +43,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -43,10 +43,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -40,13 +40,14 @@ var d = a < b && a > c;
Donec sollicitudin tortor
<!-- test on
comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
<pre>lacinia <em>libero</em> ullamcorper laoreet.
Cras quis
nisi at odio
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum,
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -43,10 +43,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -35,10 +35,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -46,10 +46,7 @@ comments -->
<pre>lacinia <em>libero</em> ullamcorper laoreet.<br />
Cras quis<br />
nisi at odio<br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non
urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at
pharetra rutrum, <br />
consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br />
lacus risus pulvinar ante.
</pre>
ut gravida eros <br />leo ut libero

View File

@ -11,9 +11,10 @@
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422043">Mozilla Bug </a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="testframe" src="file_xhtmlserializer_1.xhtml">
</iframe>
</div>
<!-- IMPORTANT: This iframe needs to actually be displayed, so the serializer
sees the relevant styles for <pre> elements. -->
<iframe id="testframe" src="file_xhtmlserializer_1.xhtml"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">

View File

@ -41,11 +41,12 @@ def memberXrayExpandoReservedSlot(member, descriptor):
member.slotIndices[descriptor.interface.identifier.name])
def mayUseXrayExpandoSlots(attr):
def mayUseXrayExpandoSlots(descriptor, attr):
assert not attr.getExtendedAttribute("NewObject")
# For attributes whose type is a Gecko interface we always use
# slots on the reflector for caching.
return not attr.type.isGeckoInterface()
# slots on the reflector for caching. Also, for interfaces that
# don't want Xrays we obviously never use the Xray expando slot.
return descriptor.wantsXrays and not attr.type.isGeckoInterface()
def toStringBool(arg):
@ -7602,7 +7603,7 @@ class CGPerSignatureCall(CGThing):
""",
maybeWrap=getMaybeWrapValueFuncForType(self.idlNode.type))
checkForXray = mayUseXrayExpandoSlots(self.idlNode)
checkForXray = mayUseXrayExpandoSlots(self.descriptor, self.idlNode)
# For the case of Cached attributes, go ahead and preserve our
# wrapper if needed. We need to do this because otherwise the
@ -8788,7 +8789,7 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
# Since [Cached] and [StoreInSlot] cannot be used with "NewObject",
# we know that in the interface type case the returned object is
# wrappercached. So creating Xrays to it is reasonable.
if mayUseXrayExpandoSlots(self.attr):
if mayUseXrayExpandoSlots(self.descriptor, self.attr):
prefix = fill(
"""
// Have to either root across the getter call or reget after.

View File

@ -17,7 +17,6 @@ support-files =
disabled = disabled
[test_pointerevent_constructor.html]
support-files = pointerevent_constructor.html
disabled = should be investigated
[test_pointerevent_element_haspointercapture-manual.html]
support-files = pointerevent_element_haspointercapture-manual.html
[test_pointerevent_element_haspointercapture_release_pending_capture-manual.html]

View File

@ -6,6 +6,7 @@
#include "CrashReporterParent.h"
#include "mozilla/Sprintf.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/ipc/CrashReporterHost.h"
#include "nsAutoPtr.h"
#include "nsXULAppAPI.h"
#include <time.h>
@ -22,6 +23,8 @@
namespace mozilla {
namespace dom {
using namespace mozilla::ipc;
void
CrashReporterParent::AnnotateCrashReport(const nsCString& key,
const nsCString& data)
@ -94,7 +97,7 @@ CrashReporterParent::SetChildData(const NativeThreadId& tid,
{
mInitialized = true;
mMainThread = tid;
mProcessType = processType;
mProcessType = GeckoProcessType(processType);
}
#ifdef MOZ_CRASHREPORTER
@ -162,74 +165,7 @@ CrashReporterParent::FinalizeChildData()
{
MOZ_ASSERT(mInitialized);
if (NS_IsMainThread()) {
// Inline, this is the main thread. Get this done.
NotifyCrashService();
return;
}
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
class NotifyOnMainThread : public Runnable
{
public:
explicit NotifyOnMainThread(CrashReporterParent* aCR)
: mCR(aCR)
{ }
NS_IMETHOD Run() override {
mCR->NotifyCrashService();
return NS_OK;
}
private:
CrashReporterParent* mCR;
};
SyncRunnable::DispatchToThread(mainThread, new NotifyOnMainThread(this));
}
void
CrashReporterParent::NotifyCrashService()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mChildDumpID.IsEmpty());
nsCOMPtr<nsICrashService> crashService =
do_GetService("@mozilla.org/crashservice;1");
if (!crashService) {
return;
}
int32_t processType;
int32_t crashType = nsICrashService::CRASH_TYPE_CRASH;
nsCString telemetryKey;
switch (mProcessType) {
case GeckoProcessType_Content:
processType = nsICrashService::PROCESS_TYPE_CONTENT;
telemetryKey.AssignLiteral("content");
break;
case GeckoProcessType_Plugin: {
processType = nsICrashService::PROCESS_TYPE_PLUGIN;
telemetryKey.AssignLiteral("plugin");
nsAutoCString val;
if (mNotes.Get(NS_LITERAL_CSTRING("PluginHang"), &val) &&
val.Equals(NS_LITERAL_CSTRING("1"))) {
crashType = nsICrashService::CRASH_TYPE_HANG;
telemetryKey.AssignLiteral("pluginhang");
}
break;
}
case GeckoProcessType_GMPlugin:
processType = nsICrashService::PROCESS_TYPE_GMPLUGIN;
telemetryKey.AssignLiteral("gmplugin");
break;
default:
NS_ERROR("unknown process type");
return;
}
crashService->AddCrash(processType, crashType, mChildDumpID);
Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1);
CrashReporterHost::NotifyCrashService(mProcessType, mChildDumpID, &mNotes);
mNotes.Clear();
}
#endif

View File

@ -178,7 +178,7 @@ public:
NativeThreadId mMainThread;
time_t mStartTime;
// stores the child process type
uint32_t mProcessType;
GeckoProcessType mProcessType;
bool mInitialized;
};

View File

@ -144,6 +144,7 @@ LOCAL_INCLUDES += [
'/layout/base',
'/media/webrtc',
'/netwerk/base',
'/toolkit/crashreporter',
'/toolkit/xre',
'/uriloader/exthandler',
'/widget',

View File

@ -239,6 +239,7 @@ bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
data.mPicY = aPicture.y;
data.mPicSize = aPicture.Size();
data.mStereoMode = aInfo.mStereoMode;
data.mYUVColorSpace = aBuffer.mYUVColorSpace;
aVideoImage->SetDelayedConversion(true);
if (aCopyData) {

View File

@ -6,10 +6,11 @@
#if !defined(MediaData_h)
#define MediaData_h
#include "AudioSampleFormat.h"
#include "ImageTypes.h"
#include "nsSize.h"
#include "mozilla/gfx/Rect.h"
#include "nsRect.h"
#include "AudioSampleFormat.h"
#include "nsIMemoryReporter.h"
#include "SharedBuffer.h"
#include "mozilla/RefPtr.h"
@ -443,6 +444,7 @@ public:
};
Plane mPlanes[3];
YUVColorSpace mYUVColorSpace = YUVColorSpace::BT601;
};
// Constructs a VideoData object. If aImage is nullptr, creates a new Image

View File

@ -10,6 +10,8 @@
#include "mozilla/dom/MediaKeyMessageEvent.h"
#include "mozilla/dom/MediaEncryptedEvent.h"
#include "mozilla/dom/MediaKeyStatusMap.h"
#include "mozilla/dom/MediaKeySystemAccess.h"
#include "mozilla/dom/KeyIdsInitDataBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/CDMProxy.h"
#include "mozilla/AsyncEventDispatcher.h"
@ -18,6 +20,7 @@
#include "mozilla/EMEUtils.h"
#include "GMPUtils.h"
#include "nsPrintfCString.h"
#include "psshparser/PsshParser.h"
namespace mozilla {
namespace dom {
@ -39,6 +42,15 @@ NS_IMPL_RELEASE_INHERITED(MediaKeySession, DOMEventTargetHelper)
// unique token.
static uint32_t sMediaKeySessionNum = 0;
// Max length of keyId in EME "keyIds" or WebM init data format, as enforced
// by web platform tests.
static const uint32_t MAX_KEY_ID_LENGTH = 512;
// Max length of CENC PSSH init data tolerated, as enforced by web
// platform tests.
static const uint32_t MAX_CENC_INIT_DATA_LENGTH = 64 * 1024;
MediaKeySession::MediaKeySession(JSContext* aCx,
nsPIDOMWindowInner* aParent,
MediaKeys* aKeys,
@ -160,6 +172,58 @@ MediaKeySession::KeyStatuses() const
return mKeyStatusMap;
}
// The user agent MUST thoroughly validate the Initialization Data before
// passing it to the CDM. This includes verifying that the length and
// values of fields are reasonable, verifying that values are within
// reasonable limits, and stripping irrelevant, unsupported, or unknown
// data or fields. It is RECOMMENDED that user agents pre-parse, sanitize,
// and/or generate a fully sanitized version of the Initialization Data.
// If the Initialization Data format specified by initDataType supports
// multiple entries, the user agent SHOULD remove entries that are not
// needed by the CDM. The user agent MUST NOT re-order entries within
// the Initialization Data.
static bool
ValidateInitData(const nsTArray<uint8_t>& aInitData, const nsAString& aInitDataType)
{
if (aInitDataType.LowerCaseEqualsLiteral("webm")) {
// WebM initData consists of a single keyId. Ensure it's of reasonable length.
return aInitData.Length() <= MAX_KEY_ID_LENGTH;
} else if (aInitDataType.LowerCaseEqualsLiteral("cenc")) {
// Limit initData to less than 64KB.
if (aInitData.Length() > MAX_CENC_INIT_DATA_LENGTH) {
return false;
}
std::vector<std::vector<uint8_t>> keyIds;
return ParseCENCInitData(aInitData.Elements(), aInitData.Length(), keyIds);
} else if (aInitDataType.LowerCaseEqualsLiteral("keyids")) {
if (aInitData.Length() > MAX_KEY_ID_LENGTH) {
return false;
}
// Ensure that init data matches the expected JSON format.
mozilla::dom::KeyIdsInitData keyIds;
nsString json;
nsDependentCSubstring raw(reinterpret_cast<const char*>(aInitData.Elements()), aInitData.Length());
if (NS_FAILED(nsContentUtils::ConvertStringFromEncoding(NS_LITERAL_CSTRING("UTF-8"), raw, json))) {
return false;
}
if (!keyIds.Init(json)) {
return false;
}
if (keyIds.mKids.Length() == 0) {
return false;
}
for (const auto& kid : keyIds.mKids) {
if (kid.IsEmpty()) {
return false;
}
}
}
return true;
}
// Generates a license request based on the initData. A message of type
// "license-request" or "individualization-request" will always be queued
// if the algorithm succeeds and the promise is resolved.
already_AddRefed<Promise>
MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
const ArrayBufferViewOrArrayBuffer& aInitData,
@ -171,16 +235,30 @@ MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
return nullptr;
}
// If this object is closed, return a promise rejected with an InvalidStateError.
if (IsClosed()) {
EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, closed",
this, NS_ConvertUTF16toUTF8(mSessionId).get());
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Session is closed in MediaKeySession.generateRequest()"));
return promise.forget();
}
// If this object's uninitialized value is false, return a promise rejected
// with an InvalidStateError.
if (!mUninitialized) {
EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, uninitialized",
this, NS_ConvertUTF16toUTF8(mSessionId).get());
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.generateRequest()"));
return promise.forget();
}
// Let this object's uninitialized value be false.
mUninitialized = false;
// If initDataType is the empty string, return a promise rejected
// with a newly created TypeError.
if (aInitDataType.IsEmpty()) {
promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
NS_LITERAL_CSTRING("Empty initDataType passed to MediaKeySession.generateRequest()"));
@ -189,16 +267,56 @@ MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
return promise.forget();
}
// If initData is an empty array, return a promise rejected with
// a newly created TypeError.
nsTArray<uint8_t> data;
CopyArrayBufferViewOrArrayBufferData(aInitData, data);
if (data.IsEmpty()) {
promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
NS_LITERAL_CSTRING("Empty initData passed to MediaKeySession.generateRequest()"));
EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initData",
this, NS_ConvertUTF16toUTF8(mSessionId).get());
this, NS_ConvertUTF16toUTF8(mSessionId).get());
return promise.forget();
}
// If the Key System implementation represented by this object's
// cdm implementation value does not support initDataType as an
// Initialization Data Type, return a promise rejected with a
// NotSupportedError. String comparison is case-sensitive.
if (!MediaKeySystemAccess::KeySystemSupportsInitDataType(mKeySystem, aInitDataType)) {
promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("Unsupported initDataType passed to MediaKeySession.generateRequest()"));
EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, unsupported initDataType",
this, NS_ConvertUTF16toUTF8(mSessionId).get());
return promise.forget();
}
// Let init data be a copy of the contents of the initData parameter.
// Note: Handled by the CopyArrayBufferViewOrArrayBufferData call above.
// Let session type be this object's session type.
// Let promise be a new promise.
// Run the following steps in parallel:
// If the init data is not valid for initDataType, reject promise with
// a newly created TypeError.
if (!ValidateInitData(data, aInitDataType)) {
// If the preceding step failed, reject promise with a newly created TypeError.
promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
NS_LITERAL_CSTRING("initData sanitization failed in MediaKeySession.generateRequest()"));
EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() initData sanitization failed",
this, NS_ConvertUTF16toUTF8(mSessionId).get());
return promise.forget();
}
// Let sanitized init data be a validated and sanitized version of init data.
// If sanitized init data is empty, reject promise with a NotSupportedError.
// Note: Remaining steps of generateRequest method continue in CDM.
Telemetry::Accumulate(Telemetry::VIDEO_CDM_GENERATE_REQUEST_CALLED,
ToCDMTypeTelemetryEnum(mKeySystem));

View File

@ -512,6 +512,16 @@ GetKeySystemConfig(const nsAString& aKeySystem)
return nullptr;
}
/* static */
bool
MediaKeySystemAccess::KeySystemSupportsInitDataType(const nsAString& aKeySystem,
const nsAString& aInitDataType)
{
const KeySystemConfig* implementation = GetKeySystemConfig(aKeySystem);
return implementation &&
implementation->mInitDataTypes.Contains(aInitDataType);
}
enum CodecType
{
Audio,

View File

@ -75,6 +75,9 @@ public:
MediaKeySystemConfiguration& aOutConfig,
DecoderDoctorDiagnostics* aDiagnostics);
static bool KeySystemSupportsInitDataType(const nsAString& aKeySystem,
const nsAString& aInitDataType);
private:
nsCOMPtr<nsPIDOMWindowInner> mParent;
const nsString mKeySystem;

View File

@ -86,16 +86,22 @@ FFmpegLibWrapper::Link()
return false;
}
#define AV_FUNC(func, ver) \
if ((ver) & version) { \
#define AV_FUNC_OPTION(func, ver) \
if ((ver) & version) { \
if (!(func = (decltype(func))PR_FindSymbol(((ver) & AV_FUNC_AVUTIL_MASK) ? mAVUtilLib : mAVCodecLib, #func))) { \
FFMPEG_LOG("Couldn't load function " # func); \
Unlink(); \
return false; \
} \
} else { \
func = (decltype(func))nullptr; \
}
#define AV_FUNC(func, ver) \
AV_FUNC_OPTION(func, ver) \
if ((ver) & version && !func) { \
Unlink(); \
return false; \
}
AV_FUNC(av_lockmgr_register, AV_FUNC_AVCODEC_ALL)
AV_FUNC(avcodec_alloc_context3, AV_FUNC_AVCODEC_ALL)
AV_FUNC(avcodec_close, AV_FUNC_AVCODEC_ALL)
@ -118,7 +124,9 @@ FFmpegLibWrapper::Link()
AV_FUNC(av_frame_alloc, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
AV_FUNC(av_frame_free, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
AV_FUNC(av_frame_unref, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
AV_FUNC_OPTION(av_frame_get_colorspace, AV_FUNC_AVUTIL_ALL)
#undef AV_FUNC
#undef AV_FUNC_OPTION
avcodec_register_all();
#ifdef DEBUG

View File

@ -67,6 +67,9 @@ struct FFmpegLibWrapper
void (*av_frame_free)(AVFrame** frame);
void (*av_frame_unref)(AVFrame* frame);
// libavutil optional
int (*av_frame_get_colorspace)(const AVFrame *frame);
PRLibrary* mAVCodecLib;
PRLibrary* mAVUtilLib;

View File

@ -301,7 +301,19 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = (mFrame->height + 1) >> 1;
}
if (mLib->av_frame_get_colorspace) {
switch (mLib->av_frame_get_colorspace(mFrame)) {
case AVCOL_SPC_BT709:
b.mYUVColorSpace = YUVColorSpace::BT709;
break;
case AVCOL_SPC_SMPTE170M:
case AVCOL_SPC_BT470BG:
b.mYUVColorSpace = YUVColorSpace::BT601;
break;
default:
NS_WARNING("Unsupported yuv color space.");
}
}
RefPtr<VideoData> v =
VideoData::CreateAndCopyData(mInfo,
mImageContainer,

View File

@ -32,7 +32,8 @@ namespace mozilla {
NS_IMPL_ISUPPORTS(LoadManagerSingleton, nsIObserver)
LoadManagerSingleton::LoadManagerSingleton(int aLoadMeasurementInterval,
LoadManagerSingleton::LoadManagerSingleton(bool aEncoderOnly,
int aLoadMeasurementInterval,
int aAveragingMeasurements,
float aHighLoadThreshold,
float aLowLoadThreshold)
@ -50,9 +51,11 @@ LoadManagerSingleton::LoadManagerSingleton(int aLoadMeasurementInterval,
mLoadMeasurementInterval, mAveragingMeasurements,
mHighLoadThreshold, mLowLoadThreshold));
MOZ_ASSERT(mHighLoadThreshold > mLowLoadThreshold);
mLoadMonitor = new LoadMonitor(mLoadMeasurementInterval);
mLoadMonitor->Init(mLoadMonitor);
mLoadMonitor->SetLoadChangeCallback(this);
if (!aEncoderOnly) {
mLoadMonitor = new LoadMonitor(mLoadMeasurementInterval);
mLoadMonitor->Init(mLoadMonitor);
mLoadMonitor->SetLoadChangeCallback(this);
}
mLastStateChange = TimeStamp::Now();
for (auto &in_state : mTimeInState) {
@ -181,36 +184,36 @@ LoadManagerSingleton::RemoveObserver(webrtc::CPULoadStateObserver * aObserver)
LOG(("LoadManager - Element to remove not found"));
}
if (mObservers.Length() == 0) {
// Record how long we spent in the final state for later Telemetry or display
TimeStamp now = TimeStamp::Now();
mTimeInState[mCurrentState] += (now - mLastStateChange).ToMilliseconds();
float total = 0;
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mTimeInState); i++) {
total += mTimeInState[i];
}
// Don't include short calls; we don't have reasonable load data, and
// such short calls rarely reach a stable state. Keep relatively
// short calls separate from longer ones
bool log = total > 5*PR_MSEC_PER_SEC;
bool small = log && total < 30*PR_MSEC_PER_SEC;
if (log) {
// Note: We don't care about rounding here; thus total may be < 100
Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_RELAXED_SHORT :
Telemetry::WEBRTC_LOAD_STATE_RELAXED,
(uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadRelaxed]/total * 100));
Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_NORMAL_SHORT :
Telemetry::WEBRTC_LOAD_STATE_NORMAL,
(uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadNormal]/total * 100));
Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_STRESSED_SHORT :
Telemetry::WEBRTC_LOAD_STATE_STRESSED,
(uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadStressed]/total * 100));
}
for (auto &in_state : mTimeInState) {
in_state = 0;
}
if (mLoadMonitor) {
// Record how long we spent in the final state for later Telemetry or display
TimeStamp now = TimeStamp::Now();
mTimeInState[mCurrentState] += (now - mLastStateChange).ToMilliseconds();
float total = 0;
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mTimeInState); i++) {
total += mTimeInState[i];
}
// Don't include short calls; we don't have reasonable load data, and
// such short calls rarely reach a stable state. Keep relatively
// short calls separate from longer ones
bool log = total > 5*PR_MSEC_PER_SEC;
bool small = log && total < 30*PR_MSEC_PER_SEC;
if (log) {
// Note: We don't care about rounding here; thus total may be < 100
Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_RELAXED_SHORT :
Telemetry::WEBRTC_LOAD_STATE_RELAXED,
(uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadRelaxed]/total * 100));
Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_NORMAL_SHORT :
Telemetry::WEBRTC_LOAD_STATE_NORMAL,
(uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadNormal]/total * 100));
Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_STRESSED_SHORT :
Telemetry::WEBRTC_LOAD_STATE_STRESSED,
(uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadStressed]/total * 100));
}
for (auto &in_state : mTimeInState) {
in_state = 0;
}
// Dance to avoid deadlock on mLock!
RefPtr<LoadMonitor> loadMonitor = mLoadMonitor.forget();
MutexAutoUnlock unlock(mLock);

View File

@ -44,7 +44,8 @@ public:
void RemoveObserver(webrtc::CPULoadStateObserver * aObserver) override;
private:
LoadManagerSingleton(int aLoadMeasurementInterval,
LoadManagerSingleton(bool aEncoderOnly,
int aLoadMeasurementInterval,
int aAveragingMeasurements,
float aHighLoadThreshold,
float aLowLoadThreshold);

View File

@ -24,6 +24,8 @@ LoadManagerSingleton::Get() {
if (!sSingleton) {
MOZ_ASSERT(NS_IsMainThread());
bool loadEncoderOnly =
mozilla::Preferences::GetBool("media.navigator.load_adapt.encoder_only", true);
int loadMeasurementInterval =
mozilla::Preferences::GetInt("media.navigator.load_adapt.measure_interval", 1000);
int averagingSeconds =
@ -33,7 +35,8 @@ LoadManagerSingleton::Get() {
float lowLoadThreshold =
mozilla::Preferences::GetFloat("media.navigator.load_adapt.low_load", 0.40f);
sSingleton = new LoadManagerSingleton(loadMeasurementInterval,
sSingleton = new LoadManagerSingleton(loadEncoderOnly,
loadMeasurementInterval,
averagingSeconds,
highLoadThreshold,
lowLoadThreshold);

View File

@ -769,7 +769,7 @@ PluginInstanceParent::RecvShowDirectBitmap(Shmem&& buffer,
RefPtr<TextureClient> texture = allocator->CreateOrRecycle(
format, size, BackendSelector::Content,
TextureFlags::NO_FLAGS,
ALLOC_FOR_OUT_OF_BAND_CONTENT);
TextureAllocationFlags(ALLOC_FOR_OUT_OF_BAND_CONTENT | ALLOC_UPDATE_FROM_SURFACE));
if (!texture) {
NS_WARNING("Could not allocate a TextureClient for plugin!");
return false;
@ -836,7 +836,7 @@ PluginInstanceParent::RecvShowDirectDXGISurface(const WindowsHandle& handle,
surface->GetFormat(), surface->GetSize(),
BackendSelector::Content,
TextureFlags::NO_FLAGS,
ALLOC_FOR_OUT_OF_BAND_CONTENT);
TextureAllocationFlags(ALLOC_FOR_OUT_OF_BAND_CONTENT | ALLOC_UPDATE_FROM_SURFACE));
if (!texture) {
NS_WARNING("Could not allocate a TextureClient for plugin!");
return false;

View File

@ -1197,6 +1197,8 @@ var interfaceNamesInGlobalScope =
{name: "VREyeParameters", release: false},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "VRFieldOfView", release: false},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "VRFrameData", release: false},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "VRPose", release: false},
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -299,11 +299,24 @@ VRPose::VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
, mAngularVelocity(nullptr)
, mAngularAcceleration(nullptr)
{
mTimeStamp = aState.timestamp * 1000.0f; // Converting from seconds to ms
mFrameId = aState.inputFrameID;
mozilla::HoldJSObjects(this);
}
VRPose::VRPose(nsISupports* aParent)
: mParent(aParent)
, mPosition(nullptr)
, mLinearVelocity(nullptr)
, mLinearAcceleration(nullptr)
, mOrientation(nullptr)
, mAngularVelocity(nullptr)
, mAngularAcceleration(nullptr)
{
mFrameId = 0;
mVRState.Clear();
mozilla::HoldJSObjects(this);
}
VRPose::~VRPose()
{
mozilla::DropJSObjects(this);
@ -491,6 +504,15 @@ VRDisplay::GetStageParameters()
return mStageParameters;
}
bool
VRDisplay::GetFrameData(VRFrameData& aFrameData)
{
gfx::VRHMDSensorState state = mClient->GetSensorState();
const gfx::VRDisplayInfo& info = mClient->GetDisplayInfo();
aFrameData.Update(info, state, mDepthNear, mDepthFar);
return true;
}
already_AddRefed<VRPose>
VRDisplay::GetPose()
{
@ -500,15 +522,6 @@ VRDisplay::GetPose()
return obj.forget();
}
already_AddRefed<VRPose>
VRDisplay::GetImmediatePose()
{
gfx::VRHMDSensorState state = mClient->GetImmediateSensorState();
RefPtr<VRPose> obj = new VRPose(GetParentObject(), state);
return obj.forget();
}
void
VRDisplay::ResetPose()
{
@ -530,7 +543,7 @@ VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, nullptr);
if (IsPresenting()) {
if (mClient->GetIsPresenting()) {
// Only one presentation allowed per VRDisplay
// on a first-come-first-serve basis.
promise->MaybeRejectWithUndefined();
@ -581,12 +594,20 @@ VRDisplay::ExitPresent(ErrorResult& aRv)
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
ExitPresentInternal();
RefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
promise->MaybeResolve(JS::UndefinedHandleValue);
if (!IsPresenting()) {
// We can not exit a presentation outside of the context that
// started the presentation.
promise->MaybeRejectWithUndefined();
} else {
promise->MaybeResolve(JS::UndefinedHandleValue);
ExitPresentInternal();
}
return promise.forget();
}
@ -640,7 +661,9 @@ VRDisplay::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError)
bool
VRDisplay::IsPresenting() const
{
return mClient->GetIsPresenting();
// IsPresenting returns true only if this Javascript context is presenting
// and will return false if another context is presenting.
return mPresentation != nullptr;
}
bool
@ -659,5 +682,174 @@ NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMEventTargetHelper)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_CLASS(VRFrameData)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRFrameData)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mPose)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
tmp->mLeftProjectionMatrix = nullptr;
tmp->mLeftViewMatrix = nullptr;
tmp->mRightProjectionMatrix = nullptr;
tmp->mRightViewMatrix = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRFrameData)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mPose)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRFrameData)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftProjectionMatrix)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftViewMatrix)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightProjectionMatrix)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightViewMatrix)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFrameData, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFrameData, Release)
VRFrameData::VRFrameData(nsISupports* aParent)
: mParent(aParent)
, mLeftProjectionMatrix(nullptr)
, mLeftViewMatrix(nullptr)
, mRightProjectionMatrix(nullptr)
, mRightViewMatrix(nullptr)
{
mPose = new VRPose(aParent);
}
VRFrameData::~VRFrameData()
{
mozilla::DropJSObjects(this);
}
/* static */ already_AddRefed<VRFrameData>
VRFrameData::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{
RefPtr<VRFrameData> obj = new VRFrameData(aGlobal.GetAsSupports());
return obj.forget();
}
JSObject*
VRFrameData::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return VRFrameDataBinding::Wrap(aCx, this, aGivenProto);
}
VRPose*
VRFrameData::Pose()
{
return mPose;
}
void
VRFrameData::LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat, JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
{
if (!aArray) {
// Lazily create the Float32Array
aArray = dom::Float32Array::Create(aCx, this, 16, aMat.components);
if (!aArray) {
aRv.NoteJSContextException(aCx);
return;
}
}
if (aArray) {
JS::ExposeObjectToActiveJS(aArray);
}
aRetval.set(aArray);
}
double
VRFrameData::Timestamp() const
{
return mVRState.timestamp * 1000.0f; // Converting from seconds to milliseconds
}
void
VRFrameData::GetLeftProjectionMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
LazyCreateMatrix(mLeftProjectionMatrix, mLeftProjection, aCx, aRetval, aRv);
}
void
VRFrameData::GetLeftViewMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
LazyCreateMatrix(mLeftViewMatrix, mLeftView, aCx, aRetval, aRv);
}
void
VRFrameData::GetRightProjectionMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
LazyCreateMatrix(mRightProjectionMatrix, mRightProjection, aCx, aRetval, aRv);
}
void
VRFrameData::GetRightViewMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
LazyCreateMatrix(mRightViewMatrix, mRightView, aCx, aRetval, aRv);
}
void
VRFrameData::Update(const gfx::VRDisplayInfo& aInfo,
const gfx::VRHMDSensorState& aState,
float aDepthNear,
float aDepthFar)
{
mVRState = aState;
mLeftProjectionMatrix = nullptr;
mLeftViewMatrix = nullptr;
mRightProjectionMatrix = nullptr;
mRightViewMatrix = nullptr;
mPose = new VRPose(GetParentObject(), aState);
gfx::Quaternion qt;
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
qt.x = mVRState.orientation[0];
qt.y = mVRState.orientation[1];
qt.z = mVRState.orientation[2];
qt.w = mVRState.orientation[3];
}
gfx::Point3D pos;
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
pos.x = -mVRState.position[0];
pos.y = -mVRState.position[1];
pos.z = -mVRState.position[2];
}
gfx::Matrix4x4 matHead;
matHead.SetRotationFromQuaternion(qt);
matHead.PreTranslate(pos);
mLeftView = matHead;
mLeftView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Left]);
mRightView = matHead;
mRightView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Right]);
// Avoid division by zero within ConstructProjectionMatrix
const float kEpsilon = 0.00001f;
if (fabs(aDepthFar - aDepthNear) < kEpsilon) {
aDepthFar = aDepthNear + kEpsilon;
}
const gfx::VRFieldOfView leftFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Left];
mLeftProjection = leftFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
const gfx::VRFieldOfView rightFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Right];
mRightProjection = rightFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
}
} // namespace dom
} // namespace mozilla

View File

@ -100,11 +100,11 @@ class VRPose final : public nsWrapperCache
public:
VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
explicit VRPose(nsISupports* aParent);
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRPose)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRPose)
double Timestamp() const { return mTimeStamp; }
uint32_t FrameID() const { return mFrameId; }
void GetPosition(JSContext* aCx,
@ -133,7 +133,6 @@ protected:
~VRPose();
nsCOMPtr<nsISupports> mParent;
double mTimeStamp;
uint32_t mFrameId;
gfx::VRHMDSensorState mVRState;
@ -146,6 +145,63 @@ protected:
};
class VRFrameData final : public nsWrapperCache
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFrameData)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFrameData)
explicit VRFrameData(nsISupports* aParent);
static already_AddRefed<VRFrameData> Constructor(const GlobalObject& aGlobal,
ErrorResult& aRv);
void Update(const gfx::VRDisplayInfo& aInfo,
const gfx::VRHMDSensorState& aState,
float aDepthNear,
float aDepthFar);
// WebIDL Members
double Timestamp() const;
void GetLeftProjectionMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
void GetLeftViewMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
void GetRightProjectionMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
void GetRightViewMatrix(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
VRPose* Pose();
// WebIDL Boilerplate
nsISupports* GetParentObject() const { return mParent; }
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
~VRFrameData();
nsCOMPtr<nsISupports> mParent;
gfx::VRHMDSensorState mVRState;
RefPtr<VRPose> mPose;
JS::Heap<JSObject*> mLeftProjectionMatrix;
JS::Heap<JSObject*> mLeftViewMatrix;
JS::Heap<JSObject*> mRightProjectionMatrix;
JS::Heap<JSObject*> mRightViewMatrix;
gfx::Matrix4x4 mLeftProjection;
gfx::Matrix4x4 mLeftView;
gfx::Matrix4x4 mRightProjection;
gfx::Matrix4x4 mRightView;
void LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat,
JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
};
class VRStageParameters final : public nsWrapperCache
{
public:
@ -237,8 +293,8 @@ public:
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye);
bool GetFrameData(VRFrameData& aFrameData);
already_AddRefed<VRPose> GetPose();
already_AddRefed<VRPose> GetImmediatePose();
void ResetPose();
double DepthNear() {

View File

@ -0,0 +1,11 @@
/* -*- Mode: IDL; tab-width: 2; 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/.
*/
// "KeyIds" EME init data format definition/parser, as defined by
// https://w3c.github.io/encrypted-media/format-registry/initdata/keyids.html
dictionary KeyIdsInitData {
required sequence<DOMString> kids;
};

View File

@ -26,8 +26,8 @@ interface PointerEvent : MouseEvent
dictionary PointerEventInit : MouseEventInit
{
long pointerId = 0;
long width = 0;
long height = 0;
long width = 1;
long height = 1;
float pressure = 0;
long tiltX = 0;
long tiltY = 0;

View File

@ -117,8 +117,6 @@ interface VRStageParameters {
[Pref="dom.vr.enabled",
HeaderFile="mozilla/dom/VRDisplay.h"]
interface VRPose {
readonly attribute DOMHighResTimeStamp timestamp;
/**
* position, linearVelocity, and linearAcceleration are 3-component vectors.
* position is relative to a sitting space. Transforming this point with
@ -135,6 +133,21 @@ interface VRPose {
[Constant, Throws] readonly attribute Float32Array? angularAcceleration;
};
[Constructor,
Pref="dom.vr.enabled",
HeaderFile="mozilla/dom/VRDisplay.h"]
interface VRFrameData {
readonly attribute DOMHighResTimeStamp timestamp;
[Throws, Pure] readonly attribute Float32Array leftProjectionMatrix;
[Throws, Pure] readonly attribute Float32Array leftViewMatrix;
[Throws, Pure] readonly attribute Float32Array rightProjectionMatrix;
[Throws, Pure] readonly attribute Float32Array rightViewMatrix;
[Pure] readonly attribute VRPose pose;
};
[Pref="dom.vr.enabled",
HeaderFile="mozilla/dom/VRDisplay.h"]
interface VREyeParameters {
@ -189,6 +202,12 @@ interface VRDisplay : EventTarget {
*/
[Constant] readonly attribute DOMString displayName;
/**
* Populates the passed VRFrameData with the information required to render
* the current frame.
*/
boolean getFrameData(VRFrameData frameData);
/**
* Return a VRPose containing the future predicted pose of the VRDisplay
* when the current frame will be presented. Subsequent calls to getPose()
@ -200,13 +219,6 @@ interface VRDisplay : EventTarget {
*/
[NewObject] VRPose getPose();
/**
* Return the current instantaneous pose of the VRDisplay, with no
* prediction applied. Every call to getImmediatePose() may
* return a different value, even within a single frame.
*/
[NewObject] VRPose getImmediatePose();
/**
* Reset the pose for this display, treating its current position and
* orientation as the "origin/zero" values. VRPose.position,

View File

@ -293,6 +293,7 @@ WEBIDL_FILES = [
'KeyEvent.webidl',
'KeyframeAnimationOptions.webidl',
'KeyframeEffect.webidl',
'KeyIdsInitData.webidl',
'LegacyQueryInterface.webidl',
'LinkStyle.webidl',
'ListBoxObject.webidl',

View File

@ -1818,11 +1818,7 @@ XMLHttpRequestMainThread::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
nsAutoCString file;
nsAutoCString scheme;
uri->GetScheme(scheme);
if (scheme.LowerCaseEqualsLiteral("app")) {
uri->GetPath(file);
// The actual file inside zip package has no leading slash.
file.Trim("/", true, false, false);
} else if (scheme.LowerCaseEqualsLiteral("jar")) {
if (scheme.LowerCaseEqualsLiteral("jar")) {
nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(uri);
if (jarURI) {
jarURI->GetJAREntry(file);
@ -2897,8 +2893,7 @@ XMLHttpRequestMainThread::SendInternal(const RequestBodyBase* aBody)
rv = mChannel->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
uri->GetScheme(scheme);
if (scheme.LowerCaseEqualsLiteral("app") ||
scheme.LowerCaseEqualsLiteral("jar")) {
if (scheme.LowerCaseEqualsLiteral("jar")) {
mIsMappedArrayBuffer = true;
}
}

View File

@ -12,6 +12,7 @@
#if defined(XP_WIN)
# include "mozilla/gfx/DeviceManagerDx.h"
#endif
#include "mozilla/ipc/CrashReporterHost.h"
namespace mozilla {
namespace gfx {
@ -113,9 +114,27 @@ GPUChild::RecvGraphicsError(const nsCString& aError)
return true;
}
bool
GPUChild::RecvInitCrashReporter(Shmem&& aShmem)
{
#ifdef MOZ_CRASHREPORTER
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_GPU, aShmem);
#endif
return true;
}
void
GPUChild::ActorDestroy(ActorDestroyReason aWhy)
{
if (aWhy == AbnormalShutdown) {
#ifdef MOZ_CRASHREPORTER
if (mCrashReporter) {
mCrashReporter->GenerateCrashReport(OtherPid());
mCrashReporter = nullptr;
}
#endif
}
gfxVars::RemoveReceiver(this);
mHost->OnChannelClosed();
}

View File

@ -12,6 +12,9 @@
#include "mozilla/gfx/gfxVarReceiver.h"
namespace mozilla {
namespace ipc {
class CrashReporterHost;
} // namespace
namespace gfx {
class GPUProcessHost;
@ -34,6 +37,7 @@ public:
// PGPUChild overrides.
bool RecvInitComplete(const GPUDeviceData& aData) override;
bool RecvReportCheckerboard(const uint32_t& aSeverity, const nsCString& aLog) override;
bool RecvInitCrashReporter(Shmem&& shmem) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
bool RecvGraphicsError(const nsCString& aError) override;
@ -41,6 +45,7 @@ public:
private:
GPUProcessHost* mHost;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
bool mGPUReady;
};

View File

@ -13,6 +13,7 @@
#include "GPUProcessHost.h"
#include "mozilla/Assertions.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/CrashReporterClient.h"
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/APZCTreeManager.h"
@ -27,6 +28,7 @@
#include "VRManager.h"
#include "VRManagerParent.h"
#include "VsyncBridgeParent.h"
#include "nsExceptionHandler.h"
#if defined(XP_WIN)
# include "DeviceManagerD3D9.h"
# include "mozilla/gfx/DeviceManagerDx.h"
@ -70,6 +72,11 @@ GPUParent::Init(base::ProcessId aParentPid,
nsDebugImpl::SetMultiprocessMode("GPU");
#ifdef MOZ_CRASHREPORTER
// Init crash reporter support.
CrashReporterClient::InitSingleton(this);
#endif
// Ensure gfxPrefs are initialized.
gfxPrefs::GetSingleton();
gfxConfig::Init();
@ -320,6 +327,9 @@ GPUParent::ActorDestroy(ActorDestroyReason aWhy)
gfxVars::Shutdown();
gfxConfig::Shutdown();
gfxPrefs::DestroySingleton();
#ifdef MOZ_CRASHREPORTER
CrashReporterClient::DestroySingleton();
#endif
NS_ShutdownXPCOM(nullptr);
XRE_ShutdownChildProcess();
}

View File

@ -942,6 +942,14 @@ struct ParamTraits<mozilla::StereoMode>
mozilla::StereoMode::MAX>
{};
template <>
struct ParamTraits<mozilla::YUVColorSpace>
: public ContiguousEnumSerializer<
mozilla::YUVColorSpace,
mozilla::YUVColorSpace::BT601,
mozilla::YUVColorSpace::UNKNOWN>
{};
template <>
struct ParamTraits<mozilla::layers::ScrollableLayerGuid>
{

View File

@ -78,6 +78,8 @@ child:
// Graphics errors, analogous to PContent::GraphicsError
async GraphicsError(nsCString aError);
async InitCrashReporter(Shmem shmem);
};
} // namespace gfx

View File

@ -68,7 +68,10 @@ IPDL_SOURCES = [
'PVsyncBridge.ipdl',
]
LOCAL_INCLUDES += ['/dom/ipc']
LOCAL_INCLUDES += [
'/dom/ipc',
'/toolkit/crashreporter',
]
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -158,6 +158,7 @@ BufferTextureData::CreateInternal(LayersIPCChannel* aAllocator,
BufferTextureData*
BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
int32_t aBufferSize,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags)
{
if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
@ -171,6 +172,7 @@ BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
// afterwards since we don't know the dimensions of the texture at this point.
BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), gfx::IntSize(),
0, 0, 0, StereoMode::MONO,
aYUVColorSpace,
hasIntermediateBuffer);
return CreateInternal(aAllocator->GetTextureForwarder(), desc, gfx::BackendType::NONE, aBufferSize,
@ -182,6 +184,7 @@ BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags)
{
uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(aYSize, aCbCrSize);
@ -201,7 +204,7 @@ BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
: true;
YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aCbCrSize, yOffset, cbOffset,
crOffset, aStereoMode,
crOffset, aStereoMode, aYUVColorSpace,
hasIntermediateBuffer);
return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr, descriptor,
@ -244,6 +247,12 @@ BufferTextureData::GetCbCrSize() const
return ImageDataSerializer::CbCrSizeFromBufferDescriptor(mDescriptor);
}
Maybe<YUVColorSpace>
BufferTextureData::GetYUVColorSpace() const
{
return ImageDataSerializer::YUVColorSpaceFromBufferDescriptor(mDescriptor);
}
Maybe<StereoMode>
BufferTextureData::GetStereoMode() const
{

View File

@ -32,6 +32,7 @@ public:
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags);
// It is generally better to use CreateForYCbCr instead.
@ -39,6 +40,7 @@ public:
// offsets in the buffer.
static BufferTextureData* CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
int32_t aSize,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags);
virtual bool Lock(OpenMode aMode, FenceHandle*) override { return true; }
@ -63,6 +65,8 @@ public:
Maybe<gfx::IntSize> GetCbCrSize() const;
Maybe<YUVColorSpace> GetYUVColorSpace() const;
Maybe<StereoMode> GetStereoMode() const;
protected:

View File

@ -688,6 +688,7 @@ struct PlanarYCbCrData {
uint32_t mPicY;
gfx::IntSize mPicSize;
StereoMode mStereoMode;
YUVColorSpace mYUVColorSpace;
gfx::IntRect GetPictureRect() const {
return gfx::IntRect(mPicX, mPicY,
@ -700,6 +701,7 @@ struct PlanarYCbCrData {
, mCbChannel(nullptr), mCrChannel(nullptr)
, mCbCrStride(0), mCbCrSize(0, 0) , mCbSkip(0), mCrSkip(0)
, mPicX(0), mPicY(0), mPicSize(0, 0), mStereoMode(StereoMode::MONO)
, mYUVColorSpace(YUVColorSpace::BT601)
{}
};

View File

@ -135,6 +135,20 @@ Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescri
}
}
Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor)
{
{
switch (aDescriptor.type()) {
case BufferDescriptor::TRGBDescriptor:
return Nothing();
case BufferDescriptor::TYCbCrDescriptor:
return Some(aDescriptor.get_YCbCrDescriptor().yUVColorSpace());
default:
MOZ_CRASH("GFX: CbCrSizeFromBufferDescriptor");
}
}
}
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
{
switch (aDescriptor.type()) {
@ -202,6 +216,7 @@ DataSourceSurfaceFromYCbCrDescriptor(uint8_t* aBuffer, const YCbCrDescriptor& aD
ycbcrData.mCbCrStride = cbCrStride;
ycbcrData.mCbCrSize = cbCrSize;
ycbcrData.mPicSize = ySize;
ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
gfx::ConvertYCbCrToRGB(ycbcrData,
gfx::SurfaceFormat::B8G8R8X8,
@ -236,6 +251,7 @@ ConvertAndScaleFromYCbCrDescriptor(uint8_t* aBuffer,
ycbcrData.mCbCrStride = cbCrStride;
ycbcrData.mCbCrSize = cbCrSize;
ycbcrData.mPicSize = ySize;
ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
gfx::ConvertYCbCrToRGB(ycbcrData, aDestFormat, aDestSize, aDestBuffer, aStride);
}

View File

@ -60,6 +60,8 @@ gfx::IntSize SizeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor);
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
uint8_t* GetYChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor);

View File

@ -115,6 +115,13 @@ enum class StereoMode {
MAX,
};
enum class YUVColorSpace {
BT601,
BT709,
// This represents the unknown format.
UNKNOWN,
};
} // namespace mozilla
#endif

View File

@ -123,6 +123,7 @@ ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwar
}
texture = TextureClient::CreateForYCbCr(aForwarder,
data->mYSize, data->mCbCrSize, data->mStereoMode,
data->mYUVColorSpace,
TextureFlags::DEFAULT);
if (!texture) {
return nullptr;
@ -231,7 +232,6 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
RefPtr<GonkNativeHandle::NhObj> nhObj = overlayImage->GetSidebandStream().GetDupNhObj();
GonkNativeHandle handle(nhObj);
if (!handle.IsValid()) {
gfxWarning() << "ImageClientSingle::UpdateImage failed in GetDupNhObj";
return false;
}
source.handle() = OverlayHandle(handle);

View File

@ -1280,6 +1280,7 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags)
{
// The only reason we allow aAllocator to be null is for gtests
@ -1293,7 +1294,8 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
}
TextureData* data = BufferTextureData::CreateForYCbCr(aAllocator, aYSize, aCbCrSize,
aStereoMode, aTextureFlags);
aStereoMode, aYUVColorSpace,
aTextureFlags);
if (!data) {
return nullptr;
}
@ -1306,6 +1308,7 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
already_AddRefed<TextureClient>
TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
size_t aSize,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags)
{
// also test the validity of aAllocator
@ -1315,7 +1318,7 @@ TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
}
TextureData* data =
BufferTextureData::CreateForYCbCrWithBufferSize(aAllocator, aSize,
BufferTextureData::CreateForYCbCrWithBufferSize(aAllocator, aSize, aYUVColorSpace,
aTextureFlags);
if (!data) {
return nullptr;

View File

@ -367,6 +367,7 @@ public:
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags);
// Creates and allocates a TextureClient (can be accessed through raw
@ -385,6 +386,7 @@ public:
static already_AddRefed<TextureClient>
CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
size_t aSize,
YUVColorSpace aYUVColorSpace,
TextureFlags aTextureFlags);
// Creates and allocates a TextureClient of the same type.

View File

@ -106,6 +106,8 @@ YCbCrTextureClientAllocationHelper::IsCompatible(TextureClient* aTextureClient)
aTextureClient->GetSize() != mData.mYSize ||
bufferData->GetCbCrSize().isNothing() ||
bufferData->GetCbCrSize().ref() != mData.mCbCrSize ||
bufferData->GetYUVColorSpace().isNothing() ||
bufferData->GetYUVColorSpace().ref() != mData.mYUVColorSpace ||
bufferData->GetStereoMode().isNothing() ||
bufferData->GetStereoMode().ref() != mData.mStereoMode) {
return false;
@ -119,6 +121,7 @@ YCbCrTextureClientAllocationHelper::Allocate(KnowsCompositor* aAllocator)
return TextureClient::CreateForYCbCr(aAllocator,
mData.mYSize, mData.mCbCrSize,
mData.mStereoMode,
mData.mYUVColorSpace,
mTextureFlags);
}
@ -165,12 +168,6 @@ TextureClientRecycleAllocator::CreateOrRecycle(gfx::SurfaceFormat aFormat,
already_AddRefed<TextureClient>
TextureClientRecycleAllocator::CreateOrRecycle(ITextureClientAllocationHelper& aHelper)
{
// TextureAllocationFlags is actually used only by ContentClient.
// This class does not handle ContentClient's TextureClient allocation.
MOZ_ASSERT(aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_DEFAULT ||
aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT ||
aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT ||
aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
MOZ_ASSERT(aHelper.mTextureFlags & TextureFlags::RECYCLE);
RefPtr<TextureClientHolder> textureHolder;

View File

@ -8,6 +8,7 @@ using struct mozilla::layers::MagicGrallocBufferHandle from "gfxipc/ShadowLayerU
using struct mozilla::layers::GrallocBufferRef from "gfxipc/ShadowLayerUtils.h";
using struct mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h";
using mozilla::StereoMode from "ImageTypes.h";
using mozilla::YUVColorSpace from "ImageTypes.h";
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
@ -115,6 +116,7 @@ struct YCbCrDescriptor {
uint32_t cbOffset;
uint32_t crOffset;
StereoMode stereoMode;
YUVColorSpace yUVColorSpace;
bool hasIntermediateBuffer;
};

View File

@ -116,8 +116,10 @@ SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
return nullptr;
}
// XXX Add YUVColorSpace handling. Use YUVColorSpace::BT601 for now.
mTextureClient = TextureClient::CreateForYCbCrWithBufferSize(mCompositable->GetForwarder(),
size,
YUVColorSpace::BT601,
mCompositable->GetTextureFlags());
// get new buffer _without_ setting mBuffer.
@ -163,7 +165,7 @@ SharedPlanarYCbCrImage::AdoptData(const Data &aData)
static_cast<BufferTextureData*>(mTextureClient->GetInternalData())->SetDesciptor(
YCbCrDescriptor(aData.mYSize, aData.mCbCrSize, yOffset, cbOffset, crOffset,
aData.mStereoMode, hasIntermediateBuffer)
aData.mStereoMode, aData.mYUVColorSpace, hasIntermediateBuffer)
);
return true;
@ -219,6 +221,7 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
mData.mPicY = aData.mPicY;
mData.mPicSize = aData.mPicSize;
mData.mStereoMode = aData.mStereoMode;
mData.mYUVColorSpace = aData.mYUVColorSpace;
// those members are not always equal to aData's, due to potentially different
// packing.
mData.mYSkip = 0;

View File

@ -258,6 +258,7 @@ TEST(Layers, TextureYCbCrSerialization) {
clientData.mYStride = ySurface->Stride();
clientData.mCbCrStride = cbSurface->Stride();
clientData.mStereoMode = StereoMode::MONO;
clientData.mYUVColorSpace = YUVColorSpace::BT601;
clientData.mYSkip = 0;
clientData.mCbSkip = 0;
clientData.mCrSkip = 0;
@ -266,7 +267,8 @@ TEST(Layers, TextureYCbCrSerialization) {
clientData.mPicX = 0;
RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(nullptr, clientData.mYSize, clientData.mCbCrSize,
StereoMode::MONO, TextureFlags::DEALLOCATE_CLIENT);
StereoMode::MONO, YUVColorSpace::BT601,
TextureFlags::DEALLOCATE_CLIENT);
TestTextureClientYCbCr(client, clientData);

View File

@ -110,7 +110,7 @@ gfxDWriteFont::gfxDWriteFont(gfxFontEntry *aFontEntry,
static_cast<gfxDWriteFontFamily*>(fontList->GetDefaultFont(aFontStyle));
mFont = defaultFontFamily->GetDefaultFont();
NS_WARNING("Using default font");
MOZ_ASSERT(mFont);
}
HRESULT hr = mFont->GetFontFamily(getter_AddRefs(mFontFamily));

View File

@ -212,21 +212,26 @@ gfxTextRun::ReleaseFontGroup()
}
bool
gfxTextRun::SetPotentialLineBreaks(Range aRange, uint8_t *aBreakBefore)
gfxTextRun::SetPotentialLineBreaks(Range aRange, const uint8_t* aBreakBefore)
{
NS_ASSERTION(aRange.end <= GetLength(), "Overflow");
uint32_t changed = 0;
uint32_t i;
CompressedGlyph *charGlyphs = mCharacterGlyphs + aRange.start;
for (i = 0; i < aRange.Length(); ++i) {
uint8_t canBreak = aBreakBefore[i];
if (canBreak && !charGlyphs[i].IsClusterStart()) {
// This can happen ... there is no guarantee that our linebreaking rules
// align with the platform's idea of what constitutes a cluster.
canBreak = CompressedGlyph::FLAG_BREAK_TYPE_NONE;
CompressedGlyph* cg = mCharacterGlyphs + aRange.start;
const CompressedGlyph* const end = cg + aRange.Length();
while (cg < end) {
uint8_t canBreak = *aBreakBefore++;
if (canBreak && !cg->IsClusterStart()) {
// XXX If we replace the line-breaker with one based more closely
// on UAX#14 (e.g. using ICU), this may not be needed any more.
// Avoid possible breaks inside a cluster, EXCEPT when the previous
// character was a space (compare UAX#14 rules LB9, LB10).
if (cg == mCharacterGlyphs || !(cg - 1)->CharIsSpace()) {
canBreak = CompressedGlyph::FLAG_BREAK_TYPE_NONE;
}
}
changed |= charGlyphs[i].SetCanBreakBefore(canBreak);
changed |= cg->SetCanBreakBefore(canBreak);
++cg;
}
return changed != 0;
}

View File

@ -171,7 +171,8 @@ public:
* @return true if this changed the linebreaks, false if the new line
* breaks are the same as the old
*/
virtual bool SetPotentialLineBreaks(Range aRange, uint8_t *aBreakBefore);
virtual bool SetPotentialLineBreaks(Range aRange,
const uint8_t* aBreakBefore);
/**
* Layout provides PropertyProvider objects. These allow detection of

View File

@ -23,7 +23,8 @@ VRDisplayManager::AllocateDisplayID()
}
Matrix4x4
VRFieldOfView::ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded)
VRFieldOfView::ConstructProjectionMatrix(float zNear, float zFar,
bool rightHanded) const
{
float upTan = tan(upDegrees * M_PI / 180.0);
float downTan = tan(downDegrees * M_PI / 180.0);

View File

@ -112,7 +112,7 @@ struct VRFieldOfView {
leftDegrees == 0.0;
}
Matrix4x4 ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded);
Matrix4x4 ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded) const;
double upDegrees;
double rightDegrees;

View File

@ -118,6 +118,7 @@ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
aData.mCbCrStride,
aStride,
yuvtype,
aData.mYUVColorSpace,
FILTER_BILINEAR);
} else { // no prescale
#if defined(HAVE_YCBCR_TO_RGB565)
@ -147,7 +148,8 @@ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
aData.mYStride,
aData.mCbCrStride,
aStride,
yuvtype);
yuvtype,
aData.mYUVColorSpace);
}
}

View File

@ -71,6 +71,7 @@ struct YUVBuferIter {
const uint8* src_v;
uint32 src_fourcc;
const struct YuvConstants* yuvconstants;
int y_index;
const uint8* src_row_y;
const uint8* src_row_u;
@ -200,15 +201,20 @@ static void YUVBuferIter_MoveToNextRowForI420(YUVBuferIter& iter) {
}
static __inline void YUVBuferIter_ConvertToARGBRow(YUVBuferIter& iter, uint8* argb_row) {
iter.YUVToARGBRow(iter.src_row_y, iter.src_row_u, iter.src_row_v, argb_row, &kYuvI601Constants, iter.src_width);
iter.YUVToARGBRow(iter.src_row_y, iter.src_row_u, iter.src_row_v, argb_row, iter.yuvconstants, iter.src_width);
}
void YUVBuferIter_Init(YUVBuferIter& iter, uint32 src_fourcc) {
void YUVBuferIter_Init(YUVBuferIter& iter, uint32 src_fourcc, mozilla::YUVColorSpace yuv_color_space) {
iter.src_fourcc = src_fourcc;
iter.y_index = 0;
iter.src_row_y = iter.src_y;
iter.src_row_u = iter.src_u;
iter.src_row_v = iter.src_v;
if (yuv_color_space == mozilla::YUVColorSpace::BT709) {
iter.yuvconstants = &kYuvH709Constants;
} else {
iter.yuvconstants = &kYuvI601Constants;
}
if (src_fourcc == FOURCC_I444) {
YUVBuferIter_InitI444(iter);
@ -241,7 +247,8 @@ static void ScaleYUVToARGBDown2(int src_width, int src_height,
uint8* dst_argb,
int x, int dx, int y, int dy,
enum FilterMode filtering,
uint32 src_fourcc) {
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space) {
int j;
// Allocate 2 rows of ARGB for source conversion.
@ -259,7 +266,7 @@ static void ScaleYUVToARGBDown2(int src_width, int src_height,
iter.src_y = src_y;
iter.src_u = src_u;
iter.src_v = src_v;
YUVBuferIter_Init(iter, src_fourcc);
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride,
uint8* dst_argb, int dst_width) =
@ -377,7 +384,8 @@ static void ScaleYUVToARGBDownEven(int src_width, int src_height,
uint8* dst_argb,
int x, int dx, int y, int dy,
enum FilterMode filtering,
uint32 src_fourcc) {
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space) {
int j;
// Allocate 2 rows of ARGB for source conversion.
const int kRowSize = (src_width * 4 + 15) & ~15;
@ -424,7 +432,7 @@ static void ScaleYUVToARGBDownEven(int src_width, int src_height,
iter.src_y = src_y;
iter.src_u = src_u;
iter.src_v = src_v;
YUVBuferIter_Init(iter, src_fourcc);
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
const int dyi = dy >> 16;
int lastyi = yi;
@ -497,7 +505,8 @@ static void ScaleYUVToARGBBilinearDown(int src_width, int src_height,
uint8* dst_argb,
int x, int dx, int y, int dy,
enum FilterMode filtering,
uint32 src_fourcc) {
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space) {
int j;
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
@ -583,7 +592,7 @@ static void ScaleYUVToARGBBilinearDown(int src_width, int src_height,
iter.src_y = src_y;
iter.src_u = src_u;
iter.src_v = src_v;
YUVBuferIter_Init(iter, src_fourcc);
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
iter.MoveTo(iter, yi);
// TODO(fbarchard): Consider not allocating row buffer for kFilterLinear.
@ -665,7 +674,8 @@ static void ScaleYUVToARGBBilinearUp(int src_width, int src_height,
uint8* dst_argb,
int x, int dx, int y, int dy,
enum FilterMode filtering,
uint32 src_fourcc) {
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space) {
int j;
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
@ -762,7 +772,7 @@ static void ScaleYUVToARGBBilinearUp(int src_width, int src_height,
iter.src_y = src_y;
iter.src_u = src_u;
iter.src_v = src_v;
YUVBuferIter_Init(iter, src_fourcc);
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
iter.MoveTo(iter, yi);
// Allocate 2 rows of ARGB.
@ -848,7 +858,8 @@ static void ScaleYUVToARGBSimple(int src_width, int src_height,
const uint8* src_v,
uint8* dst_argb,
int x, int dx, int y, int dy,
uint32 src_fourcc) {
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space) {
int j;
void (*ScaleARGBCols)(uint8* dst_argb, const uint8* src_argb,
int dst_width, int x, int dx) =
@ -890,7 +901,7 @@ static void ScaleYUVToARGBSimple(int src_width, int src_height,
iter.src_y = src_y;
iter.src_u = src_u;
iter.src_v = src_v;
YUVBuferIter_Init(iter, src_fourcc);
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
iter.MoveTo(iter, yi);
int lasty = yi;
@ -916,7 +927,8 @@ static void YUVToARGBCopy(const uint8* src_y, int src_stride_y,
int src_width, int src_height,
uint8* dst_argb, int dst_stride_argb,
int dst_width, int dst_height,
uint32 src_fourcc)
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space)
{
YUVBuferIter iter;
iter.src_width = src_width;
@ -927,7 +939,7 @@ static void YUVToARGBCopy(const uint8* src_y, int src_stride_y,
iter.src_y = src_y;
iter.src_u = src_u;
iter.src_v = src_v;
YUVBuferIter_Init(iter, src_fourcc);
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
for (int j = 0; j < dst_height; ++j) {
YUVBuferIter_ConvertToARGBRow(iter, dst_argb);
@ -943,7 +955,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
int dst_width, int dst_height,
enum FilterMode filtering,
uint32 src_fourcc)
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space)
{
// Initial source x/y coordinate and step values as 16.16 fixed point.
int x = 0;
@ -979,7 +992,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
dst_argb,
x, dx, y, dy,
filtering,
src_fourcc);
src_fourcc,
yuv_color_space);
return;
}
ScaleYUVToARGBDownEven(src_width, src_height,
@ -994,7 +1008,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
dst_argb,
x, dx, y, dy,
filtering,
src_fourcc);
src_fourcc,
yuv_color_space);
return;
}
// Optimized odd scale down. ie 3, 5, 7, 9x.
@ -1008,7 +1023,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
src_width, src_height,
dst_argb, dst_stride_argb,
dst_width, dst_height,
src_fourcc);
src_fourcc,
yuv_color_space);
return;
}
}
@ -1027,7 +1043,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
dst_argb,
x, dx, y, dy,
filtering,
src_fourcc);
src_fourcc,
yuv_color_space);
return;
}
if (filtering) {
@ -1043,7 +1060,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
dst_argb,
x, dx, y, dy,
filtering,
src_fourcc);
src_fourcc,
yuv_color_space);
return;
}
ScaleYUVToARGBSimple(src_width, src_height,
@ -1057,7 +1075,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
src_v,
dst_argb,
x, dx, y, dy,
src_fourcc);
src_fourcc,
yuv_color_space);
}
bool IsConvertSupported(uint32 src_fourcc)
@ -1075,6 +1094,7 @@ int YUVToARGBScale(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space,
int src_width, int src_height,
uint8* dst_argb, int dst_stride_argb,
int dst_width, int dst_height,
@ -1095,7 +1115,8 @@ int YUVToARGBScale(const uint8* src_y, int src_stride_y,
dst_argb, dst_stride_argb,
dst_width, dst_height,
filtering,
src_fourcc);
src_fourcc,
yuv_color_space);
return 0;
}

View File

@ -14,6 +14,8 @@
#include "libyuv/basic_types.h"
#include "libyuv/scale.h" // For FilterMode
#include "ImageTypes.h" // For YUVColorSpace
#ifdef __cplusplus
namespace libyuv {
extern "C" {
@ -23,6 +25,7 @@ int YUVToARGBScale(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint32 src_fourcc,
mozilla::YUVColorSpace yuv_color_space,
int src_width, int src_height,
uint8* dst_argb, int dst_stride_argb,
int dst_width, int dst_height,

View File

@ -75,7 +75,8 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
int y_pitch,
int uv_pitch,
int rgb_pitch,
YUVType yuv_type) {
YUVType yuv_type,
YUVColorSpace yuv_color_space) {
// Deprecated function's conversion is accurate.
@ -87,7 +88,13 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
// The function is still fast on some old intel chips.
// See Bug 1256475.
bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
(supports_mmx() && supports_sse() && !supports_sse3());
(supports_mmx() && supports_sse() && !supports_sse3() &&
yuv_color_space == YUVColorSpace::BT601);
// The deprecated function only support BT601.
// See Bug 1210357.
if (yuv_color_space != YUVColorSpace::BT601) {
use_deprecated = false;
}
if (use_deprecated) {
ConvertYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf, rgb_buf,
pic_x, pic_y, pic_width, pic_height,
@ -120,12 +127,22 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
const uint8* src_u = u_buf + (uv_pitch * pic_y + pic_x) / 2;
const uint8* src_v = v_buf + (uv_pitch * pic_y + pic_x) / 2;
DebugOnly<int> err = libyuv::I420ToARGB(src_y, y_pitch,
src_u, uv_pitch,
src_v, uv_pitch,
rgb_buf, rgb_pitch,
pic_width, pic_height);
MOZ_ASSERT(!err);
if (yuv_color_space == YUVColorSpace::BT709) {
DebugOnly<int> err = libyuv::H420ToARGB(src_y, y_pitch,
src_u, uv_pitch,
src_v, uv_pitch,
rgb_buf, rgb_pitch,
pic_width, pic_height);
MOZ_ASSERT(!err);
} else {
MOZ_ASSERT(yuv_color_space == YUVColorSpace::BT601);
DebugOnly<int> err = libyuv::I420ToARGB(src_y, y_pitch,
src_u, uv_pitch,
src_v, uv_pitch,
rgb_buf, rgb_pitch,
pic_width, pic_height);
MOZ_ASSERT(!err);
}
}
}
@ -257,6 +274,7 @@ void ScaleYCbCrToRGB32(const uint8* y_buf,
int uv_pitch,
int rgb_pitch,
YUVType yuv_type,
YUVColorSpace yuv_color_space,
ScaleFilter filter) {
bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
@ -265,6 +283,11 @@ void ScaleYCbCrToRGB32(const uint8* y_buf,
supports_sse3() ||
#endif
(supports_mmx() && supports_sse() && !supports_sse3());
// The deprecated function only support BT601.
// See Bug 1210357.
if (yuv_color_space != YUVColorSpace::BT601) {
use_deprecated = false;
}
if (use_deprecated) {
ScaleYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf,
rgb_buf,
@ -283,6 +306,7 @@ void ScaleYCbCrToRGB32(const uint8* y_buf,
u_buf, uv_pitch,
v_buf, uv_pitch,
FourCCFromYUVType(yuv_type),
yuv_color_space,
source_width, source_height,
rgb_buf, rgb_pitch,
width, height,

View File

@ -6,6 +6,7 @@
#define MEDIA_BASE_YUV_CONVERT_H_
#include "chromium_types.h"
#include "ImageTypes.h"
namespace mozilla {
@ -55,7 +56,8 @@ void ConvertYCbCrToRGB32(const uint8* yplane,
int ystride,
int uvstride,
int rgbstride,
YUVType yuv_type);
YUVType yuv_type,
YUVColorSpace yuv_color_space);
void ConvertYCbCrToRGB32_deprecated(const uint8* yplane,
const uint8* uplane,
@ -84,6 +86,7 @@ void ScaleYCbCrToRGB32(const uint8* yplane,
int uvstride,
int rgbstride,
YUVType yuv_type,
YUVColorSpace yuv_color_space,
ScaleFilter filter);
void ScaleYCbCrToRGB32_deprecated(const uint8* yplane,

View File

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CrashReporterClient.h"
#include "CrashReporterMetadataShmem.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace ipc {
StaticMutex CrashReporterClient::sLock;
StaticRefPtr<CrashReporterClient> CrashReporterClient::sClientSingleton;
CrashReporterClient::CrashReporterClient(const Shmem& aShmem)
: mMetadata(new CrashReporterMetadataShmem(aShmem))
{
MOZ_COUNT_CTOR(CrashReporterClient);
}
CrashReporterClient::~CrashReporterClient()
{
MOZ_COUNT_DTOR(CrashReporterClient);
}
void
CrashReporterClient::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData)
{
StaticMutexAutoLock lock(sLock);
mMetadata->AnnotateCrashReport(aKey, aData);
}
void
CrashReporterClient::AppendAppNotes(const nsCString& aData)
{
StaticMutexAutoLock lock(sLock);
mMetadata->AppendAppNotes(aData);
}
/* static */ void
CrashReporterClient::InitSingletonWithShmem(const Shmem& aShmem)
{
StaticMutexAutoLock lock(sLock);
MOZ_ASSERT(!sClientSingleton);
sClientSingleton = new CrashReporterClient(aShmem);
}
/* static */ void
CrashReporterClient::DestroySingleton()
{
StaticMutexAutoLock lock(sLock);
sClientSingleton = nullptr;
}
/* static */ RefPtr<CrashReporterClient>
CrashReporterClient::GetSingleton()
{
StaticMutexAutoLock lock(sLock);
return sClientSingleton;
}
} // namespace ipc
} // namespace mozilla

View File

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_CrashReporterClient_h
#define mozilla_ipc_CrashReporterClient_h
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Unused.h"
#include "mozilla/ipc/Shmem.h"
namespace mozilla {
namespace ipc {
class CrashReporterMetadataShmem;
class CrashReporterClient
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CrashReporterClient);
// |aTopLevelProtocol| must be a top-level protocol instance, as sub-actors
// do not have AllocUnsafeShmem. It must also have a child-to-parent message:
//
// async SetCrashReporterClient(Shmem shmem);
//
// The parent-side receive function of this message should save the shmem
// somewhere, and when the top-level actor's ActorDestroy runs (or when the
// crash reporter needs metadata), the shmem should be parsed.
template <typename T>
static bool InitSingleton(T* aToplevelProtocol) {
// 16KB should be enough for most metadata - see bug 1278717 comment #11.
static const size_t kShmemSize = 16 * 1024;
Shmem shmem;
bool rv = aToplevelProtocol->AllocUnsafeShmem(
kShmemSize,
SharedMemory::TYPE_BASIC,
&shmem);
if (!rv) {
return false;
}
InitSingletonWithShmem(shmem);
Unused << aToplevelProtocol->SendInitCrashReporter(shmem);
return true;
}
static void DestroySingleton();
static RefPtr<CrashReporterClient> GetSingleton();
void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
void AppendAppNotes(const nsCString& aData);
private:
explicit CrashReporterClient(const Shmem& aShmem);
~CrashReporterClient();
static void InitSingletonWithShmem(const Shmem& aShmem);
private:
static StaticMutex sLock;
static StaticRefPtr<CrashReporterClient> sClientSingleton;
private:
UniquePtr<CrashReporterMetadataShmem> mMetadata;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_CrashReporterClient_h

View File

@ -0,0 +1,124 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CrashReporterHost.h"
#include "CrashReporterMetadataShmem.h"
#include "mozilla/Sprintf.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/Telemetry.h"
#ifdef MOZ_CRASHREPORTER
# include "nsICrashService.h"
#endif
namespace mozilla {
namespace ipc {
CrashReporterHost::CrashReporterHost(GeckoProcessType aProcessType,
const Shmem& aShmem)
: mProcessType(aProcessType),
mShmem(aShmem),
mStartTime(::time(nullptr))
{
}
#ifdef MOZ_CRASHREPORTER
void
CrashReporterHost::GenerateCrashReport(RefPtr<nsIFile> aCrashDump)
{
nsString dumpID;
if (!CrashReporter::GetIDFromMinidump(aCrashDump, dumpID)) {
return;
}
CrashReporter::AnnotationTable notes;
nsAutoCString type;
switch (mProcessType) {
case GeckoProcessType_Content:
type = NS_LITERAL_CSTRING("content");
break;
case GeckoProcessType_Plugin:
case GeckoProcessType_GMPlugin:
type = NS_LITERAL_CSTRING("plugin");
break;
case GeckoProcessType_GPU:
type = NS_LITERAL_CSTRING("gpu");
break;
default:
NS_ERROR("unknown process type");
break;
}
notes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
char startTime[32];
SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime));
notes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
CrashReporterMetadataShmem::ReadAppNotes(mShmem, &notes);
CrashReporter::AppendExtraData(dumpID, notes);
NotifyCrashService(mProcessType, dumpID, &notes);
}
/* static */ void
CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
const nsString& aChildDumpID,
const AnnotationTable* aNotes)
{
if (!NS_IsMainThread()) {
RefPtr<Runnable> runnable = NS_NewRunnableFunction([=] () -> void {
CrashReporterHost::NotifyCrashService(aProcessType, aChildDumpID, aNotes);
});
RefPtr<nsIThread> mainThread = do_GetMainThread();
SyncRunnable::DispatchToThread(mainThread, runnable);
return;
}
MOZ_ASSERT(!aChildDumpID.IsEmpty());
nsCOMPtr<nsICrashService> crashService =
do_GetService("@mozilla.org/crashservice;1");
if (!crashService) {
return;
}
int32_t processType;
int32_t crashType = nsICrashService::CRASH_TYPE_CRASH;
nsCString telemetryKey;
switch (aProcessType) {
case GeckoProcessType_Content:
processType = nsICrashService::PROCESS_TYPE_CONTENT;
telemetryKey.AssignLiteral("content");
break;
case GeckoProcessType_Plugin: {
processType = nsICrashService::PROCESS_TYPE_PLUGIN;
telemetryKey.AssignLiteral("plugin");
nsAutoCString val;
if (aNotes->Get(NS_LITERAL_CSTRING("PluginHang"), &val) &&
val.Equals(NS_LITERAL_CSTRING("1"))) {
crashType = nsICrashService::CRASH_TYPE_HANG;
telemetryKey.AssignLiteral("pluginhang");
}
break;
}
case GeckoProcessType_GMPlugin:
processType = nsICrashService::PROCESS_TYPE_GMPLUGIN;
telemetryKey.AssignLiteral("gmplugin");
break;
default:
NS_ERROR("unknown process type");
return;
}
crashService->AddCrash(processType, crashType, aChildDumpID);
Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1);
}
#endif
} // namespace ipc
} // namespace mozilla

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_CrashReporterHost_h
#define mozilla_ipc_CrashReporterHost_h
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/Shmem.h"
#include "base/process.h"
#include "nsExceptionHandler.h"
namespace mozilla {
namespace ipc {
// This is the newer replacement for CrashReporterParent. It is created in
// response to a InitCrashReporter message on a top-level actor, and simply
// holds the metadata shmem alive until the process ends. When the process
// terminates abnormally, the top-level should call GenerateCrashReport to
// automatically integrate metadata.
class CrashReporterHost
{
typedef mozilla::ipc::Shmem Shmem;
typedef CrashReporter::AnnotationTable AnnotationTable;
public:
CrashReporterHost(GeckoProcessType aProcessType, const Shmem& aShmem);
#ifdef MOZ_CRASHREPORTER
void GenerateCrashReport(base::ProcessId aPid) {
RefPtr<nsIFile> crashDump;
if (!XRE_TakeMinidumpForChild(aPid, getter_AddRefs(crashDump), nullptr)) {
return;
}
GenerateCrashReport(crashDump);
}
// This is a static helper function to notify the crash service that a
// crash has occurred. When PCrashReporter is removed, we can make this
// a member function. This can be called from any thread, and if not
// called from the main thread, will post a synchronous message to the
// main thread.
static void NotifyCrashService(
GeckoProcessType aProcessType,
const nsString& aChildDumpID,
const AnnotationTable* aNotes);
#endif
private:
void GenerateCrashReport(RefPtr<nsIFile> aCrashDump);
private:
GeckoProcessType mProcessType;
Shmem mShmem;
time_t mStartTime;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_CrashReporterHost_h

View File

@ -0,0 +1,235 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CrashReporterMetadataShmem.h"
#include "mozilla/Attributes.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace ipc {
enum class EntryType : uint8_t {
None,
Annotation,
};
CrashReporterMetadataShmem::CrashReporterMetadataShmem(const Shmem& aShmem)
: mShmem(aShmem)
{
MOZ_COUNT_CTOR(CrashReporterMetadataShmem);
}
CrashReporterMetadataShmem::~CrashReporterMetadataShmem()
{
MOZ_COUNT_DTOR(CrashReporterMetadataShmem);
}
void
CrashReporterMetadataShmem::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData)
{
mNotes.Put(aKey, aData);
SyncNotesToShmem();
}
void
CrashReporterMetadataShmem::AppendAppNotes(const nsCString& aData)
{
mAppNotes.Append(aData);
mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);
SyncNotesToShmem();
}
class MOZ_STACK_CLASS MetadataShmemWriter
{
public:
explicit MetadataShmemWriter(const Shmem& aShmem)
: mCursor(aShmem.get<uint8_t>()),
mEnd(mCursor + aShmem.Size<uint8_t>())
{
*mCursor = uint8_t(EntryType::None);
}
MOZ_MUST_USE bool WriteAnnotation(const nsCString& aKey, const nsCString& aValue) {
// This shouldn't happen because Commit() guarantees mCursor < mEnd. But
// we might as well be safe.
if (mCursor >= mEnd) {
return false;
}
// Save the current position so we can write the entry type if the entire
// entry fits.
uint8_t* start = mCursor++;
if (!Write(aKey) || !Write(aValue)) {
return false;
}
return Commit(start, EntryType::Annotation);
}
private:
// On success, append a new terminal byte. On failure, rollback the cursor.
MOZ_MUST_USE bool Commit(uint8_t* aStart, EntryType aType) {
MOZ_ASSERT(aStart < mEnd);
MOZ_ASSERT(EntryType(*aStart) == EntryType::None);
if (mCursor >= mEnd) {
// No room for a terminating byte - rollback.
mCursor = aStart;
return false;
}
// Commit the entry and write a new terminal byte.
*aStart = uint8_t(aType);
*mCursor = uint8_t(EntryType::None);
return true;
}
MOZ_MUST_USE bool Write(const nsCString& aString) {
// 32-bit length is okay since our shmems are very small (16K),
// a huge write would fail anyway.
return Write(static_cast<uint32_t>(aString.Length())) &&
Write(aString.get(), aString.Length());
}
template <typename T>
MOZ_MUST_USE bool Write(const T& aT) {
return Write(&aT, sizeof(T));
}
MOZ_MUST_USE bool Write(const void* aData, size_t aLength) {
if (size_t(mEnd - mCursor) < aLength) {
return false;
}
memcpy(mCursor, aData, aLength);
mCursor += aLength;
return true;
}
private:
// The cursor (beginning at start) always points to a single byte
// representing the next EntryType. An EntryType is either None,
// indicating there are no more entries, or Annotation, meaning
// two strings follow.
//
// Strings are written as a 32-bit length and byte sequence. After each new
// entry, a None entry is always appended, and a subsequent entry will
// overwrite this byte.
uint8_t* mCursor;
uint8_t* mEnd;
};
void
CrashReporterMetadataShmem::SyncNotesToShmem()
{
MetadataShmemWriter writer(mShmem);
for (auto it = mNotes.Iter(); !it.Done(); it.Next()) {
nsCString key = nsCString(it.Key());
nsCString value = nsCString(it.Data());
if (!writer.WriteAnnotation(key, value)) {
return;
}
}
}
// Helper class to iterate over metadata entries encoded in shmem.
class MOZ_STACK_CLASS MetadataShmemReader
{
public:
explicit MetadataShmemReader(const Shmem& aShmem)
: mEntryType(EntryType::None)
{
mCursor = aShmem.get<uint8_t>();
mEnd = mCursor + aShmem.Size<uint8_t>();
// Advance to the first item, if any.
Next();
}
bool Done() const {
return mCursor >= mEnd || Type() == EntryType::None;
}
EntryType Type() const {
return mEntryType;
}
void Next() {
if (mCursor < mEnd) {
mEntryType = EntryType(*mCursor++);
} else {
mEntryType = EntryType::None;
}
}
bool Read(nsCString& aOut) {
uint32_t length = 0;
if (!Read(&length)) {
return false;
}
const uint8_t* src = Read(length);
if (!src) {
return false;
}
aOut.Assign((const char *)src, length);
return true;
}
private:
template <typename T>
bool Read(T* aOut) {
return Read(aOut, sizeof(T));
}
bool Read(void* aOut, size_t aLength) {
const uint8_t* src = Read(aLength);
if (!src) {
return false;
}
memcpy(aOut, src, aLength);
return true;
}
// If buffer has |aLength| bytes, return cursor and then advance it.
// Otherwise, return null.
const uint8_t* Read(size_t aLength) {
if (size_t(mEnd - mCursor) < aLength) {
return nullptr;
}
const uint8_t* result = mCursor;
mCursor += aLength;
return result;
}
private:
const uint8_t* mCursor;
const uint8_t* mEnd;
EntryType mEntryType;
};
#ifdef MOZ_CRASHREPORTER
void
CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes)
{
for (MetadataShmemReader reader(aShmem); !reader.Done(); reader.Next()) {
switch (reader.Type()) {
case EntryType::Annotation: {
nsCString key, value;
if (!reader.Read(key) || !reader.Read(value)) {
return;
}
aNotes->Put(key, value);
break;
}
default:
NS_ASSERTION(false, "Unknown metadata entry type");
break;
}
}
}
#endif
} // namespace ipc
} // namespace mozilla

View File

@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_CrashReporterMetadataShmem_h
#define mozilla_ipc_CrashReporterMetadataShmem_h
#include <stdint.h>
#include "mozilla/ipc/Shmem.h"
#include "nsExceptionHandler.h"
#include "nsString.h"
namespace mozilla {
namespace ipc {
class CrashReporterMetadataShmem
{
typedef mozilla::ipc::Shmem Shmem;
typedef CrashReporter::AnnotationTable AnnotationTable;
public:
explicit CrashReporterMetadataShmem(const Shmem& aShmem);
~CrashReporterMetadataShmem();
// Metadata writers. These must only be called in child processes.
void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
void AppendAppNotes(const nsCString& aData);
#ifdef MOZ_CRASHREPORTER
static void ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes);
#endif
private:
void SyncNotesToShmem();
private:
Shmem mShmem;
AnnotationTable mNotes;
nsCString mAppNotes;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_CrashReporterMetadataShmem_h

View File

@ -1,35 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
/* 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/. */
namespace mozilla {
namespace ipc {
struct FDRemap {
FileDescriptor fd;
int mapto;
};
protocol PProcLoader
{
child:
/**
* Request B2G loader service to load content process.
*
* It actually calls the main() function of plugin-container.
*/
async Load(nsCString[] argv, nsCString[] env,
FDRemap[] fdsRemap, uint32_t privs,
int32_t cookie);
parent:
/**
* The acknowledgement of Load().
*/
async LoadComplete(int32_t pid, int32_t cookie);
};
}
}

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/process_util.h"
#include "base/task.h"
#ifdef OS_POSIX
#include <errno.h>

View File

@ -15,6 +15,9 @@ EXPORTS.mozilla.ipc += [
'BackgroundParent.h',
'BackgroundUtils.h',
'BrowserProcessSubThread.h',
'CrashReporterClient.h',
'CrashReporterHost.h',
'CrashReporterMetadataShmem.h',
'CrossProcessMutex.h',
'FileDescriptor.h',
'FileDescriptorSetChild.h',
@ -119,6 +122,9 @@ UNIFIED_SOURCES += [
'BackgroundImpl.cpp',
'BackgroundUtils.cpp',
'BrowserProcessSubThread.cpp',
'CrashReporterClient.cpp',
'CrashReporterHost.cpp',
'CrashReporterMetadataShmem.cpp',
'FileDescriptor.cpp',
'FileDescriptorUtils.cpp',
'InputStreamUtils.cpp',
@ -170,14 +176,14 @@ IPDL_SOURCES = [
'PBackgroundSharedTypes.ipdlh',
'PBackgroundTest.ipdl',
'PFileDescriptorSet.ipdl',
'PProcLoader.ipdl',
'ProtocolTypes.ipdlh',
'PSendStream.ipdl',
'URIParams.ipdlh',
]
LOCAL_INCLUDES += [
'/dom/ipc',
'/toolkit/crashreporter',
'/toolkit/xre',
'/xpcom/threads',
]
@ -190,10 +196,6 @@ for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_NAME_PIE',
'MOZ_CHILD_PROCESS_BUNDLE', 'DLL_PREFIX', 'DLL_SUFFIX'):
DEFINES[var] = '"%s"' % CONFIG[var]
LOCAL_INCLUDES += [
'/toolkit/crashreporter',
]
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
LOCAL_INCLUDES += [
'/security/sandbox/chromium',

View File

@ -626,14 +626,14 @@ class AstImport : public AstNode
DefinitionKind kind_;
AstRef funcSig_;
ResizableLimits resizable_;
Limits resizable_;
AstGlobal global_;
public:
AstImport(AstName name, AstName module, AstName field, AstRef funcSig)
: name_(name), module_(module), field_(field), kind_(DefinitionKind::Function), funcSig_(funcSig)
{}
AstImport(AstName name, AstName module, AstName field, DefinitionKind kind, ResizableLimits resizable)
AstImport(AstName name, AstName module, AstName field, DefinitionKind kind, Limits resizable)
: name_(name), module_(module), field_(field), kind_(kind), resizable_(resizable)
{}
AstImport(AstName name, AstName module, AstName field, AstGlobal global)
@ -649,7 +649,7 @@ class AstImport : public AstNode
MOZ_ASSERT(kind_ == DefinitionKind::Function);
return funcSig_;
}
ResizableLimits resizable() const {
Limits resizable() const {
MOZ_ASSERT(kind_ == DefinitionKind::Memory || kind_ == DefinitionKind::Table);
return resizable_;
}
@ -744,8 +744,8 @@ class AstModule : public AstNode
SigMap sigMap_;
ImportVector imports_;
NameVector funcImportNames_;
Maybe<ResizableLimits> table_;
Maybe<ResizableLimits> memory_;
Maybe<Limits> table_;
Maybe<Limits> memory_;
ExportVector exports_;
Maybe<AstStartFunc> startFunc_;
FuncVector funcs_;
@ -769,7 +769,7 @@ class AstModule : public AstNode
bool init() {
return sigMap_.init();
}
bool setMemory(ResizableLimits memory) {
bool setMemory(Limits memory) {
if (memory_)
return false;
memory_.emplace(memory);
@ -778,10 +778,10 @@ class AstModule : public AstNode
bool hasMemory() const {
return !!memory_;
}
const ResizableLimits& memory() const {
const Limits& memory() const {
return *memory_;
}
bool setTable(ResizableLimits table) {
bool setTable(Limits table) {
if (table_)
return false;
table_.emplace(table);
@ -790,7 +790,7 @@ class AstModule : public AstNode
bool hasTable() const {
return !!table_;
}
const ResizableLimits& table() const {
const Limits& table() const {
return *table_;
}
bool append(AstDataSegment* seg) {

View File

@ -142,7 +142,7 @@ wasm::DecodeGlobalType(Decoder& d, ValType* type, uint32_t* flags)
}
bool
wasm::DecodeResizable(Decoder& d, ResizableLimits* limits)
wasm::DecodeLimits(Decoder& d, Limits* limits)
{
uint32_t flags;
if (!d.readVarU32(&flags))

View File

@ -1096,10 +1096,10 @@ DecodeLocalEntries(Decoder& d, ValTypeVector* locals);
MOZ_MUST_USE bool
DecodeGlobalType(Decoder& d, ValType* type, uint32_t* flags);
struct ResizableLimits;
struct Limits;
MOZ_MUST_USE bool
DecodeResizable(Decoder& d, ResizableLimits* resizable);
DecodeLimits(Decoder& d, Limits* limits);
MOZ_MUST_USE bool
DecodeUnknownSections(Decoder& d);

View File

@ -1511,8 +1511,8 @@ AstDecodeTableSection(AstDecodeContext& c)
if (typeConstructorValue != uint32_t(TypeConstructor::AnyFunc))
return c.d.fail("unknown type constructor kind");
ResizableLimits table;
if (!DecodeResizable(c.d, &table))
Limits table;
if (!DecodeLimits(c.d, &table))
return false;
if (table.initial > MaxTableElems)
@ -1547,7 +1547,7 @@ AstDecodeName(AstDecodeContext& c, AstName* name)
}
static bool
AstDecodeResizableTable(AstDecodeContext& c, ResizableLimits* resizable)
AstDecodeLimitsTable(AstDecodeContext& c, Limits* limits)
{
uint32_t kind;
if (!c.d.readVarU32(&kind))
@ -1556,7 +1556,7 @@ AstDecodeResizableTable(AstDecodeContext& c, ResizableLimits* resizable)
if (kind != uint32_t(TypeConstructor::AnyFunc))
return c.d.fail("unknown type constructor kind");
if (!DecodeResizable(c.d, resizable))
if (!DecodeLimits(c.d, limits))
return false;
return true;
@ -1611,8 +1611,8 @@ AstDecodeImport(AstDecodeContext& c, uint32_t importIndex, AstImport** import)
break;
}
case uint32_t(DefinitionKind::Table): {
ResizableLimits table;
if (!AstDecodeResizableTable(c, &table))
Limits table;
if (!AstDecodeLimitsTable(c, &table))
return false;
*import = new(c.lifo) AstImport(importName, moduleName, fieldName,
@ -1620,8 +1620,8 @@ AstDecodeImport(AstDecodeContext& c, uint32_t importIndex, AstImport** import)
break;
}
case uint32_t(DefinitionKind::Memory): {
ResizableLimits memory;
if (!DecodeResizable(c.d, &memory))
Limits memory;
if (!DecodeLimits(c.d, &memory))
return false;
*import = new(c.lifo) AstImport(importName, moduleName, fieldName,
@ -1684,8 +1684,8 @@ AstDecodeMemorySection(AstDecodeContext& c)
if (numMemories != 1)
return c.d.fail("the number of memories must be exactly one");
ResizableLimits memory;
if (!DecodeResizable(c.d, &memory))
Limits memory;
if (!DecodeLimits(c.d, &memory))
return false;
if (!c.d.finishSection(sectionStart, sectionSize, "memory"))

View File

@ -1170,7 +1170,7 @@ RenderTableSection(WasmRenderContext& c, const AstModule& module)
if (!RenderIndent(c))
return false;
if (!c.buffer.append("(table"))
if (!c.buffer.append("(table anyfunc (elem "))
return false;
for (const AstRef& elem : segment.elems()) {
@ -1189,7 +1189,7 @@ RenderTableSection(WasmRenderContext& c, const AstModule& module)
}
}
if (!c.buffer.append(")\n"))
if (!c.buffer.append("))\n"))
return false;
return true;

View File

@ -609,8 +609,8 @@ DecodeResizableMemory(Decoder& d, ModuleGeneratorData* init)
if (UsesMemory(init->memoryUsage))
return d.fail("already have default memory");
ResizableLimits limits;
if (!DecodeResizable(d, &limits))
Limits limits;
if (!DecodeLimits(d, &limits))
return false;
init->memoryUsage = MemoryUsage::Unshared;
@ -644,8 +644,8 @@ DecodeResizableTable(Decoder& d, ModuleGeneratorData* init)
if (elementType != uint32_t(TypeConstructor::AnyFunc))
return d.fail("expected 'anyfunc' element type");
ResizableLimits limits;
if (!DecodeResizable(d, &limits))
Limits limits;
if (!DecodeLimits(d, &limits))
return false;
if (!init->tables.empty())

View File

@ -452,8 +452,8 @@ ToNonWrappingUint32(JSContext* cx, HandleValue v, uint32_t max, const char* kind
}
static bool
GetResizableLimits(JSContext* cx, HandleObject obj, uint32_t max, const char* kind,
ResizableLimits* limits)
GetLimits(JSContext* cx, HandleObject obj, uint32_t max, const char* kind,
Limits* limits)
{
JSAtom* initialAtom = Atomize(cx, "initial", strlen("initial"));
if (!initialAtom)
@ -939,8 +939,8 @@ WasmMemoryObject::construct(JSContext* cx, unsigned argc, Value* vp)
}
RootedObject obj(cx, &args[0].toObject());
ResizableLimits limits;
if (!GetResizableLimits(cx, obj, UINT32_MAX / PageSize, "Memory", &limits))
Limits limits;
if (!GetLimits(cx, obj, UINT32_MAX / PageSize, "Memory", &limits))
return false;
limits.initial *= PageSize;
@ -1182,7 +1182,7 @@ WasmTableObject::trace(JSTracer* trc, JSObject* obj)
}
/* static */ WasmTableObject*
WasmTableObject::create(JSContext* cx, ResizableLimits limits)
WasmTableObject::create(JSContext* cx, Limits limits)
{
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmTable).toObject());
@ -1247,8 +1247,8 @@ WasmTableObject::construct(JSContext* cx, unsigned argc, Value* vp)
return false;
}
ResizableLimits limits;
if (!GetResizableLimits(cx, obj, UINT32_MAX, "Table", &limits))
Limits limits;
if (!GetLimits(cx, obj, UINT32_MAX, "Table", &limits))
return false;
RootedWasmTableObject table(cx, WasmTableObject::create(cx, limits));

View File

@ -254,7 +254,7 @@ class WasmTableObject : public NativeObject
// Note that, after creation, a WasmTableObject's table() is not initialized
// and must be initialized before use.
static WasmTableObject* create(JSContext* cx, wasm::ResizableLimits limits);
static WasmTableObject* create(JSContext* cx, wasm::Limits limits);
wasm::Table& table() const;
};

View File

@ -503,9 +503,8 @@ Module::instantiateFunctions(JSContext* cx, Handle<FunctionVector> funcImports)
}
static bool
CheckResizableLimits(JSContext* cx, uint32_t declaredMin, Maybe<uint32_t> declaredMax,
uint32_t actualLength, Maybe<uint32_t> actualMax,
bool isAsmJS, const char* kind)
CheckLimits(JSContext* cx, uint32_t declaredMin, Maybe<uint32_t> declaredMax, uint32_t actualLength,
Maybe<uint32_t> actualMax, bool isAsmJS, const char* kind)
{
if (isAsmJS) {
MOZ_ASSERT(actualLength >= declaredMin);
@ -515,14 +514,12 @@ CheckResizableLimits(JSContext* cx, uint32_t declaredMin, Maybe<uint32_t> declar
}
if (actualLength < declaredMin || actualLength > declaredMax.valueOr(UINT32_MAX)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_SIZE,
kind);
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_SIZE, kind);
return false;
}
if ((actualMax && (!declaredMax || *actualMax > *declaredMax)) || (!actualMax && declaredMax)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_MAX,
kind);
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_MAX, kind);
return false;
}
@ -549,9 +546,8 @@ Module::instantiateMemory(JSContext* cx, MutableHandleWasmMemoryObject memory) c
MOZ_ASSERT_IF(metadata_->isAsmJS(), buffer.isPreparedForAsmJS());
MOZ_ASSERT_IF(!metadata_->isAsmJS(), buffer.as<ArrayBufferObject>().isWasm());
if (!CheckResizableLimits(cx, declaredMin, declaredMax,
buffer.byteLength(), buffer.wasmMaxSize(),
metadata_->isAsmJS(), "Memory")) {
if (!CheckLimits(cx, declaredMin, declaredMax, buffer.byteLength(), buffer.wasmMaxSize(),
metadata_->isAsmJS(), "Memory")) {
return false;
}
} else {
@ -585,9 +581,8 @@ Module::instantiateTable(JSContext* cx, MutableHandleWasmTableObject tableObj,
MOZ_ASSERT(td.external);
Table& table = tableObj->table();
if (!CheckResizableLimits(cx, td.limits.initial, td.limits.maximum,
table.length(), table.maximum(),
metadata_->isAsmJS(), "Table")) {
if (!CheckLimits(cx, td.limits.initial, td.limits.maximum, table.length(), table.maximum(),
metadata_->isAsmJS(), "Table")) {
return false;
}

View File

@ -65,6 +65,7 @@ class WasmToken
enum Kind
{
Align,
AnyFunc,
BinaryOpcode,
Block,
Br,
@ -92,7 +93,6 @@ class WasmToken
GetLocal,
Global,
If,
Immutable,
Import,
Index,
Memory,
@ -101,12 +101,12 @@ class WasmToken
Local,
Loop,
Module,
Mutable,
Name,
Nop,
Offset,
OpenParen,
Param,
Resizable,
Result,
Return,
Segment,
@ -140,7 +140,12 @@ class WasmToken
Expr expr_;
} u;
public:
explicit WasmToken() = default;
WasmToken()
: kind_(Kind(-1)),
begin_(nullptr),
end_(nullptr),
u()
{ }
WasmToken(Kind kind, const char16_t* begin, const char16_t* end)
: kind_(kind),
begin_(begin),
@ -208,6 +213,7 @@ class WasmToken
end_(begin)
{}
Kind kind() const {
MOZ_ASSERT(kind_ != Kind(-1));
return kind_;
}
const char16_t* begin() const {
@ -283,6 +289,7 @@ class WasmToken
case Unreachable:
return true;
case Align:
case AnyFunc:
case CloseParen:
case Data:
case Elem:
@ -295,7 +302,7 @@ class WasmToken
case Float:
case Func:
case Global:
case Immutable:
case Mutable:
case Import:
case Index:
case Memory:
@ -306,7 +313,6 @@ class WasmToken
case Offset:
case OpenParen:
case Param:
case Resizable:
case Result:
case Segment:
case SignedInteger:
@ -323,6 +329,12 @@ class WasmToken
}
};
struct InlineImport
{
WasmToken module;
WasmToken field;
};
} // end anonymous namespace
static bool
@ -822,6 +834,8 @@ WasmTokenStream::next()
case 'a':
if (consume(u"align"))
return WasmToken(WasmToken::Align, begin, cur_);
if (consume(u"anyfunc"))
return WasmToken(WasmToken::AnyFunc, begin, cur_);
break;
case 'b':
@ -1369,8 +1383,6 @@ WasmTokenStream::next()
}
break;
}
if (consume(u"immutable"))
return WasmToken(WasmToken::Immutable, begin, cur_);
if (consume(u"import"))
return WasmToken(WasmToken::Import, begin, cur_);
if (consume(u"infinity"))
@ -1391,6 +1403,8 @@ WasmTokenStream::next()
return WasmToken(WasmToken::Module, begin, cur_);
if (consume(u"memory"))
return WasmToken(WasmToken::Memory, begin, cur_);
if (consume(u"mut"))
return WasmToken(WasmToken::Mutable, begin, cur_);
break;
case 'n':
@ -1411,8 +1425,6 @@ WasmTokenStream::next()
break;
case 'r':
if (consume(u"resizable"))
return WasmToken(WasmToken::Resizable, begin, cur_);
if (consume(u"result"))
return WasmToken(WasmToken::Result, begin, cur_);
if (consume(u"return"))
@ -2488,100 +2500,49 @@ ParseLocalOrParam(WasmParseContext& c, AstNameVector* locals, AstValTypeVector*
localTypes->append(token.valueType());
}
static AstFunc*
ParseFunc(WasmParseContext& c, AstModule* module)
static bool
ParseInlineImport(WasmParseContext& c, InlineImport* import)
{
AstValTypeVector vars(c.lifo);
AstValTypeVector args(c.lifo);
AstNameVector locals(c.lifo);
AstName exportName = c.ts.getIfText();
AstName funcName = c.ts.getIfName();
AstRef sig;
WasmToken openParen;
if (exportName.empty() && c.ts.getIf(WasmToken::OpenParen, &openParen)) {
if (c.ts.getIf(WasmToken::Export)) {
WasmToken text;
if (!c.ts.match(WasmToken::Text, &text, c.error))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
exportName = text.text();
} else {
c.ts.unget(openParen);
}
}
if (!exportName.empty()) {
if (funcName.empty())
funcName = exportName;
AstExport* exp = new(c.lifo) AstExport(exportName, DefinitionKind::Function,
AstRef(funcName, AstNoIndex));
if (!exp || !module->append(exp))
return nullptr;
}
if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
if (c.ts.getIf(WasmToken::Type)) {
if (!c.ts.matchRef(&sig, c.error))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
} else {
c.ts.unget(openParen);
}
}
AstExprVector body(c.lifo);
ExprType result = ExprType::Void;
while (c.ts.getIf(WasmToken::OpenParen)) {
WasmToken token = c.ts.get();
switch (token.kind()) {
case WasmToken::Local:
if (!ParseLocalOrParam(c, &locals, &vars))
return nullptr;
break;
case WasmToken::Param:
if (!vars.empty()) {
c.ts.generateError(token, c.error);
return nullptr;
}
if (!ParseLocalOrParam(c, &locals, &args))
return nullptr;
break;
case WasmToken::Result:
if (!ParseResult(c, &result))
return nullptr;
break;
default:
c.ts.unget(token);
AstExpr* expr = ParseExprInsideParens(c);
if (!expr || !body.append(expr))
return nullptr;
break;
}
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
}
if (!ParseExprList(c, &body, true))
return nullptr;
if (sig.isInvalid()) {
uint32_t sigIndex;
if (!module->declare(AstSig(Move(args), result), &sigIndex))
return nullptr;
sig.setIndex(sigIndex);
}
return new(c.lifo) AstFunc(funcName, sig, Move(vars), Move(locals), Move(body));
return c.ts.match(WasmToken::Text, &import->module, c.error) &&
c.ts.match(WasmToken::Text, &import->field, c.error);
}
static bool
ParseFuncType(WasmParseContext& c, AstSig* sig)
ParseInlineExport(WasmParseContext& c, DefinitionKind kind, AstModule* module,
AstRef ref = AstRef())
{
WasmToken name;
if (!c.ts.match(WasmToken::Text, &name, c.error))
return false;
AstExport* exp = nullptr;
if (!ref.isInvalid())
exp = new(c.lifo) AstExport(name.text(), kind, ref);
else
exp = new(c.lifo) AstExport(name.text(), kind);
return exp && module->append(exp);
}
static bool
MaybeParseTypeUse(WasmParseContext& c, AstRef* sig)
{
WasmToken openParen;
if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
if (c.ts.getIf(WasmToken::Type)) {
if (!c.ts.matchRef(sig, c.error))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
} else {
c.ts.unget(openParen);
}
}
return true;
}
static bool
ParseFuncSig(WasmParseContext& c, AstSig* sig)
{
AstValTypeVector args(c.lifo);
ExprType result = ExprType::Void;
@ -2609,6 +2570,121 @@ ParseFuncType(WasmParseContext& c, AstSig* sig)
return true;
}
static bool
ParseFuncType(WasmParseContext& c, AstRef* ref, AstModule* module)
{
if (!MaybeParseTypeUse(c, ref))
return false;
if (ref->isInvalid()) {
AstSig sig(c.lifo);
if (!ParseFuncSig(c, &sig))
return false;
uint32_t sigIndex;
if (!module->declare(Move(sig), &sigIndex))
return false;
ref->setIndex(sigIndex);
}
return true;
}
static bool
ParseFunc(WasmParseContext& c, AstModule* module)
{
AstValTypeVector vars(c.lifo);
AstValTypeVector args(c.lifo);
AstNameVector locals(c.lifo);
AstName funcName = c.ts.getIfName();
// Inline imports and exports.
WasmToken openParen;
if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
if (c.ts.getIf(WasmToken::Import)) {
if (module->funcs().length()) {
c.ts.generateError(openParen, "import after function definition", c.error);
return false;
}
InlineImport names;
if (!ParseInlineImport(c, &names))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
AstRef sig;
if (!ParseFuncType(c, &sig, module))
return false;
auto* imp = new(c.lifo) AstImport(funcName, names.module.text(), names.field.text(), sig);
return imp && module->append(imp);
}
if (c.ts.getIf(WasmToken::Export)) {
AstRef ref = funcName.empty()
? AstRef(AstName(), module->funcImportNames().length() + module->funcs().length())
: AstRef(funcName, AstNoIndex);
if (!ParseInlineExport(c, DefinitionKind::Function, module, ref))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
} else {
c.ts.unget(openParen);
}
}
AstRef sigRef;
if (!MaybeParseTypeUse(c, &sigRef))
return false;
AstExprVector body(c.lifo);
ExprType result = ExprType::Void;
while (c.ts.getIf(WasmToken::OpenParen)) {
WasmToken token = c.ts.get();
switch (token.kind()) {
case WasmToken::Local:
if (!ParseLocalOrParam(c, &locals, &vars))
return false;
break;
case WasmToken::Param:
if (!vars.empty()) {
c.ts.generateError(token, c.error);
return false;
}
if (!ParseLocalOrParam(c, &locals, &args))
return false;
break;
case WasmToken::Result:
if (!ParseResult(c, &result))
return false;
break;
default:
c.ts.unget(token);
AstExpr* expr = ParseExprInsideParens(c);
if (!expr || !body.append(expr))
return false;
break;
}
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
}
if (!ParseExprList(c, &body, true))
return false;
if (sigRef.isInvalid()) {
uint32_t sigIndex;
if (!module->declare(AstSig(Move(args), result), &sigIndex))
return false;
sigRef.setIndex(sigIndex);
}
auto* func = new(c.lifo) AstFunc(funcName, sigRef, Move(vars), Move(locals), Move(body));
return func && module->append(func);
}
static AstSig*
ParseTypeDef(WasmParseContext& c)
{
@ -2620,7 +2696,7 @@ ParseTypeDef(WasmParseContext& c)
return nullptr;
AstSig sig(c.lifo);
if (!ParseFuncType(c, &sig))
if (!ParseFuncSig(c, &sig))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
@ -2629,15 +2705,26 @@ ParseTypeDef(WasmParseContext& c)
return new(c.lifo) AstSig(name, Move(sig));
}
static bool
MaybeParseOwnerIndex(WasmParseContext& c)
{
if (c.ts.peek().kind() == WasmToken::Index) {
WasmToken elemIndex = c.ts.get();
if (elemIndex.index()) {
c.ts.generateError(elemIndex, "can't handle non-default memory/table yet", c.error);
return false;
}
}
return true;
}
static AstDataSegment*
ParseDataSegment(WasmParseContext& c)
{
AstExpr* offset;
WasmToken dstOffset;
if (c.ts.getIf(WasmToken::Index, &dstOffset))
offset = new(c.lifo) AstConst(Val(dstOffset.index()));
else
offset = ParseExpr(c, true);
if (!MaybeParseOwnerIndex(c))
return nullptr;
AstExpr* offset = ParseExpr(c, true);
if (!offset)
return nullptr;
@ -2649,7 +2736,7 @@ ParseDataSegment(WasmParseContext& c)
}
static bool
ParseResizable(WasmParseContext& c, ResizableLimits* resizable)
ParseLimits(WasmParseContext& c, Limits* resizable)
{
WasmToken initial;
if (!c.ts.match(WasmToken::Index, &initial, c.error))
@ -2660,7 +2747,7 @@ ParseResizable(WasmParseContext& c, ResizableLimits* resizable)
if (c.ts.getIf(WasmToken::Index, &token))
maximum.emplace(token.index());
ResizableLimits r = { initial.index(), maximum };
Limits r = { initial.index(), maximum };
*resizable = r;
return true;
}
@ -2668,6 +2755,36 @@ ParseResizable(WasmParseContext& c, ResizableLimits* resizable)
static bool
ParseMemory(WasmParseContext& c, WasmToken token, AstModule* module)
{
AstName name = c.ts.getIfName();
WasmToken openParen;
if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
if (c.ts.getIf(WasmToken::Import)) {
InlineImport names;
if (!ParseInlineImport(c, &names))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
Limits memory;
if (!ParseLimits(c, &memory))
return false;
auto* imp = new(c.lifo) AstImport(name, names.module.text(), names.field.text(),
DefinitionKind::Memory, memory);
return imp && module->append(imp);
}
if (c.ts.getIf(WasmToken::Export)) {
if (!ParseInlineExport(c, DefinitionKind::Memory, module))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
} else {
c.ts.unget(openParen);
}
}
if (c.ts.getIf(WasmToken::OpenParen)) {
if (!c.ts.match(WasmToken::Data, c.error))
return false;
@ -2688,7 +2805,7 @@ ParseMemory(WasmParseContext& c, WasmToken token, AstModule* module)
return false;
}
ResizableLimits memory = { uint32_t(pages), Some(uint32_t(pages)) };
Limits memory = { uint32_t(pages), Some(uint32_t(pages)) };
if (!module->setMemory(memory))
return false;
@ -2698,8 +2815,8 @@ ParseMemory(WasmParseContext& c, WasmToken token, AstModule* module)
return true;
}
ResizableLimits memory;
if (!ParseResizable(c, &memory))
Limits memory;
if (!ParseLimits(c, &memory))
return false;
if (!module->setMemory(memory)) {
@ -2728,15 +2845,32 @@ ParseStartFunc(WasmParseContext& c, WasmToken token, AstModule* module)
static bool
ParseGlobalType(WasmParseContext& c, WasmToken* typeToken, uint32_t* flags)
{
if (!c.ts.match(WasmToken::ValueType, typeToken, c.error))
return false;
// Either (mut i32) or i32.
if (c.ts.getIf(WasmToken::OpenParen)) {
// Immutable by default.
*flags = c.ts.getIf(WasmToken::Mutable) ? 0x1 : 0x0;
if (!c.ts.match(WasmToken::ValueType, typeToken, c.error))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
return true;
}
// Mutable by default.
*flags = 0x1;
if (c.ts.getIf(WasmToken::Immutable))
*flags = 0x0;
return c.ts.match(WasmToken::ValueType, typeToken, c.error);
}
return true;
static bool
ParseElemType(WasmParseContext& c)
{
// Only AnyFunc is allowed at the moment.
return c.ts.match(WasmToken::AnyFunc, c.error);
}
static bool
ParseTableSig(WasmParseContext& c, Limits* table)
{
return ParseLimits(c, table) &&
ParseElemType(c);
}
static AstImport*
@ -2756,8 +2890,11 @@ ParseImport(WasmParseContext& c, AstModule* module)
WasmToken openParen;
if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
if (c.ts.getIf(WasmToken::Memory)) {
ResizableLimits memory;
if (!ParseResizable(c, &memory))
if (name.empty())
name = c.ts.getIfName();
Limits memory;
if (!ParseLimits(c, &memory))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
@ -2765,8 +2902,11 @@ ParseImport(WasmParseContext& c, AstModule* module)
DefinitionKind::Memory, memory);
}
if (c.ts.getIf(WasmToken::Table)) {
ResizableLimits table;
if (!ParseResizable(c, &table))
if (name.empty())
name = c.ts.getIfName();
Limits table;
if (!ParseTableSig(c, &table))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
@ -2774,38 +2914,30 @@ ParseImport(WasmParseContext& c, AstModule* module)
DefinitionKind::Table, table);
}
if (c.ts.getIf(WasmToken::Global)) {
if (name.empty())
name = c.ts.getIfName();
WasmToken typeToken;
uint32_t flags = 0;
if (!ParseGlobalType(c, &typeToken, &flags))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
return new(c.lifo) AstImport(name, moduleName.text(), fieldName.text(),
AstGlobal(AstName(), typeToken.valueType(), flags));
}
if (c.ts.getIf(WasmToken::Func)) {
AstName name = c.ts.getIfName();
if (name.empty())
name = c.ts.getIfName();
WasmToken token;
if (c.ts.getIf(WasmToken::Type, &token)) {
if (!c.ts.matchRef(&sigRef, c.error))
return nullptr;
} else {
AstSig sig(c.lifo);
if (!ParseFuncType(c, &sig))
return nullptr;
uint32_t sigIndex;
if (!module->declare(Move(sig), &sigIndex))
return nullptr;
sigRef.setIndex(sigIndex);
}
AstRef sigRef;
if (!ParseFuncType(c, &sigRef, module))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
return new(c.lifo) AstImport(name, moduleName.text(), fieldName.text(),
sigRef);
return new(c.lifo) AstImport(name, moduleName.text(), fieldName.text(), sigRef);
}
if (c.ts.getIf(WasmToken::Type)) {
@ -2820,7 +2952,7 @@ ParseImport(WasmParseContext& c, AstModule* module)
if (sigRef.isInvalid()) {
AstSig sig(c.lifo);
if (!ParseFuncType(c, &sig))
if (!ParseFuncSig(c, &sig))
return nullptr;
uint32_t sigIndex;
@ -2879,10 +3011,14 @@ ParseExport(WasmParseContext& c)
break;
}
case WasmToken::Table:
if (!MaybeParseOwnerIndex(c))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
return new(c.lifo) AstExport(name.text(), DefinitionKind::Table);
case WasmToken::Memory:
if (!MaybeParseOwnerIndex(c))
return nullptr;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
return new(c.lifo) AstExport(name.text(), DefinitionKind::Memory);
@ -2905,20 +3041,48 @@ ParseExport(WasmParseContext& c)
c.ts.generateError(exportee, c.error);
return nullptr;
}
static bool
ParseTable(WasmParseContext& c, WasmToken token, AstModule* module)
{
AstName name = c.ts.getIfName();
if (c.ts.getIf(WasmToken::OpenParen)) {
if (!c.ts.match(WasmToken::Resizable, c.error))
// Either an import and we're done, or an export and continue.
if (c.ts.getIf(WasmToken::Import)) {
InlineImport names;
if (!ParseInlineImport(c, &names))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
Limits table;
if (!ParseTableSig(c, &table))
return false;
auto* import = new(c.lifo) AstImport(name, names.module.text(), names.field.text(),
DefinitionKind::Table, table);
return import && module->append(import);
}
if (!c.ts.match(WasmToken::Export, c.error)) {
c.ts.generateError(token, c.error);
return false;
ResizableLimits table;
if (!ParseResizable(c, &table))
}
if (!ParseInlineExport(c, DefinitionKind::Table, module))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
}
// Either: min max? anyfunc
if (c.ts.peek().kind() == WasmToken::Index) {
Limits table;
if (!ParseTableSig(c, &table))
return false;
if (!module->setTable(table)) {
c.ts.generateError(token, c.error);
return false;
@ -2926,6 +3090,15 @@ ParseTable(WasmParseContext& c, WasmToken token, AstModule* module)
return true;
}
// Or: anyfunc (elem 1 2 ...)
if (!ParseElemType(c))
return false;
if (!c.ts.match(WasmToken::OpenParen, c.error))
return false;
if (!c.ts.match(WasmToken::Elem, c.error))
return false;
AstRefVector elems(c.lifo);
AstRef elem;
@ -2934,11 +3107,14 @@ ParseTable(WasmParseContext& c, WasmToken token, AstModule* module)
return false;
}
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
uint32_t numElements = uint32_t(elems.length());
if (numElements != elems.length())
return false;
ResizableLimits r = { numElements, Some(numElements) };
Limits r = { numElements, Some(numElements) };
if (!module->setTable(r)) {
c.ts.generateError(token, c.error);
return false;
@ -2955,6 +3131,9 @@ ParseTable(WasmParseContext& c, WasmToken token, AstModule* module)
static AstElemSegment*
ParseElemSegment(WasmParseContext& c)
{
if (!MaybeParseOwnerIndex(c))
return nullptr;
AstExpr* offset = ParseExpr(c, true);
if (!offset)
return nullptr;
@ -2970,21 +3149,58 @@ ParseElemSegment(WasmParseContext& c)
return new(c.lifo) AstElemSegment(offset, Move(elems));
}
static AstGlobal*
ParseGlobal(WasmParseContext& c)
static bool
ParseGlobal(WasmParseContext& c, AstModule* module)
{
AstName name = c.ts.getIfName();
WasmToken typeToken;
uint32_t flags = 0;
WasmToken openParen;
if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
if (c.ts.getIf(WasmToken::Import)) {
if (module->globals().length()) {
c.ts.generateError(openParen, "import after global definition", c.error);
return false;
}
InlineImport names;
if (!ParseInlineImport(c, &names))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
if (!ParseGlobalType(c, &typeToken, &flags))
return false;
auto* imp = new(c.lifo) AstImport(name, names.module.text(), names.field.text(),
AstGlobal(AstName(), typeToken.valueType(), flags));
return imp && module->append(imp);
}
if (c.ts.getIf(WasmToken::Export)) {
AstRef ref = name.empty()
? AstRef(AstName(), module->globals().length())
: AstRef(name, AstNoIndex);
if (!ParseInlineExport(c, DefinitionKind::Global, module, ref))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
} else {
c.ts.unget(openParen);
}
}
if (!ParseGlobalType(c, &typeToken, &flags))
return nullptr;
return false;
AstExpr* init = ParseExpr(c, true);
if (!init)
return nullptr;
return false;
return new(c.lifo) AstGlobal(name, typeToken.valueType(), flags, Some(init));
auto* glob = new(c.lifo) AstGlobal(name, typeToken.valueType(), flags, Some(init));
return glob && module->append(glob);
}
static AstModule*
@ -2997,7 +3213,7 @@ ParseModule(const char16_t* text, LifoAlloc& lifo, UniqueChars* error)
if (!c.ts.match(WasmToken::Module, c.error))
return nullptr;
auto module = new(c.lifo) AstModule(c.lifo);
auto* module = new(c.lifo) AstModule(c.lifo);
if (!module || !module->init())
return nullptr;
@ -3022,8 +3238,7 @@ ParseModule(const char16_t* text, LifoAlloc& lifo, UniqueChars* error)
break;
}
case WasmToken::Global: {
AstGlobal* global = ParseGlobal(c);
if (!global || !module->append(global))
if (!ParseGlobal(c, module))
return nullptr;
break;
}
@ -3057,8 +3272,7 @@ ParseModule(const char16_t* text, LifoAlloc& lifo, UniqueChars* error)
break;
}
case WasmToken::Func: {
AstFunc* func = ParseFunc(c, module);
if (!func || !module->append(func))
if (!ParseFunc(c, module))
return nullptr;
break;
}
@ -4072,20 +4286,20 @@ EncodeBytes(Encoder& e, AstName wasmName)
}
static bool
EncodeResizable(Encoder& e, const ResizableLimits& resizable)
EncodeLimits(Encoder& e, const Limits& limits)
{
uint32_t flags = uint32_t(ResizableFlags::Default);
if (resizable.maximum)
if (limits.maximum)
flags |= uint32_t(ResizableFlags::HasMaximum);
if (!e.writeVarU32(flags))
return false;
if (!e.writeVarU32(resizable.initial))
if (!e.writeVarU32(limits.initial))
return false;
if (resizable.maximum) {
if (!e.writeVarU32(*resizable.maximum))
if (limits.maximum) {
if (!e.writeVarU32(*limits.maximum))
return false;
}
@ -4093,12 +4307,12 @@ EncodeResizable(Encoder& e, const ResizableLimits& resizable)
}
static bool
EncodeResizableTable(Encoder& e, const ResizableLimits& resizable)
EncodeTableLimits(Encoder& e, const Limits& limits)
{
if (!e.writeVarU32(uint32_t(TypeConstructor::AnyFunc)))
return false;
return EncodeResizable(e, resizable);
return EncodeLimits(e, limits);
}
static bool
@ -4126,11 +4340,11 @@ EncodeImport(Encoder& e, AstImport& imp)
return false;
break;
case DefinitionKind::Table:
if (!EncodeResizableTable(e, imp.resizable()))
if (!EncodeTableLimits(e, imp.resizable()))
return false;
break;
case DefinitionKind::Memory:
if (!EncodeResizable(e, imp.resizable()))
if (!EncodeLimits(e, imp.resizable()))
return false;
break;
}
@ -4174,9 +4388,9 @@ EncodeMemorySection(Encoder& e, AstModule& module)
if (!e.writeVarU32(numMemories))
return false;
const ResizableLimits& memory = module.memory();
const Limits& memory = module.memory();
if (!EncodeResizable(e, memory))
if (!EncodeLimits(e, memory))
return false;
e.finishSection(offset);
@ -4273,8 +4487,8 @@ EncodeTableSection(Encoder& e, AstModule& module)
if (!e.writeVarU32(numTables))
return false;
const ResizableLimits& table = module.table();
if (!EncodeResizableTable(e, table))
const Limits& table = module.table();
if (!EncodeTableLimits(e, table))
return false;
e.finishSection(offset);

View File

@ -935,7 +935,7 @@ enum ModuleKind
// Represents the resizable limits of memories and tables.
struct ResizableLimits
struct Limits
{
uint32_t initial;
Maybe<uint32_t> maximum;
@ -956,10 +956,10 @@ struct TableDesc
TableKind kind;
bool external;
uint32_t globalDataOffset;
ResizableLimits limits;
Limits limits;
TableDesc() = default;
TableDesc(TableKind kind, ResizableLimits limits)
TableDesc(TableKind kind, Limits limits)
: kind(kind),
external(false),
globalDataOffset(UINT32_MAX),

View File

@ -4335,9 +4335,9 @@ BytecodeEmitter::emitDestructuringLHS(ParseNode* target, DestructuringFlavor fla
else if (target->isKind(PNK_ASSIGN))
target = target->pn_left;
if (target->isKind(PNK_ARRAY) || target->isKind(PNK_OBJECT)) {
if (!emitDestructuringOpsHelper(target, flav))
if (!emitDestructuringOps(target, flav))
return false;
// Per its post-condition, emitDestructuringOpsHelper has left the
// Per its post-condition, emitDestructuringOps has left the
// to-be-destructured value on top of the stack.
if (!emit1(JSOP_POP))
return false;
@ -4514,7 +4514,7 @@ BytecodeEmitter::emitDefault(ParseNode* defaultExpr)
}
bool
BytecodeEmitter::emitDestructuringOpsArrayHelper(ParseNode* pattern, DestructuringFlavor flav)
BytecodeEmitter::emitDestructuringOpsArray(ParseNode* pattern, DestructuringFlavor flav)
{
MOZ_ASSERT(pattern->isKind(PNK_ARRAY));
MOZ_ASSERT(pattern->isArity(PN_LIST));
@ -4781,7 +4781,7 @@ BytecodeEmitter::emitComputedPropertyName(ParseNode* computedPropName)
}
bool
BytecodeEmitter::emitDestructuringOpsObjectHelper(ParseNode* pattern, DestructuringFlavor flav)
BytecodeEmitter::emitDestructuringOpsObject(ParseNode* pattern, DestructuringFlavor flav)
{
MOZ_ASSERT(pattern->isKind(PNK_OBJECT));
MOZ_ASSERT(pattern->isArity(PN_LIST));
@ -4855,28 +4855,12 @@ BytecodeEmitter::emitDestructuringOpsObjectHelper(ParseNode* pattern, Destructur
return true;
}
/*
* Recursive helper for emitDestructuringOps.
* EmitDestructuringOpsHelper assumes the to-be-destructured value has been
* pushed on the stack and emits code to destructure each part of a [] or {}
* lhs expression.
*/
bool
BytecodeEmitter::emitDestructuringOpsHelper(ParseNode* pattern, DestructuringFlavor flav)
{
if (pattern->isKind(PNK_ARRAY))
return emitDestructuringOpsArrayHelper(pattern, flav);
return emitDestructuringOpsObjectHelper(pattern, flav);
}
bool
BytecodeEmitter::emitDestructuringOps(ParseNode* pattern, DestructuringFlavor flav)
{
/*
* Call our recursive helper to emit the destructuring assignments and
* related stack manipulations.
*/
return emitDestructuringOpsHelper(pattern, flav);
if (pattern->isKind(PNK_ARRAY))
return emitDestructuringOpsArray(pattern, flav);
return emitDestructuringOpsObject(pattern, flav);
}
bool
@ -4940,55 +4924,20 @@ BytecodeEmitter::emitDeclarationList(ParseNode* declList)
return false;
next = decl->pn_next;
if (decl->isKind(PNK_ARRAY) || decl->isKind(PNK_OBJECT)) {
// Destructuring BindingPattern in a deprecated comprehension:
// a = [x*y for (let [x, y] of pts)];
//
// (When emitting code for a plain LexicalDeclaration, like
// `let [x, y] = pt;`, decl will be a PNK_ASSIGN node, not a
// PNK_ARRAY node. `let [x, y];` without an initializer is a
// SyntaxError.)
MOZ_ASSERT(declList->pn_count == 1);
auto emitInitializeToUndefined = [](BytecodeEmitter* bce, ParseNode *pn) {
MOZ_ASSERT(bce->lookupName(pn->name()).hasKnownSlot());
MOZ_ASSERT(bce->lookupName(pn->name()).isLexical());
auto emitUndefined = [](BytecodeEmitter* bce, const NameLocation&, bool) {
return bce->emit1(JSOP_UNDEFINED);
};
if (!bce->emitInitializeName(pn, emitUndefined))
return false;
// Pop the RHS.
return bce->emit1(JSOP_POP);
};
if (!emitDestructuringDeclsWithEmitter(decl, emitInitializeToUndefined))
return false;
} else if (decl->isKind(PNK_ASSIGN)) {
/*
* A destructuring initialiser assignment preceded by var will
* never occur to the left of 'in' in a for-in loop. As with 'for
* (var x = i in o)...', this will cause the entire 'var [a, b] =
* i' to be hoisted out of the loop.
*/
if (decl->isKind(PNK_ASSIGN)) {
MOZ_ASSERT(decl->isOp(JSOP_NOP));
if (decl->pn_left->isKind(PNK_NAME)) {
if (!emitSingleDeclaration(declList, decl->pn_left, decl->pn_right))
return false;
} else {
ParseNode* initializer = decl->pn_left;
ParseNode* pattern = decl->pn_left;
MOZ_ASSERT(pattern->isKind(PNK_ARRAY) || pattern->isKind(PNK_OBJECT));
if (!emitTree(decl->pn_right))
return false;
if (!emitTree(decl->pn_right))
return false;
if (!emitDestructuringOpsHelper(initializer, DestructuringDeclaration))
return false;
if (!emitDestructuringOps(pattern, DestructuringDeclaration))
return false;
if (!emit1(JSOP_POP))
return false;
}
if (!emit1(JSOP_POP))
return false;
} else {
if (!emitSingleDeclaration(declList, decl, decl->expr()))
return false;
@ -6082,9 +6031,7 @@ BytecodeEmitter::emitInitializeForInOrOfTarget(ParseNode* forHead)
}
MOZ_ASSERT(!target->isKind(PNK_ASSIGN),
"for-in/of loop declarations can't have initializers; or if "
"they do, those initializers are ignored -- see "
"Parser::declarationPattern");
"for-in/of loop destructuring declarations can't have initializers");
MOZ_ASSERT(target->isKind(PNK_ARRAY) || target->isKind(PNK_OBJECT));
return emitDestructuringOps(target, DestructuringDeclaration);
@ -6226,6 +6173,33 @@ BytecodeEmitter::emitForIn(ParseNode* forInLoop, EmitterScope* headLexicalEmitte
MOZ_ASSERT(forInHead->isKind(PNK_FORIN));
MOZ_ASSERT(forInHead->isArity(PN_TERNARY));
// Annex B: Evaluate the var-initializer expression if present.
// |for (var i = initializer in expr) { ... }|
ParseNode* forInTarget = forInHead->pn_kid1;
if (parser->handler.isDeclarationList(forInTarget)) {
ParseNode* decl = parser->handler.singleBindingFromDeclaration(forInTarget);
if (decl->isKind(PNK_NAME)) {
if (ParseNode* initializer = decl->expr()) {
MOZ_ASSERT(forInTarget->isKind(PNK_VAR),
"for-in initializers are only permitted for |var| declarations");
if (!updateSourceCoordNotes(decl->pn_pos.begin))
return false;
auto emitRhs = [initializer](BytecodeEmitter* bce, const NameLocation&, bool) {
return bce->emitTree(initializer);
};
if (!emitInitializeName(decl, emitRhs))
return false;
// Pop the initializer.
if (!emit1(JSOP_POP))
return false;
}
}
}
// Evaluate the expression being iterated.
ParseNode* expr = forInHead->pn_kid3;
if (!emitTree(expr)) // EXPR
@ -6268,7 +6242,6 @@ BytecodeEmitter::emitForIn(ParseNode* forInLoop, EmitterScope* headLexicalEmitte
// recreation each iteration. If a lexical scope exists for the head,
// it must be the innermost one. If that scope has closed-over
// bindings inducing an environment, recreate the current environment.
DebugOnly<ParseNode*> forInTarget = forInHead->pn_kid1;
MOZ_ASSERT(forInTarget->isKind(PNK_LET) || forInTarget->isKind(PNK_CONST));
MOZ_ASSERT(headLexicalEmitterScope == innermostEmitterScope);
MOZ_ASSERT(headLexicalEmitterScope->scope(this)->kind() == ScopeKind::Lexical);

View File

@ -641,17 +641,19 @@ struct MOZ_STACK_CLASS BytecodeEmitter
DestructuringAssignment
};
// EmitDestructuringLHS assumes the to-be-destructured value has been pushed on
// emitDestructuringLHS assumes the to-be-destructured value has been pushed on
// the stack and emits code to destructure a single lhs expression (either a
// name or a compound []/{} expression).
MOZ_MUST_USE bool emitDestructuringLHS(ParseNode* target, DestructuringFlavor flav);
MOZ_MUST_USE bool emitConditionallyExecutedDestructuringLHS(ParseNode* target,
DestructuringFlavor flav);
// emitDestructuringOps assumes the to-be-destructured value has been
// pushed on the stack and emits code to destructure each part of a [] or
// {} lhs expression.
MOZ_MUST_USE bool emitDestructuringOps(ParseNode* pattern, DestructuringFlavor flav);
MOZ_MUST_USE bool emitDestructuringOpsHelper(ParseNode* pattern, DestructuringFlavor flav);
MOZ_MUST_USE bool emitDestructuringOpsArrayHelper(ParseNode* pattern, DestructuringFlavor flav);
MOZ_MUST_USE bool emitDestructuringOpsObjectHelper(ParseNode* pattern, DestructuringFlavor flav);
MOZ_MUST_USE bool emitDestructuringOpsArray(ParseNode* pattern, DestructuringFlavor flav);
MOZ_MUST_USE bool emitDestructuringOpsObject(ParseNode* pattern, DestructuringFlavor flav);
typedef bool
(*DestructuringDeclEmitter)(BytecodeEmitter* bce, ParseNode* pn);

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