This commit is contained in:
Ryan VanderMeulen 2013-06-14 21:42:59 -04:00
Родитель 6a87e37411 2a21128c26
Коммит 978c564339
364 изменённых файлов: 5984 добавлений и 3099 удалений

Просмотреть файл

@ -18,3 +18,4 @@
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 879831 needed to clobber for the removal of jsprobes.cpp
bug 882904: move LIBS to moz.build (logic).

Просмотреть файл

@ -2112,6 +2112,14 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartIndex,
ENameValueFlag
HyperTextAccessible::NativeName(nsString& aName)
{
// Check @alt attribute for invalid img elements.
bool hasImgAlt = false;
if (mContent->IsHTML(nsGkAtoms::img)) {
hasImgAlt = mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
if (!aName.IsEmpty())
return eNameOK;
}
ENameValueFlag nameFlag = AccessibleWrap::NativeName(aName);
if (!aName.IsEmpty())
return nameFlag;
@ -2123,7 +2131,7 @@ HyperTextAccessible::NativeName(nsString& aName)
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName))
aName.CompressWhitespace();
return eNameOK;
return hasImgAlt ? eNoNameOnPurpose : eNameOK;
}
void

Просмотреть файл

@ -16,6 +16,8 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
'resource://gre/modules/accessibility/Utils.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'EventManager',
'resource://gre/modules/accessibility/EventManager.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'ObjectWrapper',
'resource://gre/modules/ObjectWrapper.jsm');
Logger.debug('content-script.js');
@ -182,6 +184,21 @@ function scroll(aMessage) {
while (acc) {
let elem = acc.DOMNode;
// This is inspired by IndieUI events. Once they are
// implemented, it should be easy to transition to them.
// https://dvcs.w3.org/hg/IndieUI/raw-file/tip/src/indie-ui-events.html#scrollrequest
let uiactions = elem.getAttribute ? elem.getAttribute('uiactions') : '';
if (uiactions && uiactions.split(' ').indexOf('scroll') >= 0) {
let evt = elem.ownerDocument.createEvent('CustomEvent');
let details = horiz ? { deltaX: page * elem.clientWidth } :
{ deltaY: page * elem.clientHeight };
evt.initCustomEvent(
'scrollrequest', true, true,
ObjectWrapper.wrap(details, elem.ownerDocument.defaultView));
if (!elem.dispatchEvent(evt))
return;
}
// We will do window scrolling next.
if (elem == content.document)
break;
@ -202,25 +219,6 @@ function scroll(aMessage) {
return true;
}
}
let controllers = acc.
getRelationByType(
Ci.nsIAccessibleRelation.RELATION_CONTROLLED_BY);
for (let i = 0; controllers.targetsCount > i; i++) {
let controller = controllers.getTarget(i);
// If the section has a controlling slider, it should be considered
// the page-turner.
if (controller.role == Ci.nsIAccessibleRole.ROLE_SLIDER) {
// Sliders are controlled with ctrl+right/left. I just decided :)
let evt = content.document.createEvent('KeyboardEvent');
evt.initKeyEvent(
'keypress', true, true, null,
true, false, false, false,
(page > 0) ? evt.DOM_VK_RIGHT : evt.DOM_VK_LEFT, 0);
controller.DOMNode.dispatchEvent(evt);
return true;
}
}
}
acc = acc.parent;
}

Просмотреть файл

@ -208,6 +208,7 @@
// Test equation image
testName("img_eq", "x^2 + y^2 + z^2")
testName("input_img_eq", "x^2 + y^2 + z^2")
testName("txt_eq", "x^2 + y^2 + z^2")
////////////////////////////////////////////////////////////////////////
@ -606,6 +607,7 @@
<p>Image:
<img id="img_eq" role="math" src="foo" alt="x^2 + y^2 + z^2">
<input type="image" id="input_img_eq" src="foo" alt="x^2 + y^2 + z^2">
</p>
<p>Text:

Просмотреть файл

@ -34,6 +34,7 @@ MOCHITEST_A11Y_FILES =\
test_groupbox.xul \
test_iframe.html \
test_img.html \
test_invalid_img.xhtml \
test_invalidationlist.html \
test_list.html \
test_map.html \

Просмотреть файл

@ -0,0 +1,50 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>invalid html img</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script>
<![CDATA[
function doTest()
{
document.getElementsByTagName("img")[0].firstChild.data = "2";
var accTree = {
role: ROLE_TEXT_CONTAINER,
children: [ { role: ROLE_TEXT_LEAF } ]
};
testAccessibleTree("the_img", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
</head>
<body>
<a target="_blank"
title="use HyperTextAccessible for invalid img"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=852129">
Mozilla Bug 852129
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<img id="the_img">1</img>
</body>
</html>

Просмотреть файл

@ -51,7 +51,6 @@ STL_FLAGS=
LIBS += $(JEMALLOC_LIBS)
LIBS += \
$(EXTRA_DSO_LIBS) \
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
$(NULL)

Просмотреть файл

@ -9,7 +9,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXTRA_PP_COMPONENTS = \
DISABLED_EXTRA_PP_COMPONENTS = \
ActivitiesGlue.js \
AlertsService.js \
B2GAboutRedirector.js \
@ -36,7 +36,7 @@ EXTRA_JS_MODULES = \
$(NULL)
ifdef MOZ_UPDATER
EXTRA_PP_COMPONENTS += UpdatePrompt.js
DISABLED_EXTRA_PP_COMPONENTS += UpdatePrompt.js
endif
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -12,3 +12,26 @@ XPIDL_SOURCES += [
MODULE = 'B2GComponents'
EXTRA_PP_COMPONENTS += [
'ActivitiesGlue.js',
'AlertsService.js',
'B2GAboutRedirector.js',
'B2GComponents.manifest',
'ContentHandler.js',
'ContentPermissionPrompt.js',
'DirectoryProvider.js',
'FilePicker.js',
'MailtoProtocolHandler.js',
'MozKeyboard.js',
'PaymentGlue.js',
'ProcessGlobal.js',
'RecoveryService.js',
'SmsProtocolHandler.js',
'TelProtocolHandler.js',
'YoutubeProtocolHandler.js',
]
if CONFIG['MOZ_UPDATER']:
EXTRA_PP_COMPONENTS += [
'UpdatePrompt.js',
]

Просмотреть файл

@ -54,7 +54,6 @@ DEFINES += -DXPCOM_GLUE
STL_FLAGS=
LIBS += \
$(EXTRA_DSO_LIBS) \
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
$(NULL)

Просмотреть файл

@ -23,7 +23,6 @@ function sendNotifyRequest(name) {
service.healthReporter.onInit().then(function onInit() {
is(policy.ensureNotifyResponse(new Date()), false, "User has not responded to policy.");
is(policy.notifyState, policy.STATE_NOTIFY_WAIT, "Policy is waiting for notification response.");
});
return policy;

Просмотреть файл

@ -45,7 +45,7 @@ function test() {
gURLBar.value = "firefox health report";
gURLBar.handleCommand();
executeSoon(function afterSearch() {
executeSoon(() => executeSoon(() => {
gBrowser.removeTab(tab);
m.getValues().then(function onData(data) {
@ -58,7 +58,7 @@ function test() {
is(newCount, oldCount + 1, "Exactly one search has been recorded.");
finish();
});
});
}));
});
});
}

Просмотреть файл

@ -13,7 +13,7 @@ DISABLED_EXTRA_COMPONENTS = \
BrowserComponents.manifest \
$(NULL)
EXTRA_PP_COMPONENTS = \
DISABLED_EXTRA_PP_COMPONENTS = \
nsBrowserContentHandler.js \
nsBrowserGlue.js \
$(NULL)

Просмотреть файл

@ -25,7 +25,7 @@ DISABLED_EXTRA_COMPONENTS = \
WebContentConverter.js \
$(NULL)
EXTRA_PP_COMPONENTS = \
DISABLED_EXTRA_PP_COMPONENTS = \
FeedWriter.js \
$(NULL)

Просмотреть файл

@ -15,3 +15,7 @@ EXTRA_COMPONENTS += [
'FeedConverter.js',
'WebContentConverter.js',
]
EXTRA_PP_COMPONENTS += [
'FeedWriter.js',
]

Просмотреть файл

@ -19,7 +19,7 @@ DISABLED_EXTRA_COMPONENTS = \
FirefoxProfileMigrator.js \
$(NULL)
EXTRA_PP_COMPONENTS = \
DISABLED_EXTRA_PP_COMPONENTS = \
ChromeProfileMigrator.js \
$(NULL)
@ -27,19 +27,19 @@ ifeq ($(OS_ARCH),WINNT)
DISABLED_EXTRA_COMPONENTS += IEProfileMigrator.js \
$(NULL)
EXTRA_PP_COMPONENTS += SafariProfileMigrator.js \
DISABLED_EXTRA_PP_COMPONENTS += SafariProfileMigrator.js \
$(NULL)
DEFINES += -DHAS_IE_MIGRATOR -DHAS_SAFARI_MIGRATOR
endif
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
EXTRA_PP_COMPONENTS += SafariProfileMigrator.js \
DISABLED_EXTRA_PP_COMPONENTS += SafariProfileMigrator.js \
$(NULL)
DEFINES += -DHAS_SAFARI_MIGRATOR
endif
EXTRA_PP_COMPONENTS += \
DISABLED_EXTRA_PP_COMPONENTS += \
BrowserProfileMigrators.manifest \
$(NULL)

Просмотреть файл

@ -20,3 +20,18 @@ if CONFIG['OS_ARCH'] == 'WINNT':
EXTRA_COMPONENTS += [
'IEProfileMigrator.js',
]
EXTRA_PP_COMPONENTS += [
'BrowserProfileMigrators.manifest',
'ChromeProfileMigrator.js',
]
if CONFIG['OS_ARCH'] == 'WINNT':
EXTRA_PP_COMPONENTS += [
'SafariProfileMigrator.js',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
EXTRA_PP_COMPONENTS += [
'SafariProfileMigrator.js',
]

Просмотреть файл

@ -39,3 +39,7 @@ MODULE = 'browsercomps'
EXTRA_COMPONENTS += [
'BrowserComponents.manifest',
]
EXTRA_PP_COMPONENTS += [
'nsBrowserContentHandler.js',
'nsBrowserGlue.js',
]

Просмотреть файл

@ -66,7 +66,7 @@ function test() {
}
EventUtils.synthesizeKey("VK_RETURN", {});
executeSoon(afterSearch);
executeSoon(() => executeSoon(afterSearch));
});
});
}

Просмотреть файл

@ -91,16 +91,16 @@ StyleEditorPanel.prototype = {
* @param {string} href
* Url of stylesheet to find and select in editor
* @param {number} line
* Line number to jump to after selecting
* Line number to jump to after selecting. One-indexed
* @param {number} col
* Column number to jump to after selecting
* Column number to jump to after selecting. One-indexed
*/
selectStyleSheet: function(href, line, col) {
if (!this._debuggee || !this.UI) {
return;
}
let stylesheet = this._debuggee.styleSheetFromHref(href);
this.UI.selectStyleSheet(href, line, col);
this.UI.selectStyleSheet(href, line - 1, col - 1);
},
/**

Просмотреть файл

@ -48,7 +48,7 @@ function StyleEditorUI(debuggee, panelDoc) {
this._root = this._panelDoc.getElementById("style-editor-chrome");
this.editors = [];
this.selectedStyleSheetIndex = -1;
this.selectedEditor = null;
this._onStyleSheetCreated = this._onStyleSheetCreated.bind(this);
this._onStyleSheetsCleared = this._onStyleSheetsCleared.bind(this);
@ -84,6 +84,14 @@ StyleEditorUI.prototype = {
this._markedDirty = value;
},
/*
* Index of selected stylesheet in document.styleSheets
*/
get selectedStyleSheetIndex() {
return this.selectedEditor ?
this.selectedEditor.styleSheet.styleSheetIndex : -1;
},
/**
* Build the initial UI and wire buttons with event handlers.
*/
@ -140,10 +148,17 @@ StyleEditorUI.prototype = {
* Handler for debuggee's 'stylesheets-cleared' event. Remove all editors.
*/
_onStyleSheetsCleared: function() {
this._clearStyleSheetEditors();
// remember selected sheet and line number for next load
if (this.selectedEditor) {
let href = this.selectedEditor.styleSheet.href;
let {line, col} = this.selectedEditor.sourceEditor.getCaretPosition();
this.selectStyleSheet(href, line, col);
}
this._clearStyleSheetEditors();
this._view.removeAll();
this.selectedStyleSheetIndex = -1;
this.selectedEditor = null;
this._root.classList.add("loading");
},
@ -166,11 +181,22 @@ StyleEditorUI.prototype = {
* StyleSheet object for new sheet
*/
_onDocumentLoad: function(event, styleSheets) {
if (this._styleSheetToSelect) {
// if selected stylesheet from previous load isn't here,
// just set first stylesheet to be selected instead
let selectedExists = styleSheets.some((sheet) => {
return this._styleSheetToSelect.href == sheet.href;
})
if (!selectedExists) {
this._styleSheetToSelect = null;
}
}
for (let sheet of styleSheets) {
this._addStyleSheetEditor(sheet);
}
// this might be the first stylesheet, so remove loading indicator
this._root.classList.remove("loading");
this.emit("document-load");
},
@ -295,13 +321,18 @@ StyleEditorUI.prototype = {
onShow: function(summary, details, data) {
let editor = data.editor;
this.selectedEditor = editor;
this._styleSheetToSelect = null;
if (!editor.sourceEditor) {
// only initialize source editor when we switch to this view
let inputElement = details.querySelector(".stylesheet-editor-input");
editor.load(inputElement);
}
editor.onShow();
}
this.emit("editor-selected", editor);
}.bind(this)
});
},
@ -314,7 +345,6 @@ StyleEditorUI.prototype = {
for each (let editor in this.editors) {
if (editor.styleSheet.href == sheet.href) {
this._selectEditor(editor, sheet.line, sheet.col);
this._styleSheetToSelect = null;
break;
}
}
@ -331,18 +361,14 @@ StyleEditorUI.prototype = {
* Column number to jump to
*/
_selectEditor: function(editor, line, col) {
line = line || 1;
col = col || 1;
this.selectedStyleSheetIndex = editor.styleSheet.styleSheetIndex;
line = line || 0;
col = col || 0;
editor.getSourceEditor().then(() => {
editor.sourceEditor.setCaretPosition(line - 1, col - 1);
editor.sourceEditor.setCaretPosition(line, col);
});
this._view.activeSummary = editor.summary;
this.emit("editor-selected", editor);
},
/**
@ -354,9 +380,9 @@ StyleEditorUI.prototype = {
* a stylesheet is not passed and the editor is initialized we ignore
* the call.
* @param {Number} [line]
* Line to which the caret should be moved (one-indexed).
* Line to which the caret should be moved (zero-indexed).
* @param {Number} [col]
* Column to which the caret should be moved (one-indexed).
* Column to which the caret should be moved (zero-indexed).
*/
selectStyleSheet: function(href, line, col)
{

Просмотреть файл

@ -28,6 +28,7 @@ _BROWSER_TEST_FILES = \
browser_styleeditor_bug_740541_iframes.js \
browser_styleeditor_bug_851132_middle_click.js \
browser_styleeditor_nostyle.js \
browser_styleeditor_reload.js \
head.js \
four.html \
head.js \

Просмотреть файл

@ -0,0 +1,99 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const TESTCASE_URI = TEST_BASE_HTTPS + "simple.html";
const NEW_URI = TEST_BASE_HTTPS + "media.html";
const LINE_NO = 5;
const COL_NO = 3;
let gContentWin;
let gUI;
function test()
{
waitForExplicitFinish();
addTabAndOpenStyleEditor(function(panel) {
gContentWin = gBrowser.selectedTab.linkedBrowser.contentWindow.wrappedJSObject;
gUI = panel.UI;
let count = 0;
gUI.on("editor-added", function editorAdded(event, editor) {
if (++count == 2) {
gUI.off("editor-added", editorAdded);
gUI.editors[0].getSourceEditor().then(runTests);
}
})
});
content.location = TESTCASE_URI;
}
function runTests()
{
let count = 0;
gUI.once("editor-selected", (event, editor) => {
editor.getSourceEditor().then(() => {
info("selected second editor, about to reload page");
reloadPage();
gUI.on("editor-added", function editorAdded(event, editor) {
if (++count == 2) {
gUI.off("editor-added", editorAdded);
gUI.editors[1].getSourceEditor().then(testRemembered);
}
})
});
});
gUI.selectStyleSheet(gUI.editors[1].styleSheet.href, LINE_NO, COL_NO);
}
function testRemembered()
{
is(gUI.selectedEditor, gUI.editors[1], "second editor is selected");
let {line, col} = gUI.selectedEditor.sourceEditor.getCaretPosition();
is(line, LINE_NO, "correct line selected");
is(col, COL_NO, "correct column selected");
testNewPage();
}
function testNewPage()
{
let count = 0;
gUI.on("editor-added", function editorAdded(event, editor) {
info("editor added here")
if (++count == 2) {
gUI.off("editor-added", editorAdded);
gUI.editors[0].getSourceEditor().then(testNotRemembered);
}
})
info("navigating to a different page");
navigatePage();
}
function testNotRemembered()
{
is(gUI.selectedEditor, gUI.editors[0], "first editor is selected");
let {line, col} = gUI.selectedEditor.sourceEditor.getCaretPosition();
is(line, 0, "first line is selected");
is(col, 0, "first column is selected");
gUI = null;
finish();
}
function reloadPage()
{
gContentWin.location.reload();
}
function navigatePage()
{
gContentWin.location = NEW_URI;
}

Просмотреть файл

@ -8,7 +8,7 @@
// Tests that the Web Console CSP messages are displayed
const TEST_VIOLATION = "https://example.com/browser/browser/devtools/webconsole/test/test_bug_770099_violation.html";
const CSP_VIOLATION_MSG = "CSP WARN: Directive default-src https://example.com:443 violated by http://some.example.com/test.png"
const CSP_VIOLATION_MSG = "Content Security Policy: Directive default-src https://example.com:443 violated by http://some.example.com/test.png"
let hud = undefined;

Просмотреть файл

@ -10,6 +10,6 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DISABLED_EXTRA_COMPONENTS = fuelApplication.manifest
EXTRA_PP_COMPONENTS = fuelApplication.js
DISABLED_EXTRA_PP_COMPONENTS = fuelApplication.js
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -9,3 +9,7 @@ MODULE = 'fuel'
EXTRA_COMPONENTS += [
'fuelApplication.manifest',
]
EXTRA_PP_COMPONENTS += [
'fuelApplication.js',
]

Просмотреть файл

@ -143,7 +143,7 @@ let Content = {
// pages have any privilege themselves.
addEventListener("click", this, false);
docShell.QueryInterface(Ci.nsIDocShellHistory).useGlobalHistory = true;
docShell.useGlobalHistory = true;
},
/*******************************************

Просмотреть файл

@ -11,7 +11,7 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
# metro/components.manifest
EXTRA_PP_COMPONENTS = \
DISABLED_EXTRA_PP_COMPONENTS = \
components.manifest \
AboutRedirector.js \
BrowserCLH.js \

Просмотреть файл

@ -10,3 +10,14 @@ XPIDL_SOURCES += [
MODULE = 'components'
# metro/components.manifest
EXTRA_PP_COMPONENTS += [
'AboutRedirector.js',
'BrowserCLH.js',
'BrowserStartup.js',
'DirectoryProvider.js',
'HelperAppDialog.js',
'SessionStore.js',
'Sidebar.js',
'components.manifest',
]

Просмотреть файл

@ -2090,7 +2090,7 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JS::Handle<JSObject*> aObj,
// Note: jsClass is set before this loop, and also at the
// *end* of this loop.
if (IS_WRAPPER_CLASS(jsClass)) {
if (IS_WN_CLASS(jsClass)) {
result = nsXPConnect::XPConnect()->GetPrincipal(obj,
aAllowShortCircuit);
if (result) {

Просмотреть файл

@ -50,7 +50,6 @@ ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $
@echo "IMPORT_LIBRARY = $(IMPORT_LIBRARY)"
@echo "STATIC_LIBS = $(STATIC_LIBS)"
@echo "SHARED_LIBS = $(SHARED_LIBS)"
@echo "EXTRA_DSO_LIBS = $(EXTRA_DSO_LIBS)"
@echo "EXTRA_DSO_LDOPTS = $(EXTRA_DSO_LDOPTS)"
@echo "DEPENDENT_LIBS = $(DEPENDENT_LIBS)"
@echo --------------------------------------------------------------------------------

Просмотреть файл

@ -110,10 +110,6 @@ endif # ifndef .PYMAKE
_VPATH_SRCS = $(abspath $<)
ifdef EXTRA_DSO_LIBS
EXTRA_DSO_LIBS := $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS))
endif
################################################################################
# Testing frameworks support
################################################################################

Просмотреть файл

@ -766,7 +766,9 @@ public:
* Get this document's inline style sheet. May return null if there
* isn't one
*/
virtual nsHTMLCSSStyleSheet* GetInlineStyleSheet() const = 0;
nsHTMLCSSStyleSheet* GetInlineStyleSheet() const {
return mStyleAttrStyleSheet;
}
/**
* Get/set the object from which a document can get a script context
@ -2178,6 +2180,7 @@ protected:
nsRefPtr<mozilla::css::Loader> mCSSLoader;
nsRefPtr<mozilla::css::ImageLoader> mStyleImageLoader;
nsRefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
// The set of all object, embed, applet, video and audio elements for
// which this is the owner document. (They might not be in the document.)

Просмотреть файл

@ -13,6 +13,9 @@
const Cu = Components.utils;
const Ci = Components.interfaces;
const WARN_FLAG = Ci.nsIScriptError.warningFlag;
const ERROR_FLAG = Ci.nsIScriptError.ERROR_FLAG;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@ -842,7 +845,7 @@ CSPRep.prototype = {
// However, our original CSP implementation required a default src
// or an allow directive.
if (!defaultSrcDir && !this._specCompliant) {
this.warn(CSPLocalizer.getStr("allowOrDefaultSrcRequired"));
this.log(WARN_FLAG, CSPLocalizer.getStr("allowOrDefaultSrcRequired"));
return false;
}
@ -888,7 +891,9 @@ CSPRep.prototype = {
},
/**
* Sends a warning message to the error console and web developer console.
* Sends a message to the error console and web developer console.
* @param aFlag
* The nsIScriptError flag constant indicating severity
* @param aMsg
* The message to send
* @param aSource (optional)
@ -898,50 +903,25 @@ CSPRep.prototype = {
* @param aLineNum (optional)
* The number of the line where the error occurred
*/
warn:
function cspd_warn(aMsg, aSource, aScriptLine, aLineNum) {
var textMessage = 'CSP WARN: ' + aMsg + "\n";
log:
function cspd_log(aFlag, aMsg, aSource, aScriptLine, aLineNum) {
var textMessage = "Content Security Policy: " + aMsg;
var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
.createInstance(Ci.nsIScriptError);
if (this._innerWindowID) {
consoleMsg.initWithWindowID(textMessage, aSource, aScriptLine, aLineNum,
0, Ci.nsIScriptError.warningFlag,
"Content Security Policy",
0, aFlag,
"CSP",
this._innerWindowID);
} else {
consoleMsg.init(textMessage, aSource, aScriptLine, aLineNum, 0,
Ci.nsIScriptError.warningFlag,
"Content Security Policy");
aFlag,
"CSP");
}
Components.classes["@mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService).logMessage(consoleMsg);
},
/**
* Sends an error message to the error console and web developer console.
* @param aMsg
* The message to send
*/
error:
function cspsd_error(aMsg) {
var textMessage = 'CSP ERROR: ' + aMsg + "\n";
var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
.createInstance(Ci.nsIScriptError);
if (this._innerWindowID) {
consoleMsg.initWithWindowID(textMessage, null, null, 0, 0,
Ci.nsIScriptError.errorFlag,
"Content Security Policy",
this._innerWindowID);
}
else {
consoleMsg.init(textMessage, null, null, 0, 0,
Ci.nsIScriptError.errorFlag, "Content Security Policy");
}
Components.classes["@mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService).logMessage(consoleMsg);
},
};
//////////////////////////////////////////////////////////////////////
@ -1967,17 +1947,17 @@ function innerWindowFromRequest(docRequest) {
function cspError(aCSPRep, aMessage) {
if (aCSPRep) {
aCSPRep.error(aMessage);
aCSPRep.log(ERROR_FLAG, aMessage);
} else {
(new CSPRep()).error(aMessage);
(new CSPRep()).log(ERROR_FLAG, aMessage);
}
}
function cspWarn(aCSPRep, aMessage) {
if (aCSPRep) {
aCSPRep.warn(aMessage);
aCSPRep.log(WARN_FLAG, aMessage);
} else {
(new CSPRep()).warn(aMessage);
(new CSPRep()).log(WARN_FLAG, aMessage);
}
}

Просмотреть файл

@ -34,7 +34,7 @@ EXTRA_COMPONENTS = \
messageWakeupService.manifest \
$(NULL)
EXTRA_PP_COMPONENTS = \
DISABLED_EXTRA_PP_COMPONENTS = \
contentSecurityPolicy.js \
$(NULL)

Просмотреть файл

@ -25,6 +25,9 @@ const CSP_VIOLATION_TOPIC = "csp-on-violate-policy";
const CSP_TYPE_XMLHTTPREQUEST_SPEC_COMPLIANT = "csp_type_xmlhttprequest_spec_compliant";
const CSP_TYPE_WEBSOCKET_SPEC_COMPLIANT = "csp_type_websocket_spec_compliant";
const WARN_FLAG = Ci.nsIScriptError.warningFlag;
const ERROR_FLAG = Ci.nsIScriptError.ERROR_FLAG;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/CSPUtils.jsm");
@ -180,13 +183,13 @@ ContentSecurityPolicy.prototype = {
break;
case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_INLINE_SCRIPT:
if (!this._policy.allowsInlineScripts)
this._asyncReportViolation('self',null,'inline script base restriction',
this._asyncReportViolation('self', null, 'inline script base restriction',
'violated base restriction: Inline Scripts will not execute',
aSourceFile, aScriptSample, aLineNum);
break;
case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_EVAL:
if (!this._policy.allowsEvalInScripts)
this._asyncReportViolation('self',null,'eval script base restriction',
this._asyncReportViolation('self', null, 'eval script base restriction',
'violated base restriction: Code will not be created from strings',
aSourceFile, aScriptSample, aLineNum);
break;
@ -360,7 +363,7 @@ ContentSecurityPolicy.prototype = {
} else {
violationMessage = CSPLocalizer.getFormatStr("directiveViolated", [violatedDirective]);
}
this._policy.warn(violationMessage,
this._policy.log(WARN_FLAG, violationMessage,
(aSourceFile) ? aSourceFile : null,
(aScriptSample) ? decodeURIComponent(aScriptSample) : null,
(aLineNum) ? aLineNum : null);
@ -425,8 +428,8 @@ ContentSecurityPolicy.prototype = {
} catch(e) {
// it's possible that the URI was invalid, just log a
// warning and skip over that.
this._policy.warn(CSPLocalizer.getFormatStr("triedToSendReport", [uris[i]]));
this._policy.warn(CSPLocalizer.getFormatStr("errorWas", [e.toString()]));
this._policy.log(WARN_FLAG, CSPLocalizer.getFormatStr("triedToSendReport", [uris[i]]));
this._policy.log(WARN_FLAG, CSPLocalizer.getFormatStr("errorWas", [e.toString()]));
}
}
}
@ -663,7 +666,7 @@ CSPReportRedirectSink.prototype = {
// nsIChannelEventSink
asyncOnChannelRedirect: function channel_redirect(oldChannel, newChannel,
flags, callback) {
this._policy.warn(CSPLocalizer.getFormatStr("reportPostRedirect", [oldChannel.URI.asciiSpec]));
this._policy.log(WARN_FLAG, CSPLocalizer.getFormatStr("reportPostRedirect", [oldChannel.URI.asciiSpec]));
// cancel the old channel so XHR failure callback happens
oldChannel.cancel(Cr.NS_ERROR_ABORT);

Просмотреть файл

@ -153,3 +153,6 @@ CPP_SOURCES += [
'nsXMLNameSpaceMap.cpp',
]
EXTRA_PP_COMPONENTS += [
'contentSecurityPolicy.js',
]

Просмотреть файл

@ -1478,8 +1478,6 @@ nsDocument::~nsDocument()
if (mAttrStyleSheet) {
mAttrStyleSheet->SetOwningDocument(nullptr);
}
if (mStyleAttrStyleSheet)
mStyleAttrStyleSheet->SetOwningDocument(nullptr);
if (mListenerManager) {
mListenerManager->Disconnect();
@ -1539,7 +1537,6 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocumentTouch)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsITouchEventReceiver)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIInlineEventHandlers)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocumentRegister)
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIObserver)
NS_INTERFACE_TABLE_END
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsDocument)
@ -2234,37 +2231,16 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
// Now reset our inline style and attribute sheets.
if (mAttrStyleSheet) {
// Remove this sheet from all style sets
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->RemoveStyleSheet(nsStyleSet::ePresHintSheet,
mAttrStyleSheet);
}
mAttrStyleSheet->Reset(aURI);
mAttrStyleSheet->Reset();
mAttrStyleSheet->SetOwningDocument(this);
} else {
mAttrStyleSheet = new nsHTMLStyleSheet(aURI, this);
mAttrStyleSheet = new nsHTMLStyleSheet(this);
}
// Don't use AddStyleSheet, since it'll put the sheet into style
// sets in the document level, which is not desirable here.
mAttrStyleSheet->SetOwningDocument(this);
if (mStyleAttrStyleSheet) {
// Remove this sheet from all style sets
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
shell->StyleSet()->
RemoveStyleSheet(nsStyleSet::eStyleAttrSheet, mStyleAttrStyleSheet);
}
mStyleAttrStyleSheet->Reset(aURI);
} else {
mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet(aURI, this);
if (!mStyleAttrStyleSheet) {
mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet();
}
// The loop over style sets below will handle putting this sheet
// into style sets as needed.
mStyleAttrStyleSheet->SetOwningDocument(this);
// Now set up our style sets
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
@ -2295,19 +2271,13 @@ void
nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
{
NS_PRECONDITION(aStyleSet, "Must have a style set");
NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::ePresHintSheet) == 0,
"Style set already has a preshint sheet?");
NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eDocSheet) == 0,
"Style set already has document sheets?");
NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eStyleAttrSheet) == 0,
"Style set already has style attr sheets?");
NS_PRECONDITION(mStyleAttrStyleSheet, "No style attr stylesheet?");
NS_PRECONDITION(mAttrStyleSheet, "No attr stylesheet?");
aStyleSet->AppendStyleSheet(nsStyleSet::ePresHintSheet, mAttrStyleSheet);
aStyleSet->AppendStyleSheet(nsStyleSet::eStyleAttrSheet,
mStyleAttrStyleSheet);
// We could consider moving this to nsStyleSet::Init, to match its
// handling of the eAnimationSheet and eTransitionSheet levels.
aStyleSet->DirtyRuleProcessors(nsStyleSet::ePresHintSheet);
aStyleSet->DirtyRuleProcessors(nsStyleSet::eStyleAttrSheet);
int32_t i;
for (i = mStyleSheets.Count() - 1; i >= 0; --i) {
@ -5104,32 +5074,6 @@ nsDocument::RegisterEnabled()
return sPrefValue;
}
NS_IMETHODIMP
nsDocument::Register(const nsAString& aName, const JS::Value& aOptions,
JSContext* aCx, uint8_t aOptionalArgc,
jsval* aConstructor /* out param */)
{
RootedDictionary<ElementRegistrationOptions> options(aCx);
if (aOptionalArgc > 0) {
JSAutoCompartment ac(aCx, GetWrapper());
JS::Rooted<JS::Value> opts(aCx, aOptions);
NS_ENSURE_TRUE(JS_WrapValue(aCx, opts.address()),
NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(options.Init(aCx, opts),
NS_ERROR_UNEXPECTED);
}
ErrorResult rv;
JSObject* object = Register(aCx, aName, options, rv);
if (rv.Failed()) {
return rv.ErrorCode();
}
NS_ENSURE_TRUE(object, NS_ERROR_UNEXPECTED);
*aConstructor = OBJECT_TO_JSVAL(object);
return NS_OK;
}
JSObject*
nsDocument::Register(JSContext* aCx, const nsAString& aName,
const ElementRegistrationOptions& aOptions,

Просмотреть файл

@ -60,7 +60,6 @@
#include "nsIProgressEventSink.h"
#include "nsISecurityEventSink.h"
#include "nsIChannelEventSink.h"
#include "nsIDocumentRegister.h"
#include "imgIRequest.h"
#include "mozilla/dom/DOMImplementation.h"
#include "nsIDOMTouchEvent.h"
@ -505,7 +504,6 @@ class nsDocument : public nsIDocument,
public nsStubMutationObserver,
public nsIDOMDocumentTouch,
public nsIInlineEventHandlers,
public nsIDocumentRegister,
public nsIObserver
{
public:
@ -641,14 +639,6 @@ public:
return mChannel;
}
/**
* Get this document's inline style sheet. May return null if there
* isn't one
*/
virtual nsHTMLCSSStyleSheet* GetInlineStyleSheet() const MOZ_OVERRIDE {
return mStyleAttrStyleSheet;
}
/**
* Set the object from which a document can get a script context.
* This is the context within which all scripts (during document
@ -804,9 +794,6 @@ public:
// nsIInlineEventHandlers
NS_DECL_NSIINLINEEVENTHANDLERS
// nsIDocumentRegister
NS_DECL_NSIDOCUMENTREGISTER
// nsIObserver
NS_DECL_NSIOBSERVER
@ -1308,7 +1295,6 @@ protected:
// The channel that got passed to StartDocumentLoad(), if any
nsCOMPtr<nsIChannel> mChannel;
nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
// A document "without a browsing context" that owns the content of
// HTMLTemplateElement.

Просмотреть файл

@ -401,13 +401,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
AutoJSContext cx;
nsresult rv;
JS::RootedObject wrapper(cx);
bool isDOMBinding;
if (aReparentScope && (wrapper = aNode->GetWrapper()) &&
!(isDOMBinding = IsDOMObject(wrapper))) {
rv = xpc_MorphSlimWrapper(cx, aNode);
NS_ENSURE_SUCCESS(rv, rv);
}
nsNodeInfoManager *nodeInfoManager = aNewNodeInfoManager;
@ -523,19 +516,22 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
elem->RecompileScriptEventListeners();
}
if (aReparentScope && wrapper) {
if (isDOMBinding) {
rv = ReparentWrapper(cx, wrapper);
} else {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
if (xpc) {
rv = xpc->ReparentWrappedNativeIfFound(cx, wrapper, aReparentScope, aNode);
if (aReparentScope) {
JS::Rooted<JSObject*> wrapper(cx);
if ((wrapper = aNode->GetWrapper())) {
if (IsDOMObject(wrapper)) {
rv = ReparentWrapper(cx, wrapper);
} else {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
if (xpc) {
rv = xpc->ReparentWrappedNativeIfFound(cx, wrapper, aReparentScope, aNode);
}
}
}
if (NS_FAILED(rv)) {
aNode->mNodeInfo.swap(nodeInfo);
if (NS_FAILED(rv)) {
aNode->mNodeInfo.swap(nodeInfo);
return rv;
return rv;
}
}
}
}

Просмотреть файл

@ -16,6 +16,7 @@ interface nsIEventListenerInfo : nsISupports
{
/**
* The type of the event for which the listener was added.
* Null if the listener is for all the events.
*/
readonly attribute AString type;
readonly attribute boolean capturing;

Просмотреть файл

@ -1167,8 +1167,12 @@ nsEventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
CompileEventHandlerInternal(const_cast<nsListenerStruct*>(&ls),
true, nullptr);
}
const nsDependentSubstring& eventType =
Substring(nsDependentAtomString(ls.mTypeAtom), 2);
nsAutoString eventType;
if (ls.mAllEvents) {
eventType.SetIsVoid(true);
} else {
eventType.Assign(Substring(nsDependentAtomString(ls.mTypeAtom), 2));
}
// EventListenerInfo is defined in XPCOM, so we have to go ahead
// and convert to an XPCOM callback here...
nsRefPtr<nsEventListenerInfo> info =

Просмотреть файл

@ -184,6 +184,15 @@ function testAllListener() {
}
els.addListenerForAllEvents(root, allListener, false, true);
var infos = els.getListenerInfoFor(root);
var nullTypes = 0;
for (var i = 0; i < infos.length; ++i) {
if (infos[i].type == null) {
++nullTypes;
}
}
is(nullTypes, 1, "Should have one all-event-listener!");
els.addListenerForAllEvents(root, allListener, false, true, true);
els.addListenerForAllEvents(root, allListenerTrustedOnly, false, false, true);
l3.dispatchEvent(new Event("testevent", { bubbles: true }));

Просмотреть файл

@ -94,7 +94,8 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_4(HTMLTrackElement, nsGenericHTMLElement,
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTrackElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLElement)
NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
NS_HTML_CONTENT_INTERFACES(nsGenericHTMLElement)
NS_ELEMENT_INTERFACE_MAP_END
void
HTMLTrackElement::OnChannelRedirect(nsIChannel* aChannel,

Просмотреть файл

@ -44,7 +44,7 @@ public:
~nsHTMLDocument();
virtual nsresult Init() MOZ_OVERRIDE;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsHTMLDocument,
nsDocument)

Просмотреть файл

@ -171,7 +171,7 @@ AudioSegment::WriteTo(AudioStream* aOutput)
if (channelData.Length() > outputChannels) {
// Down-mix.
DownmixAndInterleave(channelData, c.mBufferFormat, duration,
c.mVolume, channelData.Length(), buf.Elements());
c.mVolume, outputChannels, buf.Elements());
} else {
InterleaveAndConvertBuffer(channelData.Elements(), c.mBufferFormat,
duration, c.mVolume,

Просмотреть файл

@ -30,9 +30,11 @@ void InterleaveAndConvertBuffer(const void** aSourceChannels,
int32_t aLength, float aVolume,
int32_t aChannels,
AudioDataValue* aOutput);
/**
* Down-mix audio channels, and interleave the channel data. A total of
* aOutputChannels*aDuration interleaved samples will be stored into aOutput.
* Given an array of input channels (aChannelData), downmix to aOutputChannels,
* interleave the channel data. A total of aOutputChannels*aDuration
* interleaved samples will be copied to a channel buffer in aOutput.
*/
void DownmixAndInterleave(const nsTArray<const void*>& aChannelData,
AudioSampleFormat aSourceFormat, int32_t aDuration,

Просмотреть файл

@ -73,6 +73,7 @@ WebVTTLoadListener::LoadResource()
mParser.own(parser);
NS_ENSURE_TRUE(mParser != nullptr, NS_ERROR_FAILURE);
mElement->mReadyState = HTMLTrackElement::LOADING;
return NS_OK;
}
@ -89,6 +90,9 @@ WebVTTLoadListener::OnStopRequest(nsIRequest* aRequest,
nsresult aStatus)
{
webvtt_finish_parsing(mParser);
if(mElement->mReadyState != HTMLTrackElement::ERROR) {
mElement->mReadyState = HTMLTrackElement::LOADED;
}
return NS_OK;
}
@ -227,6 +231,11 @@ WebVTTLoadListener::OnReportError(uint32_t aLine, uint32_t aCol,
#endif
switch(aError) {
// Non-recoverable errors require us to abort parsing:
case WEBVTT_MALFORMED_TAG:
mElement->mReadyState = HTMLTrackElement::ERROR;
return -1;
// Errors which should result in dropped cues
// if the return value is negative:
case WEBVTT_MALFORMED_TIMESTAMP:

Просмотреть файл

@ -0,0 +1,15 @@
<script>
o1 = new window.AudioContext(1, 2048, 44100);
o2 = o1.createBufferSource();
o1.destination.channelCountMode = 'max';
o2.connect(o1.destination);
o2.buffer = function(){
var buffer = o1.createBuffer(30, 442, 94933);
for(var c=0; c<30; c++) {
for(var i=0; i<442; i++) {
buffer.getChannelData(c)[i] = 1;
}
}
return buffer;
}();
</script>

Просмотреть файл

@ -46,3 +46,4 @@ load 880384.html
load 880404.html
load 880724.html
load 881775.html
load 882956.html

Просмотреть файл

@ -15,7 +15,7 @@ DISABLED_EXTRA_COMPONENTS = \
Webapps.manifest \
$(NULL)
EXTRA_PP_COMPONENTS = \
DISABLED_EXTRA_PP_COMPONENTS = \
Webapps.js \
$(NULL)

Просмотреть файл

@ -10,6 +10,10 @@ EXTRA_COMPONENTS += [
'Webapps.manifest',
]
EXTRA_PP_COMPONENTS += [
'Webapps.js',
]
EXTRA_JS_MODULES += [
'AppDownloadManager.jsm',
'AppsServiceChild.jsm',

Просмотреть файл

@ -4259,7 +4259,7 @@ LocationSetterGuts(JSContext *cx, JSObject *obj, jsval *vp)
{
// This function duplicates some of the logic in XPC_WN_HelperSetProperty
obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
if (!IS_WN_WRAPPER(obj))
if (!IS_WN_REFLECTOR(obj))
return NS_ERROR_XPC_BAD_CONVERT_JS;
XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
@ -5099,8 +5099,7 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *aGlobalObj,
nsresult rv = WrapNativeParent(cx, globalObj, native_parent, parentObj);
NS_ENSURE_SUCCESS(rv, rv);
return node->ChromeOnlyAccess() ?
NS_SUCCESS_CHROME_ACCESS_ONLY : NS_SUCCESS_ALLOW_SLIM_WRAPPERS;
return node->ChromeOnlyAccess() ? NS_SUCCESS_CHROME_ACCESS_ONLY : NS_OK;
}
NS_IMETHODIMP
@ -5261,8 +5260,7 @@ nsElementSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
if (element->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) &&
doc->BindingManager()->GetBinding(element)) {
// Don't allow slim wrappers.
return rv == NS_SUCCESS_ALLOW_SLIM_WRAPPERS ? NS_OK : rv;
return rv;
}
mozilla::css::URLValue *bindingURL;
@ -5276,7 +5274,7 @@ nsElementSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
element->SetFlags(NODE_ATTACH_BINDING_ON_POSTCREATE);
return rv == NS_SUCCESS_ALLOW_SLIM_WRAPPERS ? NS_OK : rv;
return rv;
}
NS_IMETHODIMP

Просмотреть файл

@ -535,29 +535,24 @@ MaybeWrapValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
return true;
}
if (rval.isObject()) {
JSObject* obj = &rval.toObject();
if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
return JS_WrapValue(cx, rval.address());
}
// We're same-compartment, but even then we might need to wrap
// objects specially. Check for that.
if (GetSameCompartmentWrapperForDOMBinding(obj)) {
// We're a new-binding object, and "obj" now points to the right thing
rval.set(JS::ObjectValue(*obj));
return true;
}
if (!IS_SLIM_WRAPPER(obj)) {
// We might need a SOW
return JS_WrapValue(cx, rval.address());
}
// Fall through to returning true
if (!rval.isObject()) {
return true;
}
return true;
JSObject* obj = &rval.toObject();
if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
return JS_WrapValue(cx, rval.address());
}
// We're same-compartment, but even then we might need to wrap
// objects specially. Check for that.
if (GetSameCompartmentWrapperForDOMBinding(obj)) {
// We're a new-binding object, and "obj" now points to the right thing
rval.set(JS::ObjectValue(*obj));
return true;
}
return JS_WrapValue(cx, rval.address());
}
static inline void
@ -642,7 +637,7 @@ WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T* value,
}
rval.set(JS::ObjectValue(*obj));
return (sameCompartment && IS_SLIM_WRAPPER(obj)) || JS_WrapValue(cx, rval.address());
return JS_WrapValue(cx, rval.address());
}
// Create a JSObject wrapping "value", for cases when "value" is a

Просмотреть файл

@ -25,7 +25,6 @@ XPIDL_SOURCES += [
'nsIDOMText.idl',
'nsIDOMUserDataHandler.idl',
'nsIDOMXMLDocument.idl',
'nsIDocumentRegister.idl',
'nsIInlineEventHandlers.idl',
]

Просмотреть файл

@ -1,16 +0,0 @@
/* -*- 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/. */
#include "nsISupports.idl"
[scriptable, uuid(e35935bd-ebae-4e0d-93bf-efa93ab14c05)]
interface nsIDocumentRegister : nsISupports
{
[optional_argc,
implicit_jscontext] jsval register(in DOMString name,
[optional] in jsval options)
raises(DOMException);
};

Просмотреть файл

@ -348,11 +348,10 @@ TabChild::Observe(nsISupports *aSubject,
// the top-left of the page.
mLastMetrics.mZoom = gfxSize(1.0, 1.0);
mLastMetrics.mViewport = CSSRect(CSSPoint(), kDefaultViewportSize);
// I don't know what units mInnerSize is in, hence FromUnknownRect
mLastMetrics.mCompositionBounds = LayerIntRect::FromUnknownRect(
gfx::IntRect(0, 0, mInnerSize.width, mInnerSize.height));
mLastMetrics.mResolution =
mLastMetrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
CSSToScreenScale resolution =
AsyncPanZoomController::CalculateResolution(mLastMetrics);
mLastMetrics.mResolution = gfxSize(resolution.scale, resolution.scale);
mLastMetrics.mScrollOffset = CSSPoint(0, 0);
utils->SetResolution(mLastMetrics.mResolution.width,
mLastMetrics.mResolution.height);
@ -590,9 +589,7 @@ TabChild::HandlePossibleViewportChange()
FrameMetrics metrics(mLastMetrics);
metrics.mViewport = CSSRect(CSSPoint(), viewport);
metrics.mScrollableRect = CSSRect(CSSPoint(), pageSize);
// I don't know what units mInnerSize is in, hence FromUnknownRect
metrics.mCompositionBounds = LayerIntRect::FromUnknownRect(
gfx::IntRect(0, 0, mInnerSize.width, mInnerSize.height));
metrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
// Changing the zoom when we're not doing a first paint will get ignored
// by AsyncPanZoomController and causes a blurry flash.
@ -623,14 +620,13 @@ TabChild::HandlePossibleViewportChange()
// new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take.
metrics, gfx::Point(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
gfxSize resolution = AsyncPanZoomController::CalculateResolution(metrics);
CSSToScreenScale resolution = AsyncPanZoomController::CalculateResolution(metrics);
// XXX is this actually hysteresis? This calculation is not well
// understood. It's taken from the previous JS implementation.
gfxFloat hysteresis/*?*/ =
gfxFloat(oldBrowserWidth) / gfxFloat(oldScreenWidth);
resolution.width *= hysteresis;
resolution.height *= hysteresis;
metrics.mResolution = resolution;
metrics.mResolution = gfxSize(resolution.scale * hysteresis,
resolution.scale * hysteresis);
utils->SetResolution(metrics.mResolution.width, metrics.mResolution.height);
// Force a repaint with these metrics. This, among other things, sets the
@ -1413,7 +1409,8 @@ TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const
mOuterRect.height = rect.height;
mOrientation = orientation;
mInnerSize = size;
mInnerSize = ScreenIntSize::FromUnknownSize(
gfx::IntSize(size.width, size.height));
mWidget->Resize(0, 0, size.width, size.height,
true);
@ -1530,9 +1527,9 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
utils->SetScrollPositionClampingScrollPortSize(
cssCompositedRect.width, cssCompositedRect.height);
ScrollWindowTo(window, aFrameMetrics.mScrollOffset);
gfxSize resolution = AsyncPanZoomController::CalculateResolution(
CSSToScreenScale resolution = AsyncPanZoomController::CalculateResolution(
aFrameMetrics);
utils->SetResolution(resolution.width, resolution.height);
utils->SetResolution(resolution.scale, resolution.scale);
nsCOMPtr<nsIDOMDocument> domDoc;
nsCOMPtr<nsIDOMElement> docElement;

Просмотреть файл

@ -441,7 +441,7 @@ private:
nsRefPtr<TabChildGlobal> mTabChildGlobal;
uint32_t mChromeFlags;
nsIntRect mOuterRect;
nsIntSize mInnerSize;
ScreenIntSize mInnerSize;
// When we're tracking a possible tap gesture, this is the "down"
// point of the touchstart.
nsIntPoint mGestureDownPoint;

Просмотреть файл

@ -464,7 +464,8 @@ TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size)
unused << SendUpdateDimensions(mRect, mDimensions, mOrientation);
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->NotifyDimensionsChanged(mDimensions.width, mDimensions.height);
rfp->NotifyDimensionsChanged(ScreenIntSize::FromUnknownSize(
gfx::IntSize(mDimensions.width, mDimensions.height)));
}
}
}
@ -1464,7 +1465,8 @@ TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor,
{
RenderFrameParent* rfp = GetRenderFrame();
if (mDimensions != nsIntSize() && rfp) {
rfp->NotifyDimensionsChanged(mDimensions.width, mDimensions.height);
rfp->NotifyDimensionsChanged(ScreenIntSize::FromUnknownSize(
gfx::IntSize(mDimensions.width, mDimensions.height)));
}
return true;

Просмотреть файл

@ -1976,18 +1976,23 @@ NS_IMPL_ISUPPORTS1(UpdateCurrentDictionaryCallback, nsIEditorSpellCheckCallback)
NS_IMETHODIMP mozInlineSpellChecker::UpdateCurrentDictionary()
{
if (!mSpellCheck) {
// mSpellCheck is null and mPendingSpellCheck is nonnull while the spell
// checker is being initialized. Calling UpdateCurrentDictionary on
// mPendingSpellCheck simply queues the dictionary update after the init.
nsCOMPtr<nsIEditorSpellCheck> spellCheck = mSpellCheck ? mSpellCheck :
mPendingSpellCheck;
if (!spellCheck) {
return NS_OK;
}
if (NS_FAILED(mSpellCheck->GetCurrentDictionary(mPreviousDictionary))) {
if (NS_FAILED(spellCheck->GetCurrentDictionary(mPreviousDictionary))) {
mPreviousDictionary.Truncate();
}
nsRefPtr<UpdateCurrentDictionaryCallback> cb =
new UpdateCurrentDictionaryCallback(this, mDisabledAsyncToken);
NS_ENSURE_STATE(cb);
nsresult rv = mSpellCheck->UpdateCurrentDictionary(cb);
nsresult rv = spellCheck->UpdateCurrentDictionary(cb);
if (NS_FAILED(rv)) {
cb = nullptr;
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -61,6 +61,12 @@ struct PointTyped :
};
typedef PointTyped<UnknownUnits> Point;
template<class units>
IntPointTyped<units> RoundedToInt(const PointTyped<units>& aPoint) {
return IntPointTyped<units>(NS_lround(aPoint.x),
NS_lround(aPoint.y));
}
template<class units>
struct IntSizeTyped :
public BaseSize< int32_t, IntSizeTyped<units> >,

Просмотреть файл

@ -100,6 +100,26 @@ struct RectTyped :
};
typedef RectTyped<UnknownUnits> Rect;
template<class units>
IntRectTyped<units> RoundedToInt(const RectTyped<units>& aRect)
{
return IntRectTyped<units>(NS_lround(aRect.x),
NS_lround(aRect.y),
NS_lround(aRect.width),
NS_lround(aRect.height));
}
template<class units>
IntRectTyped<units> RoundedIn(const RectTyped<units>& aRect)
{
RectTyped<units> copy(aRect);
copy.RoundIn();
return IntRectTyped<units>(int32_t(copy.x),
int32_t(copy.y),
int32_t(copy.width),
int32_t(copy.height));
}
}
}

67
gfx/2d/ScaleFactor.h Normal file
Просмотреть файл

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_SCALEFACTOR_H_
#define MOZILLA_GFX_SCALEFACTOR_H_
#include "gfxPoint.h"
namespace mozilla {
namespace gfx {
/*
* This class represents a scaling factor between two different pixel unit
* systems. This is effectively a type-safe float, intended to be used in
* combination with the known-type instances of gfx::Point, gfx::Rect, etc.
*
* Note that some parts of the code that pre-date this class used separate
* scaling factors for the x and y axes. However, at runtime these values
* were always expected to be the same, so this class uses only one scale
* factor for both axes. The two constructors that take two-axis scaling
* factors check to ensure that this assertion holds.
*/
template<class src, class dst>
struct ScaleFactor {
float scale;
ScaleFactor() : scale(1.0) {}
ScaleFactor(const ScaleFactor<src, dst>& aCopy) : scale(aCopy.scale) {}
explicit ScaleFactor(float aScale) : scale(aScale) {}
explicit ScaleFactor(float aX, float aY) : scale(aX) {
MOZ_ASSERT(fabs(aX - aY) < 1e-6);
}
explicit ScaleFactor(gfxSize aScale) : scale(aScale.width) {
MOZ_ASSERT(fabs(aScale.width - aScale.height) < 1e-6);
}
ScaleFactor<dst, src> Inverse() {
return ScaleFactor<dst, src>(1 / scale);
}
bool operator==(const ScaleFactor<src, dst>& aOther) const {
return scale == aOther.scale;
}
bool operator!=(const ScaleFactor<src, dst>& aOther) const {
return !(*this == aOther);
}
template<class other>
ScaleFactor<other, dst> operator/(const ScaleFactor<src, other>& aOther) const {
return ScaleFactor<other, dst>(scale / aOther.scale);
}
template<class other>
ScaleFactor<src, other> operator*(const ScaleFactor<dst, other>& aOther) const {
return ScaleFactor<src, other>(scale * aOther.scale);
}
};
}
}
#endif /* MOZILLA_GFX_SCALEFACTOR_H_ */

Просмотреть файл

@ -20,6 +20,7 @@ EXPORTS.mozilla.gfx += [
'Point.h',
'Rect.h',
'Scale.h',
'ScaleFactor.h',
'Tools.h',
'Types.h',
'UserData.h',

Просмотреть файл

@ -1,6 +1,6 @@
This directory contains the Graphite2 library from http://hg.palaso.org/graphitedev
Current version derived from upstream changeset 09707dd22634
Current version derived from upstream changeset 6b8ddb7d599f
See gfx/graphite2/moz-gr-update.sh for update procedure.

Просмотреть файл

@ -30,7 +30,7 @@
#define GR2_VERSION_MAJOR 1
#define GR2_VERSION_MINOR 2
#define GR2_VERSION_BUGFIX 2
#define GR2_VERSION_BUGFIX 3
#ifdef __cplusplus
extern "C"

Просмотреть файл

@ -199,7 +199,8 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt)
return false;
ac_begin = ac_data + be::peek<uint16>(--o_action);
rc_begin = *--o_constraint ? rc_data + be::peek<uint16>(o_constraint) : rc_end;
--o_constraint;
rc_begin = be::peek<uint16>(o_constraint) ? rc_data + be::peek<uint16>(o_constraint) : rc_end;
if (ac_begin > ac_end || ac_begin > ac_data_end || ac_end > ac_data_end
|| rc_begin > rc_end || rc_begin > rc_data_end || rc_end > rc_data_end)

Просмотреть файл

@ -147,7 +147,7 @@ Position Slot::finalise(const Segment *seg, const Font *font, Position & base, R
int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel)
{
Position base;
Rect bbox = seg->theGlyphBBoxTemporary(gid());
Rect bbox = seg->theGlyphBBoxTemporary(glyph());
float clusterMin = 0.;
Position res = finalise(seg, NULL, base, bbox, attrLevel, clusterMin);
@ -389,12 +389,13 @@ void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
}
}
m_realglyphid = theGlyph->attrs()[seg->silf()->aPseudo()];
const GlyphFace *aGlyph = theGlyph;
if (m_realglyphid)
{
const GlyphFace *aGlyph = seg->getFace()->glyphs().glyphSafe(m_realglyphid);
if (aGlyph) theGlyph = aGlyph;
aGlyph = seg->getFace()->glyphs().glyphSafe(m_realglyphid);
if (!aGlyph) aGlyph = theGlyph;
}
m_advance = Position(theGlyph->theAdvance().x, 0.);
m_advance = Position(aGlyph->theAdvance().x, 0.);
if (seg->silf()->aPassBits())
seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()]);
}

Просмотреть файл

@ -954,11 +954,11 @@ gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId,
return (uint16)(idDelta + nUnicodeId); // must use modulus 2^16
// Look up value in glyphIdArray
size_t offset = (nUnicodeId - chStart) + (idRangeOffset >> 1) +
(reinterpret_cast<const uint16 *>(pMid) - reinterpret_cast<const uint16 *>(pTable));
if (offset * 2 >= pTable->length)
const ptrdiff_t offset = (nUnicodeId - chStart) + (idRangeOffset >> 1) +
(pMid - reinterpret_cast<const uint16 *>(pTable));
if (offset * 2 >= be::swap<uint16>(pTable->length))
return 0;
gid16 nGlyphId = be::peek<uint16>(pMid + (nUnicodeId - chStart) + (idRangeOffset >> 1));
gid16 nGlyphId = be::peek<uint16>(reinterpret_cast<const uint16 *>(pTable)+offset);
// If this value is 0, return 0. Else add the idDelta
return nGlyphId ? nGlyphId + idDelta : 0;
}

Просмотреть файл

@ -106,9 +106,9 @@ sparse::sparse(I attr, const I last)
}
if (m_nchunks == 0) return;
m_array.values = grzeroalloc<mapped_type>((m_nchunks*sizeof(chunk) + sizeof(mapped_type)/2)
m_array.values = grzeroalloc<mapped_type>((m_nchunks*sizeof(chunk) + sizeof(mapped_type)-1)
/ sizeof(mapped_type)
+ n_values*sizeof(mapped_type));
+ n_values);
if (m_array.values == 0)
{

Просмотреть файл

@ -89,9 +89,9 @@ public:
return mResolution * mDevPixelsPerCSSPixel;
}
gfxPoint GetScrollOffsetInLayerPixels() const
gfx::Point GetScrollOffsetInLayerPixels() const
{
return gfxPoint(
return gfx::Point(
static_cast<gfx::Float>(
mScrollOffset.x * LayersPixelsPerCSSPixel().width),
static_cast<gfx::Float>(
@ -118,7 +118,7 @@ public:
//
// This is only valid on the root layer. Nested iframes do not need this
// metric as they do not have a displayport set. See bug 775452.
LayerIntRect mCompositionBounds;
ScreenIntRect mCompositionBounds;
// ---------------------------------------------------------------------------
// The following metrics are all in CSS pixels. They are not in any uniform

Просмотреть файл

@ -395,16 +395,15 @@ ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
float devPixelRatioX = 1 / rootTransform.GetXScale();
float devPixelRatioY = 1 / rootTransform.GetYScale();
CSSToLayerScale paintScale = LayerToCSSScale(rootTransform.GetXScale(),
rootTransform.GetYScale()).Inverse();
const CSSRect& metricsDisplayPort =
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
LayerRect displayPort = LayerRect::FromCSSRect(metricsDisplayPort + metrics.mScrollOffset,
devPixelRatioX, devPixelRatioY);
LayerRect displayPort = (metricsDisplayPort + metrics.mScrollOffset) * paintScale;
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
aHasPendingNewThebesContent, displayPort, devPixelRatioX, aDrawingCritical,
aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
aViewport, aScaleX, aScaleY);
}
#endif

Просмотреть файл

@ -342,7 +342,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
LayerComposite* layerComposite = aLayer->AsLayerComposite();
ViewTransform treeTransform;
gfx::Point scrollOffset;
ScreenPoint scrollOffset;
*aWantNextFrame |=
controller->SampleContentTransformForFrame(aCurrentFrame,
container,
@ -355,7 +355,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
metrics.mDisplayPort : metrics.mCriticalDisplayPort);
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
ScreenPoint offset(0, 0);
SyncFrameMetrics(scrollOffset, treeTransform.mScale.width, metrics.mScrollableRect,
SyncFrameMetrics(scrollOffset, treeTransform.mScale.scale, metrics.mScrollableRect,
mLayersUpdated, displayPort, 1 / rootTransform.GetXScale(),
mIsFirstPaint, fixedLayerMargins, offset);
@ -381,8 +381,8 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
TransformFixedLayers(
aLayer,
-treeTransform.mTranslation / treeTransform.mScale,
treeTransform.mScale,
gfxPoint(-treeTransform.mTranslation.x, -treeTransform.mTranslation.y),
gfxSize(treeTransform.mScale.scale, treeTransform.mScale.scale),
fixedLayerMargins);
appliedTransform = true;
@ -404,16 +404,15 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
gfx3DMatrix treeTransform;
float layerPixelRatioX = 1 / aRootTransform.GetXScale(),
layerPixelRatioY = 1 / aRootTransform.GetYScale();
CSSToLayerScale geckoZoom = LayerToCSSScale(aRootTransform.GetXScale(),
aRootTransform.GetYScale()).Inverse();
LayerIntPoint scrollOffsetLayerPixels = LayerIntPoint::FromCSSPointRounded(
metrics.mScrollOffset, layerPixelRatioX, layerPixelRatioY);
LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.mScrollOffset * geckoZoom);
if (mIsFirstPaint) {
mContentRect = metrics.mScrollableRect;
SetFirstPaintViewport(scrollOffsetLayerPixels,
layerPixelRatioX,
geckoZoom.scale,
mContentRect);
mIsFirstPaint = false;
} else if (!metrics.mScrollableRect.IsEqualEdges(mContentRect)) {
@ -424,20 +423,19 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
// We synchronise the viewport information with Java after sending the above
// notifications, so that Java can take these into account in its response.
// Calculate the absolute display port to send to Java
LayerIntRect displayPort =
LayerIntRect::FromCSSRectRounded(metrics.mCriticalDisplayPort.IsEmpty()
? metrics.mDisplayPort
: metrics.mCriticalDisplayPort,
layerPixelRatioX, layerPixelRatioY);
LayerIntRect displayPort = RoundedToInt(
(metrics.mCriticalDisplayPort.IsEmpty()
? metrics.mDisplayPort
: metrics.mCriticalDisplayPort
) * geckoZoom);
displayPort += scrollOffsetLayerPixels;
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
ScreenPoint offset(0, 0);
ScreenPoint scrollOffset(0, 0);
float scaleX = 1.0,
scaleY = 1.0;
SyncViewportInfo(displayPort, layerPixelRatioX, mLayersUpdated,
scrollOffset, scaleX, scaleY, fixedLayerMargins,
ScreenPoint userScroll(0, 0);
CSSToScreenScale userZoom;
SyncViewportInfo(displayPort, geckoZoom.scale, mLayersUpdated,
userScroll, userZoom.scale, userZoom.scale, fixedLayerMargins,
offset);
mLayersUpdated = false;
@ -447,50 +445,44 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
// Handle transformations for asynchronous panning and zooming. We determine the
// zoom used by Gecko from the transformation set on the root layer, and we
// determine the scroll offset used by Gecko from the frame metrics of the
// primary scrollable layer. We compare this to the desired zoom and scroll
// primary scrollable layer. We compare this to the user zoom and scroll
// offset in the view transform we obtained from Java in order to compute the
// transformation we need to apply.
float tempScaleDiffX = aRootTransform.GetXScale() * scaleX;
float tempScaleDiffY = aRootTransform.GetYScale() * scaleY;
LayerToScreenScale zoomAdjust = userZoom / geckoZoom;
LayerIntPoint metricsScrollOffset(0, 0);
LayerIntPoint geckoScroll(0, 0);
if (metrics.IsScrollable()) {
metricsScrollOffset = scrollOffsetLayerPixels;
geckoScroll = scrollOffsetLayerPixels;
}
nsIntPoint scrollCompensation(
(scrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * scaleX,
(scrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * scaleY);
treeTransform = gfx3DMatrix(ViewTransform(-scrollCompensation,
gfxSize(scaleX, scaleY)));
LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll;
treeTransform = gfx3DMatrix(ViewTransform(-translation, userZoom));
// Translate fixed position layers so that they stay in the correct position
// when scrollOffset and metricsScrollOffset differ.
// when userScroll and geckoScroll differ.
gfxPoint fixedOffset;
gfxSize scaleDiff;
LayerRect content = LayerRect::FromCSSRect(mContentRect,
1 / aRootTransform.GetXScale(),
1 / aRootTransform.GetYScale());
LayerRect content = mContentRect * geckoZoom;
// If the contents can fit entirely within the widget area on a particular
// dimension, we need to translate and scale so that the fixed layers remain
// within the page boundaries.
if (mContentRect.width * scaleX < metrics.mCompositionBounds.width) {
fixedOffset.x = -metricsScrollOffset.x;
if (mContentRect.width * userZoom.scale < metrics.mCompositionBounds.width) {
fixedOffset.x = -geckoScroll.x;
scaleDiff.width = std::min(1.0f, metrics.mCompositionBounds.width / content.width);
} else {
fixedOffset.x = clamped(scrollOffset.x / tempScaleDiffX, content.x,
content.XMost() - metrics.mCompositionBounds.width / tempScaleDiffX) - metricsScrollOffset.x;
scaleDiff.width = tempScaleDiffX;
fixedOffset.x = clamped(userScroll.x / zoomAdjust.scale, content.x,
content.XMost() - metrics.mCompositionBounds.width / zoomAdjust.scale) - geckoScroll.x;
scaleDiff.width = zoomAdjust.scale;
}
if (mContentRect.height * scaleY < metrics.mCompositionBounds.height) {
fixedOffset.y = -metricsScrollOffset.y;
if (mContentRect.height * userZoom.scale < metrics.mCompositionBounds.height) {
fixedOffset.y = -geckoScroll.y;
scaleDiff.height = std::min(1.0f, metrics.mCompositionBounds.height / content.height);
} else {
fixedOffset.y = clamped(scrollOffset.y / tempScaleDiffY, content.y,
content.YMost() - metrics.mCompositionBounds.height / tempScaleDiffY) - metricsScrollOffset.y;
scaleDiff.height = tempScaleDiffY;
fixedOffset.y = clamped(userScroll.y / zoomAdjust.scale, content.y,
content.YMost() - metrics.mCompositionBounds.height / zoomAdjust.scale) - geckoScroll.y;
scaleDiff.height = zoomAdjust.scale;
}
// The transform already takes the resolution scale into account. Since we
@ -588,7 +580,7 @@ AsyncCompositionManager::SyncViewportInfo(const LayerIntRect& aDisplayPort,
}
void
AsyncCompositionManager::SyncFrameMetrics(const gfx::Point& aScrollOffset,
AsyncCompositionManager::SyncFrameMetrics(const ScreenPoint& aScrollOffset,
float aZoom,
const CSSRect& aCssPageRect,
bool aLayersUpdated,

Просмотреть файл

@ -27,8 +27,8 @@ class AutoResolveRefLayers;
// Represents (affine) transforms that are calculated from a content view.
struct ViewTransform {
ViewTransform(gfxPoint aTranslation = gfxPoint(),
gfxSize aScale = gfxSize(1, 1))
ViewTransform(LayerPoint aTranslation = LayerPoint(),
CSSToScreenScale aScale = CSSToScreenScale())
: mTranslation(aTranslation)
, mScale(aScale)
{}
@ -36,12 +36,12 @@ struct ViewTransform {
operator gfx3DMatrix() const
{
return
gfx3DMatrix::ScalingMatrix(mScale.width, mScale.height, 1) *
gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0);
gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0) *
gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1);
}
gfxPoint mTranslation;
gfxSize mScale;
LayerPoint mTranslation;
CSSToScreenScale mScale;
};
/**
@ -125,7 +125,7 @@ private:
float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins,
ScreenPoint& aOffset);
void SyncFrameMetrics(const gfx::Point& aScrollOffset,
void SyncFrameMetrics(const ScreenPoint& aScrollOffset,
float aZoom,
const CSSRect& aCssPageRect,
bool aLayersUpdated,

Просмотреть файл

@ -246,17 +246,15 @@ ThebesLayerComposite::GetCompositionBounds()
// the content resolution.
Layer* rootLayer = Manager()->GetRoot();
const gfx3DMatrix& rootTransform = rootLayer->GetTransform();
float scaleX = rootTransform.GetXScale();
float scaleY = rootTransform.GetYScale();
LayerToCSSScale scale(rootTransform.GetXScale(),
rootTransform.GetYScale());
// Get the content document bounds, in screen-space.
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
const LayerIntRect content = LayerIntRect::FromCSSRectRounded(metrics.mScrollableRect,
1 / scaleX,
1 / scaleY);
const LayerIntRect content = RoundedToInt(metrics.mScrollableRect / scale);
gfx::Point scrollOffset =
gfx::Point((metrics.mScrollOffset.x * metrics.LayersPixelsPerCSSPixel().width) / scaleX,
(metrics.mScrollOffset.y * metrics.LayersPixelsPerCSSPixel().height) / scaleY);
gfx::Point((metrics.mScrollOffset.x * metrics.LayersPixelsPerCSSPixel().width) / scale.scale,
(metrics.mScrollOffset.y * metrics.LayersPixelsPerCSSPixel().height) / scale.scale);
const nsIntPoint contentOrigin(
content.x - NS_lround(scrollOffset.x),
content.y - NS_lround(scrollOffset.y));

Просмотреть файл

@ -208,37 +208,29 @@ AsyncPanZoomController::GetTouchStartTolerance()
return gTouchStartTolerance;
}
static gfx::Point
WidgetSpaceToCompensatedViewportSpace(const gfx::Point& aPoint,
gfxFloat aCurrentZoom)
static CSSPoint
WidgetSpaceToCompensatedViewportSpace(const ScreenPoint& aPoint,
const CSSToScreenScale& aCurrentZoom)
{
// Transform the input point from local widget space to the content document
// space that the user is seeing, from last composite.
gfx::Point pt(aPoint);
pt = pt / aCurrentZoom;
// FIXME/bug 775451: this doesn't attempt to compensate for content transforms
// in effect on the compositor. The problem is that it's very hard for us to
// know what content CSS pixel is at widget point 0,0 based on information
// available here. So we use this hacky implementation for now, which works
// in quiescent states.
return pt;
return aPoint / aCurrentZoom;
}
nsEventStatus
AsyncPanZoomController::ReceiveInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent)
{
gfxFloat currentResolution;
gfx::Point currentScrollOffset, lastScrollOffset;
CSSToScreenScale currentResolution;
{
MonitorAutoLock monitor(mMonitor);
currentResolution = CalculateResolution(mFrameMetrics).width;
currentScrollOffset = gfx::Point(mFrameMetrics.mScrollOffset.x,
mFrameMetrics.mScrollOffset.y);
lastScrollOffset = gfx::Point(mLastContentPaintMetrics.mScrollOffset.x,
mLastContentPaintMetrics.mScrollOffset.y);
currentResolution = CalculateResolution(mFrameMetrics);
}
nsEventStatus status;
@ -265,8 +257,9 @@ AsyncPanZoomController::ReceiveInputEvent(const nsInputEvent& aEvent,
for (uint32_t i = 0; i < touches.Length(); ++i) {
nsIDOMTouch* touch = touches[i];
if (touch) {
gfx::Point refPoint = WidgetSpaceToCompensatedViewportSpace(
gfx::Point(touch->mRefPoint.x, touch->mRefPoint.y),
CSSPoint refPoint = WidgetSpaceToCompensatedViewportSpace(
ScreenPoint::FromUnknownPoint(gfx::Point(
touch->mRefPoint.x, touch->mRefPoint.y)),
currentResolution);
touch->mRefPoint = nsIntPoint(refPoint.x, refPoint.y);
}
@ -274,8 +267,9 @@ AsyncPanZoomController::ReceiveInputEvent(const nsInputEvent& aEvent,
break;
}
default: {
gfx::Point refPoint = WidgetSpaceToCompensatedViewportSpace(
gfx::Point(aOutEvent->refPoint.x, aOutEvent->refPoint.y),
CSSPoint refPoint = WidgetSpaceToCompensatedViewportSpace(
ScreenPoint::FromUnknownPoint(gfx::Point(
aOutEvent->refPoint.x, aOutEvent->refPoint.y)),
currentResolution);
aOutEvent->refPoint = nsIntPoint(refPoint.x, refPoint.y);
break;
@ -550,13 +544,11 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
{
MonitorAutoLock monitor(mMonitor);
gfxFloat resolution = CalculateResolution(mFrameMetrics).width;
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
gfxFloat userZoom = mFrameMetrics.mZoom.width;
ScreenPoint focusPoint = aEvent.mFocusPoint;
CSSPoint focusChange = ScreenPoint::ToCSSPoint(mLastZoomFocus - focusPoint,
1.0 / resolution,
1.0 / resolution);
CSSPoint focusChange = (mLastZoomFocus - focusPoint) / resolution;
// If displacing by the change in focus point will take us off page bounds,
// then reduce the displacement such that it doesn't.
if (mX.DisplacementWillOverscroll(focusChange.x) != Axis::OVERSCROLL_NONE) {
@ -653,12 +645,12 @@ nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent)
if (mGeckoContentController) {
MonitorAutoLock monitor(mMonitor);
gfxFloat resolution = CalculateResolution(mFrameMetrics).width;
CSSPoint point = CSSPoint::FromUnknownPoint(
WidgetSpaceToCompensatedViewportSpace(
gfx::Point(aEvent.mPoint.x, aEvent.mPoint.y),
resolution));
mGeckoContentController->HandleLongTap(CSSIntPoint::RoundToInt(point));
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
CSSPoint point = WidgetSpaceToCompensatedViewportSpace(
ScreenPoint::FromUnknownPoint(gfx::Point(
aEvent.mPoint.x, aEvent.mPoint.y)),
resolution);
mGeckoContentController->HandleLongTap(gfx::RoundedToInt(point));
return nsEventStatus_eConsumeNoDefault;
}
return nsEventStatus_eIgnore;
@ -672,12 +664,12 @@ nsEventStatus AsyncPanZoomController::OnSingleTapConfirmed(const TapGestureInput
if (mGeckoContentController) {
MonitorAutoLock monitor(mMonitor);
gfxFloat resolution = CalculateResolution(mFrameMetrics).width;
CSSPoint point = CSSPoint::FromUnknownPoint(
WidgetSpaceToCompensatedViewportSpace(
gfx::Point(aEvent.mPoint.x, aEvent.mPoint.y),
resolution));
mGeckoContentController->HandleSingleTap(CSSIntPoint::RoundToInt(point));
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
CSSPoint point = WidgetSpaceToCompensatedViewportSpace(
ScreenPoint::FromUnknownPoint(gfx::Point(
aEvent.mPoint.x, aEvent.mPoint.y)),
resolution);
mGeckoContentController->HandleSingleTap(gfx::RoundedToInt(point));
return nsEventStatus_eConsumeNoDefault;
}
return nsEventStatus_eIgnore;
@ -688,12 +680,12 @@ nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent)
MonitorAutoLock monitor(mMonitor);
if (mAllowZoom) {
gfxFloat resolution = CalculateResolution(mFrameMetrics).width;
CSSPoint point = CSSPoint::FromUnknownPoint(
WidgetSpaceToCompensatedViewportSpace(
gfx::Point(aEvent.mPoint.x, aEvent.mPoint.y),
resolution));
mGeckoContentController->HandleDoubleTap(CSSIntPoint::RoundToInt(point));
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
CSSPoint point = WidgetSpaceToCompensatedViewportSpace(
ScreenPoint::FromUnknownPoint(gfx::Point(
aEvent.mPoint.x, aEvent.mPoint.y)),
resolution);
mGeckoContentController->HandleDoubleTap(gfx::RoundedToInt(point));
}
return nsEventStatus_eConsumeNoDefault;
@ -758,11 +750,11 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
// We want to inversely scale it because when you're zoomed further in, a
// larger swipe should move you a shorter distance.
gfxFloat inverseResolution = 1 / CalculateResolution(mFrameMetrics).width;
ScreenToCSSScale inverseResolution = CalculateResolution(mFrameMetrics).Inverse();
gfx::Point displacement(mX.GetDisplacementForDuration(inverseResolution,
gfx::Point displacement(mX.GetDisplacementForDuration(inverseResolution.scale,
timeDelta),
mY.GetDisplacementForDuration(inverseResolution,
mY.GetDisplacementForDuration(inverseResolution.scale,
timeDelta));
if (fabs(displacement.x) <= EPSILON && fabs(displacement.y) <= EPSILON) {
return;
@ -802,11 +794,11 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
// We want to inversely scale it because when you're zoomed further in, a
// larger swipe should move you a shorter distance.
gfxFloat inverseResolution = 1 / CalculateResolution(mFrameMetrics).width;
ScreenToCSSScale inverseResolution = CalculateResolution(mFrameMetrics).Inverse();
ScrollBy(CSSPoint::FromUnknownPoint(gfx::Point(
mX.GetDisplacementForDuration(inverseResolution, aDelta),
mY.GetDisplacementForDuration(inverseResolution, aDelta)
mX.GetDisplacementForDuration(inverseResolution.scale, aDelta),
mY.GetDisplacementForDuration(inverseResolution.scale, aDelta)
)));
TimeDuration timePaintDelta = TimeStamp::Now() - mPreviousPaintStartTime;
if (timePaintDelta.ToMilliseconds() > gFlingRepaintInterval) {
@ -834,17 +826,17 @@ void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) {
void AsyncPanZoomController::ScaleWithFocus(float aZoom,
const ScreenPoint& aFocus) {
float zoomFactor = aZoom / mFrameMetrics.mZoom.width;
gfxFloat resolution = CalculateResolution(mFrameMetrics).width;
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
SetZoomAndResolution(aZoom);
// If the new scale is very small, we risk multiplying in huge rounding
// errors, so don't bother adjusting the scroll offset.
if (resolution >= 0.01f) {
if (resolution.scale >= 0.01f) {
mFrameMetrics.mScrollOffset.x +=
aFocus.x * (zoomFactor - 1.0) / resolution;
aFocus.x * (zoomFactor - 1.0) / resolution.scale;
mFrameMetrics.mScrollOffset.y +=
aFocus.y * (zoomFactor - 1.0) / resolution;
aFocus.y * (zoomFactor - 1.0) / resolution.scale;
}
}
@ -896,9 +888,8 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
double estimatedPaintDuration =
aEstimatedPaintDuration > EPSILON ? aEstimatedPaintDuration : 1.0;
gfxSize resolution = CalculateResolution(aFrameMetrics);
CSSIntRect compositionBounds = LayerIntRect::ToCSSIntRectRoundIn(
aFrameMetrics.mCompositionBounds, resolution.width, resolution.height);
CSSToScreenScale resolution = CalculateResolution(aFrameMetrics);
CSSIntRect compositionBounds = gfx::RoundedIn(aFrameMetrics.mCompositionBounds / resolution);
CSSRect scrollableRect = aFrameMetrics.mScrollableRect;
// Ensure the scrollableRect is at least as big as the compositionBounds
@ -975,21 +966,20 @@ AsyncPanZoomController::CalculateIntrinsicScale(const FrameMetrics& aMetrics)
return gfxSize(intrinsicScale, intrinsicScale);
}
/*static*/ gfxSize
/*static*/ CSSToScreenScale
AsyncPanZoomController::CalculateResolution(const FrameMetrics& aMetrics)
{
gfxSize intrinsicScale = CalculateIntrinsicScale(aMetrics);
gfxSize userZoom = aMetrics.mZoom;
return gfxSize(intrinsicScale.width * userZoom.width,
intrinsicScale.height * userZoom.height);
return CSSToScreenScale(intrinsicScale.width * userZoom.width,
intrinsicScale.height * userZoom.height);
}
/*static*/ CSSRect
AsyncPanZoomController::CalculateCompositedRectInCssPixels(const FrameMetrics& aMetrics)
{
gfxSize resolution = CalculateResolution(aMetrics);
CSSIntRect rect = LayerIntRect::ToCSSIntRectRoundIn(
aMetrics.mCompositionBounds, resolution.width, resolution.height);
CSSToScreenScale resolution = CalculateResolution(aMetrics);
CSSIntRect rect = gfx::RoundedIn(aMetrics.mCompositionBounds / resolution);
return CSSRect(rect);
}
@ -1087,7 +1077,7 @@ AsyncPanZoomController::FireAsyncScrollOnTimeout()
bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime,
ContainerLayer* aLayer,
ViewTransform* aNewTransform,
gfx::Point& aScrollOffset) {
ScreenPoint& aScrollOffset) {
// The eventual return value of this function. The compositor needs to know
// whether or not to advance by a frame as soon as it can. For example, if a
// fling is happening, it has to keep compositing so that the animation is
@ -1098,12 +1088,12 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
const gfx3DMatrix& currentTransform = aLayer->GetTransform();
// Scales on the root layer, on what's currently painted.
gfxSize rootScale(currentTransform.GetXScale(),
currentTransform.GetYScale());
LayerToCSSScale rootScale(currentTransform.GetXScale(),
currentTransform.GetYScale());
gfxPoint metricsScrollOffset(0, 0);
gfxPoint scrollOffset;
gfxSize localScale;
LayerPoint metricsScrollOffset;
CSSPoint scrollOffset;
CSSToScreenScale localScale;
const FrameMetrics& frame = aLayer->GetFrameMetrics();
{
MonitorAutoLock mon(mMonitor);
@ -1159,10 +1149,11 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
localScale = CalculateResolution(mFrameMetrics);
if (frame.IsScrollable()) {
metricsScrollOffset = frame.GetScrollOffsetInLayerPixels();
metricsScrollOffset = LayerPoint::FromUnknownPoint(
frame.GetScrollOffsetInLayerPixels());
}
scrollOffset = gfxPoint(mFrameMetrics.mScrollOffset.x, mFrameMetrics.mScrollOffset.y);
scrollOffset = mFrameMetrics.mScrollOffset;
mCurrentAsyncScrollOffset = mFrameMetrics.mScrollOffset;
}
@ -1193,11 +1184,9 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
mAsyncScrollTimeout);
}
gfxPoint scrollCompensation(
(scrollOffset / rootScale - metricsScrollOffset) * localScale);
*aNewTransform = ViewTransform(-scrollCompensation, localScale);
aScrollOffset.x = scrollOffset.x * localScale.width;
aScrollOffset.y = scrollOffset.y * localScale.height;
LayerPoint translation = (scrollOffset / rootScale) - metricsScrollOffset;
*aNewTransform = ViewTransform(-translation, localScale);
aScrollOffset = scrollOffset * localScale;
mLastSampleTime = aSampleTime;
@ -1245,9 +1234,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
aViewportFrame.mCompositionBounds.height == mFrameMetrics.mCompositionBounds.height) {
// Remote content has sync'd up to the composition geometry
// change, so we can accept the viewport it's calculated.
gfxSize previousResolution = CalculateResolution(mFrameMetrics);
CSSToScreenScale previousResolution = CalculateResolution(mFrameMetrics);
mFrameMetrics.mViewport = aViewportFrame.mViewport;
gfxSize newResolution = CalculateResolution(mFrameMetrics);
CSSToScreenScale newResolution = CalculateResolution(mFrameMetrics);
needContentRepaint |= (previousResolution != newResolution);
}
@ -1274,10 +1263,10 @@ const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() {
return mFrameMetrics;
}
void AsyncPanZoomController::UpdateCompositionBounds(const LayerIntRect& aCompositionBounds) {
void AsyncPanZoomController::UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds) {
MonitorAutoLock mon(mMonitor);
LayerIntRect oldCompositionBounds = mFrameMetrics.mCompositionBounds;
ScreenIntRect oldCompositionBounds = mFrameMetrics.mCompositionBounds;
mFrameMetrics.mCompositionBounds = aCompositionBounds;
// If the window had 0 dimensions before, or does now, we don't want to
@ -1312,10 +1301,10 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
{
MonitorAutoLock mon(mMonitor);
LayerIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
ScreenIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
CSSRect cssPageRect = mFrameMetrics.mScrollableRect;
CSSPoint scrollOffset = mFrameMetrics.mScrollOffset;
gfxSize resolution = CalculateResolution(mFrameMetrics);
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
gfxSize currentZoom = mFrameMetrics.mZoom;
float targetZoom;
gfxFloat targetResolution;
@ -1338,7 +1327,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
targetResolution =
std::min(compositionBounds.width / zoomToRect.width,
compositionBounds.height / zoomToRect.height);
targetZoom = float(targetResolution / resolution.width) * currentZoom.width;
targetZoom = float(targetResolution / resolution.scale) * currentZoom.width;
}
// 1. If the rect is empty, request received from browserElementScrolling.js
// 2. currentZoom is equal to mMaxZoom and user still double-tapping it
@ -1347,8 +1336,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
if (zoomToRect.IsEmpty() ||
(currentZoom.width == mMaxZoom && targetZoom >= mMaxZoom) ||
(currentZoom.width == localMinZoom && targetZoom <= localMinZoom)) {
CSSIntRect cssCompositionBounds = LayerIntRect::ToCSSIntRectRoundIn(
compositionBounds, resolution.width, resolution.height);
CSSIntRect cssCompositionBounds = gfx::RoundedIn(compositionBounds / resolution);
float y = scrollOffset.y;
float newHeight =
@ -1363,7 +1351,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
targetResolution =
std::min(compositionBounds.width / zoomToRect.width,
compositionBounds.height / zoomToRect.height);
targetZoom = float(targetResolution / resolution.width) * currentZoom.width;
targetZoom = float(targetResolution / resolution.scale) * currentZoom.width;
}
targetZoom = clamped(targetZoom, localMinZoom, mMaxZoom);
@ -1453,7 +1441,8 @@ void AsyncPanZoomController::TimeoutTouchListeners() {
void AsyncPanZoomController::SetZoomAndResolution(float aZoom) {
mMonitor.AssertCurrentThreadOwns();
mFrameMetrics.mZoom = gfxSize(aZoom, aZoom);
mFrameMetrics.mResolution = CalculateResolution(mFrameMetrics);
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
mFrameMetrics.mResolution = gfxSize(resolution.scale, resolution.scale);
}
void AsyncPanZoomController::UpdateZoomConstraints(bool aAllowZoom,

Просмотреть файл

@ -111,7 +111,7 @@ public:
* { x = 0, y = 0, width = surface.width, height = surface.height }, however
* there is no hard requirement for this.
*/
void UpdateCompositionBounds(const LayerIntRect& aCompositionBounds);
void UpdateCompositionBounds(const ScreenIntRect& aCompositionBounds);
/**
* We are scrolling a subframe, so disable our machinery until we hit
@ -178,7 +178,7 @@ public:
bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
ContainerLayer* aLayer,
ViewTransform* aNewTransform,
gfx::Point& aScrollOffset);
ScreenPoint& aScrollOffset);
/**
* A shadow layer update has arrived. |aViewportFrame| is the new FrameMetrics
@ -235,7 +235,7 @@ public:
* factor, etc. (The mResolution member of aFrameMetrics is
* ignored.)
*/
static gfxSize CalculateResolution(const FrameMetrics& aMetrics);
static CSSToScreenScale CalculateResolution(const FrameMetrics& aMetrics);
static CSSRect CalculateCompositedRectInCssPixels(const FrameMetrics& aMetrics);

Просмотреть файл

@ -318,9 +318,8 @@ bool Axis::ScaleWillOverscrollBothSides(float aScale) {
CSSRect cssContentRect = metrics.mScrollableRect;
float scale = metrics.mZoom.width * aScale;
CSSIntRect cssCompositionBounds = LayerIntRect::ToCSSIntRectRoundIn(
metrics.mCompositionBounds, scale, scale);
CSSToScreenScale scale(metrics.mZoom.width * aScale);
CSSIntRect cssCompositionBounds = RoundedIn(metrics.mCompositionBounds / scale);
return GetRectLength(cssContentRect) < GetRectLength(CSSRect(cssCompositionBounds));
}

Просмотреть файл

@ -68,7 +68,6 @@ TEST(TiledLayerBuffer, TileStart) {
TEST(TiledLayerBuffer, EmptyUpdate) {
TestTiledLayerBuffer buffer;
nsRegion::InitStatic();
nsIntRegion validRegion(nsIntRect(0, 0, 10, 10));
buffer.TestUpdate(validRegion, validRegion);

Просмотреть файл

@ -19,7 +19,7 @@ LOCAL_INCLUDES += $(MOZ_QT_CFLAGS)
FORCE_STATIC_LIB = 1
EXTRA_COMPONENTS = gtkqticonsconverter.manifest
EXTRA_PP_COMPONENTS = gtkqticonsconverter.js
DISABLED_EXTRA_PP_COMPONENTS = gtkqticonsconverter.js
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -12,3 +12,6 @@ CPP_SOURCES += [
'nsIconChannel.cpp',
]
EXTRA_PP_COMPONENTS += [
'gtkqticonsconverter.js',
]

Просмотреть файл

@ -8,7 +8,6 @@
#define Iterator_inl_h_
#include "jsiter.h"
#include "jsobjinlines.h"
inline bool
JSObject::isPropertyIterator() const

Просмотреть файл

@ -13,10 +13,13 @@
#include "gc/Marking.h"
#include "js/Utility.h"
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"
#include "vm/Stack.h"
#include "jsobjinlines.h"
#include "gc/Barrier-inl.h"
using namespace js;
using mozilla::DoubleIsInt32;

Просмотреть файл

@ -4,9 +4,10 @@
* 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 "jsobjinlines.h"
#include "builtin/Module.h"
#include "jsobjinlines.h"
using namespace js;
Class js::ModuleClass = {

Просмотреть файл

@ -15,8 +15,6 @@
#include "vm/String.h"
#include "vm/ThreadPool.h"
#include "jsobjinlines.h"
#include "vm/Interpreter-inl.h"
using namespace js;

Просмотреть файл

@ -377,7 +377,7 @@ function ParallelArrayMap(func, mode) {
// FIXME(bug 844887): Check |IsCallable(func)|
var self = this;
var length = self.shape[0];
var length = UnsafeGetImmutableElement(self.shape, 0);
var buffer = NewDenseArray(length);
parallel: for (;;) { // see ParallelArrayBuild() to explain why for(;;) etc
@ -432,7 +432,7 @@ function ParallelArrayReduce(func, mode) {
// FIXME(bug 844887): Check |IsCallable(func)|
var self = this;
var length = self.shape[0];
var length = UnsafeGetImmutableElement(self.shape, 0);
if (length === 0)
ThrowError(JSMSG_PAR_ARRAY_REDUCE_EMPTY);
@ -519,7 +519,7 @@ function ParallelArrayScan(func, mode) {
// FIXME(bug 844887): Check |IsCallable(func)|
var self = this;
var length = self.shape[0];
var length = UnsafeGetImmutableElement(self.shape, 0);
if (length === 0)
ThrowError(JSMSG_PAR_ARRAY_REDUCE_EMPTY);
@ -726,7 +726,7 @@ function ParallelArrayScatter(targets, defaultValue, conflictFunc, length, mode)
var self = this;
if (length === undefined)
length = self.shape[0];
length = UnsafeGetImmutableElement(self.shape, 0);
// The Divide-Scatter-Vector strategy:
// 1. Slice |targets| array of indices ("scatter-vector") into N
@ -977,7 +977,7 @@ function ParallelArrayFilter(func, mode) {
// FIXME(bug 844887): Check |IsCallable(func)|
var self = this;
var length = self.shape[0];
var length = UnsafeGetImmutableElement(self.shape, 0);
parallel: for (;;) { // see ParallelArrayBuild() to explain why for(;;) etc
if (ShouldForceSequential())
@ -1151,6 +1151,11 @@ function ParallelArrayFlatten() {
function ParallelArrayGet1(i) {
if (i === undefined)
return undefined;
// We could use UnsafeGetImmutableElement here, but I am not doing
// so (for the moment) since using the default path enables
// bounds-check hoisting, which is (currently) not possible
// otherwise.
return this.buffer[this.offset + i];
}
@ -1158,27 +1163,25 @@ function ParallelArrayGet1(i) {
* Specialized variant of get() for two-dimensional case
*/
function ParallelArrayGet2(x, y) {
var xDimension = this.shape[0];
var yDimension = this.shape[1];
if (x === undefined)
return undefined;
if (x >= xDimension)
var xDimension = UnsafeGetImmutableElement(this.shape, 0);
var yDimension = UnsafeGetImmutableElement(this.shape, 1);
if (x === undefined || TO_INT32(x) !== x || x >= xDimension)
return undefined;
if (y === undefined)
return NewParallelArray(ParallelArrayView, [yDimension], this.buffer, this.offset + x * yDimension);
if (y >= yDimension)
if (TO_INT32(y) !== y || y >= yDimension)
return undefined;
var offset = y + x * yDimension;
return this.buffer[this.offset + offset];
return UnsafeGetImmutableElement(this.buffer, this.offset + offset);
}
/**
* Specialized variant of get() for three-dimensional case
*/
function ParallelArrayGet3(x, y, z) {
var xDimension = this.shape[0];
var yDimension = this.shape[1];
var zDimension = this.shape[2];
var xDimension = UnsafeGetImmutableElement(this.shape, 0);
var yDimension = UnsafeGetImmutableElement(this.shape, 1);
var zDimension = UnsafeGetImmutableElement(this.shape, 2);
if (x === undefined)
return undefined;
if (x >= xDimension)
@ -1194,7 +1197,7 @@ function ParallelArrayGet3(x, y, z) {
if (z >= zDimension)
return undefined;
var offset = z + y*zDimension + x * yDimension * zDimension;
return this.buffer[this.offset + offset];
return UnsafeGetImmutableElement(this.buffer, this.offset + offset);
}
/**
@ -1228,7 +1231,7 @@ function ParallelArrayGetN(...coords) {
/** The length property yields the outermost dimension */
function ParallelArrayLength() {
return this.shape[0];
return UnsafeGetImmutableElement(this.shape, 0);
}
function ParallelArrayToString() {

Просмотреть файл

@ -10,6 +10,8 @@
#include "builtin/RegExp.h"
#include "jsobjinlines.h"
#include "vm/RegExpObject-inl.h"
#include "vm/RegExpStatics-inl.h"

Просмотреть файл

@ -11,13 +11,14 @@
#include "jsfriendapi.h"
#include "jsgc.h"
#include "jsobj.h"
#include "jsobjinlines.h"
#include "jsprf.h"
#include "jswrapper.h"
#include "builtin/TestingFunctions.h"
#include "vm/ForkJoin.h"
#include "jsobjinlines.h"
#include "vm/Stack-inl.h"
using namespace js;

Просмотреть файл

@ -50,7 +50,6 @@ ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $
@echo "IMPORT_LIBRARY = $(IMPORT_LIBRARY)"
@echo "STATIC_LIBS = $(STATIC_LIBS)"
@echo "SHARED_LIBS = $(SHARED_LIBS)"
@echo "EXTRA_DSO_LIBS = $(EXTRA_DSO_LIBS)"
@echo "EXTRA_DSO_LDOPTS = $(EXTRA_DSO_LDOPTS)"
@echo "DEPENDENT_LIBS = $(DEPENDENT_LIBS)"
@echo --------------------------------------------------------------------------------

Просмотреть файл

@ -110,10 +110,6 @@ endif # ifndef .PYMAKE
_VPATH_SRCS = $(abspath $<)
ifdef EXTRA_DSO_LIBS
EXTRA_DSO_LIBS := $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS))
endif
################################################################################
# Testing frameworks support
################################################################################

Просмотреть файл

@ -4,16 +4,14 @@
* 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 "ctypes/CTypes.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/StandardInteger.h"
#include "CTypes.h"
#include "Library.h"
#include "jsnum.h"
#include "jscompartment.h"
#include "jsobjinlines.h"
#include <limits>
#include <math.h>
#if defined(XP_WIN) || defined(XP_OS2)
#include <float.h>
#endif
@ -32,7 +30,12 @@
#include <windows.h>
#endif
#include "mozilla/StandardInteger.h"
#include "jscompartment.h"
#include "jsnum.h"
#include "jsprf.h"
#include "jstypedarray.h"
#include "ctypes/Library.h"
using namespace std;

Просмотреть файл

@ -14,6 +14,8 @@
#include "vm/GlobalObject.h"
#include "jsinferinlines.h"
#include "jsobjinlines.h"
#include "frontend/ParseMaps-inl.h"
#include "frontend/ParseNode-inl.h"
#include "frontend/Parser-inl.h"
@ -74,6 +76,15 @@ CheckArgumentsWithinEval(JSContext *cx, Parser<FullParseHandler> &parser, Handle
return true;
}
inline bool
CanLazilyParse(JSContext *cx, const CompileOptions &options)
{
return options.canLazilyParse &&
options.compileAndGo &&
options.sourcePolicy == CompileOptions::SAVE_SOURCE &&
!cx->compartment()->debugMode();
}
JSScript *
frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
HandleScript evalCaller,
@ -102,7 +113,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
return NULL;
if (options.filename && !ss->setFilename(cx, options.filename))
return NULL;
JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
if (!sourceObject)
return NULL;
@ -120,28 +131,21 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
break;
}
bool canLazilyParse = CanLazilyParse(cx, options);
Maybe<Parser<SyntaxParseHandler> > syntaxParser;
if (options.canLazilyParse) {
if (canLazilyParse) {
syntaxParser.construct(cx, options, chars, length, /* foldConstants = */ false,
(Parser<SyntaxParseHandler> *) NULL,
(LazyScript *) NULL);
}
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true,
options.canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
parser.sct = sct;
GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
// Syntax parsing may cause us to restart processing of top level
// statements in the script. Use Maybe<> so that the parse context can be
// reset when this occurs.
Maybe<ParseContext<FullParseHandler> > pc;
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc, staticLevel, /* bodyid = */ 0);
if (!pc.ref().init())
return NULL;
bool savedCallerFun =
options.compileAndGo &&
evalCaller &&
@ -169,6 +173,15 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
if (!bce.init())
return NULL;
// Syntax parsing may cause us to restart processing of top level
// statements in the script. Use Maybe<> so that the parse context can be
// reset when this occurs.
Maybe<ParseContext<FullParseHandler> > pc;
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc, staticLevel, /* bodyid = */ 0);
if (!pc.ref().init())
return NULL;
/* If this is a direct call to eval, inherit the caller's strictness. */
if (evalCaller && evalCaller->strict)
globalsc.strict = true;
@ -313,32 +326,34 @@ bool
frontend::CompileLazyFunction(JSContext *cx, HandleFunction fun, LazyScript *lazy,
const jschar *chars, size_t length)
{
CompileOptions options(cx);
JS_ASSERT(cx->compartment() == fun->compartment());
CompileOptions options(cx, lazy->version());
options.setPrincipals(cx->compartment()->principals)
.setOriginPrincipals(lazy->parent()->originPrincipals)
.setVersion(lazy->parent()->getVersion())
.setFileAndLine(lazy->parent()->filename(), lazy->lineno())
.setOriginPrincipals(lazy->originPrincipals())
.setFileAndLine(lazy->source()->filename(), lazy->lineno())
.setColumn(lazy->column())
.setCompileAndGo(lazy->parent()->compileAndGo)
.setCompileAndGo(true)
.setNoScriptRval(false)
.setSelfHostingMode(false);
Parser<FullParseHandler> parser(cx, options, chars, length,
/* foldConstants = */ true, NULL, lazy);
RootedObject enclosingScope(cx, lazy->parent()->function());
RootedObject enclosingScope(cx, lazy->parentFunction());
ParseNode *pn = parser.standaloneLazyFunction(fun, lazy->parent()->staticLevel + 1,
lazy->strict());
ParseNode *pn = parser.standaloneLazyFunction(fun, lazy->staticLevel(), lazy->strict());
if (!pn)
return false;
JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, lazy->source()));
if (!sourceObject)
if (!NameFunctions(cx, pn))
return false;
JS::RootedScriptSource sourceObject(cx, lazy->sourceObject());
JS_ASSERT(sourceObject);
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false,
options, lazy->parent()->staticLevel + 1,
options, lazy->staticLevel(),
sourceObject, lazy->begin(), lazy->end()));
if (!script)
return false;
@ -347,11 +362,11 @@ frontend::CompileLazyFunction(JSContext *cx, HandleFunction fun, LazyScript *laz
if (lazy->directlyInsideEval())
script->directlyInsideEval = true;
bool hasGlobalScope = lazy->parent()->compileAndGo;
if (lazy->usesArgumentsAndApply())
script->usesArgumentsAndApply = true;
BytecodeEmitter bce(/* parent = */ NULL, &parser, pn->pn_funbox, script, options.forEval,
/* evalCaller = */ NullPtr(), hasGlobalScope,
/* evalCaller = */ NullPtr(), /* hasGlobalScope = */ true,
options.lineno, BytecodeEmitter::LazyFunction);
if (!bce.init())
return false;
@ -385,8 +400,10 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
return false;
}
bool canLazilyParse = CanLazilyParse(cx, options);
Maybe<Parser<SyntaxParseHandler> > syntaxParser;
if (options.canLazilyParse) {
if (canLazilyParse) {
syntaxParser.construct(cx, options, chars, length, /* foldConstants = */ false,
(Parser<SyntaxParseHandler> *) NULL,
(LazyScript *) NULL);
@ -395,7 +412,7 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
JS_ASSERT(!options.forEval);
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true,
options.canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
parser.sct = &sct;
JS_ASSERT(fun);

Просмотреть файл

@ -41,6 +41,7 @@
#include "vm/Shape.h"
#include "jsatominlines.h"
#include "jsobjinlines.h"
#include "jsscriptinlines.h"
#include "frontend/ParseMaps-inl.h"
@ -1128,11 +1129,22 @@ TryConvertFreeName(BytecodeEmitter *bce, ParseNode *pn)
* resolving upvar accesses within the inner function.
*/
if (bce->emitterMode == BytecodeEmitter::LazyFunction) {
// The only statements within a lazy function which can push lexical
// scopes are try/catch blocks. Use generic ops in this case.
for (StmtInfoBCE *stmt = bce->topStmt; stmt; stmt = stmt->down) {
switch (stmt->type) {
case STMT_TRY:
case STMT_FINALLY:
return true;
default:;
}
}
size_t hops = 0;
FunctionBox *funbox = bce->sc->asFunctionBox();
if (funbox->hasExtensibleScope())
return false;
if (funbox->function()->atom() == pn->pn_atom)
if (funbox->function()->isNamedLambda() && funbox->function()->atom() == pn->pn_atom)
return false;
if (funbox->function()->isHeavyweight()) {
hops++;
@ -2676,7 +2688,7 @@ EmitDestructuringDecls(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, Parse
if (pn->isKind(PNK_ARRAY)) {
for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
if (pn2->isKind(PNK_COMMA))
if (pn2->isKind(PNK_ELISION))
continue;
emitter = (pn2->isKind(PNK_NAME))
? EmitDestructuringDecl
@ -2896,8 +2908,8 @@ EmitDestructuringOpsHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn,
JS_ASSERT(bce->stackDepth >= stackDepth + 1);
}
/* Nullary comma node makes a hole in the array destructurer. */
if (pn3->isKind(PNK_COMMA) && pn3->isArity(PN_NULLARY)) {
/* Elision node makes a hole in the array destructurer. */
if (pn3->isKind(PNK_ELISION)) {
JS_ASSERT(pn->isKind(PNK_ARRAY));
JS_ASSERT(pn2 == pn3);
if (Emit1(cx, bce, JSOP_POP) < 0)
@ -2972,7 +2984,7 @@ EmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp,
}
/* MaybeEmitGroupAssignment won't call us if rhs is holey. */
JS_ASSERT(!(pn->isKind(PNK_COMMA) && pn->isArity(PN_NULLARY)));
JS_ASSERT(!pn->isKind(PNK_ELISION));
if (!EmitTree(cx, bce, pn))
return false;
++limit;
@ -2989,7 +3001,7 @@ EmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp,
if (!EmitUnaliasedVarOp(cx, JSOP_GETLOCAL, slot, bce))
return false;
if (pn->isKind(PNK_COMMA) && pn->isArity(PN_NULLARY)) {
if (pn->isKind(PNK_ELISION)) {
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
} else {
@ -4491,8 +4503,10 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false;
if (fun->isInterpretedLazy()) {
if (!fun->lazyScript()->parent())
fun->lazyScript()->initParent(bce->script);
if (!fun->lazyScript()->sourceObject()) {
JSFunction *parent = bce->sc->isFunctionBox() ? bce->sc->asFunctionBox()->function() : NULL;
fun->lazyScript()->setParent(parent, bce->script->sourceObject(), bce->script->originPrincipals);
}
} else {
SharedContext *outersc = bce->sc;
@ -4557,6 +4571,9 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
/* We measured the max scope depth when we parsed the function. */
if (!EmitFunctionScript(cx, &bce2, pn->pn_body))
return false;
if (funbox->usesArguments && funbox->usesApply)
script->usesArgumentsAndApply = true;
}
}
@ -5264,16 +5281,14 @@ EmitIncOrDec(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* the comment on EmitSwitch.
*/
MOZ_NEVER_INLINE static bool
EmitLabel(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
EmitLabeledStatement(JSContext *cx, BytecodeEmitter *bce, const LabeledStatement *pn)
{
/*
* Emit a JSOP_LABEL instruction. The argument is the offset to the statement
* following the labeled statement.
*/
JSAtom *atom = pn->pn_atom;
jsatomid index;
if (!bce->makeAtomIndex(atom, &index))
if (!bce->makeAtomIndex(pn->label(), &index))
return false;
ptrdiff_t top = EmitJump(cx, bce, JSOP_LABEL, 0);
@ -5283,8 +5298,8 @@ EmitLabel(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
/* Emit code for the labeled statement. */
StmtInfoBCE stmtInfo(cx);
PushStatementBCE(bce, &stmtInfo, STMT_LABEL, bce->offset());
stmtInfo.label = atom;
if (!EmitTree(cx, bce, pn->expr()))
stmtInfo.label = pn->label();
if (!EmitTree(cx, bce, pn->statement()))
return false;
if (!PopStatementBCE(cx, bce))
return false;
@ -5527,7 +5542,7 @@ EmitArray(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (nspread && !EmitNumberOp(cx, 0, bce))
return false;
for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
if (pn2->isKind(PNK_COMMA) && pn2->isArity(PN_NULLARY)) {
if (pn2->isKind(PNK_ELISION)) {
if (Emit1(cx, bce, JSOP_HOLE) < 0)
return false;
} else {
@ -5816,8 +5831,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
ok = EmitStatement(cx, bce, pn);
break;
case PNK_COLON:
ok = EmitLabel(cx, bce, pn);
case PNK_LABEL:
ok = EmitLabeledStatement(cx, bce, &pn->as<LabeledStatement>());
break;
case PNK_COMMA:

Просмотреть файл

@ -49,6 +49,10 @@ class FullParseHandler
LazyScript * const lazyOuterFunction_;
size_t lazyInnerFunctionIndex;
const TokenPos &pos() {
return tokenStream.currentToken().pos;
}
public:
/*
@ -100,7 +104,7 @@ class FullParseHandler
return dn;
}
ParseNode *newAtom(ParseNodeKind kind, JSAtom *atom, JSOp op = JSOP_NOP) {
ParseNode *pn = NullaryNode::create(kind, this);
ParseNode *pn = new_<NullaryNode>(kind, pos());
if (!pn)
return NULL;
pn->setOp(op);
@ -108,7 +112,7 @@ class FullParseHandler
return pn;
}
ParseNode *newNumber(double value, DecimalPoint decimalPoint = NoDecimal) {
ParseNode *pn = NullaryNode::create(PNK_NUMBER, this);
ParseNode *pn = new_<NullaryNode>(PNK_NUMBER, pos());
if (!pn)
return NULL;
pn->initNumber(value, decimalPoint);
@ -130,8 +134,8 @@ class FullParseHandler
return new_<ConditionalExpression>(cond, thenExpr, elseExpr);
}
ParseNode *newNullary(ParseNodeKind kind) {
return NullaryNode::create(kind, this);
ParseNode *newElision() {
return new_<NullaryNode>(PNK_ELISION, pos());
}
ParseNode *newUnary(ParseNodeKind kind, ParseNode *kid, JSOp op = JSOP_NOP) {
@ -162,11 +166,6 @@ class FullParseHandler
ParseContext<FullParseHandler> *pc, JSOp op = JSOP_NOP) {
return ParseNode::newBinaryOrAppend(kind, op, left, right, this, pc, foldConstants);
}
void setBinaryRHS(ParseNode *pn, ParseNode *rhs) {
JS_ASSERT(pn->isArity(PN_BINARY));
pn->pn_right = rhs;
pn->pn_pos.end = rhs->pn_pos.end;
}
ParseNode *newTernary(ParseNodeKind kind,
ParseNode *first, ParseNode *second, ParseNode *third,
@ -174,12 +173,22 @@ class FullParseHandler
return new_<TernaryNode>(kind, op, first, second, third);
}
ParseNode *newLabeledStatement(PropertyName *label, ParseNode *stmt, uint32_t begin) {
return new_<LabeledStatement>(label, stmt, begin);
}
ParseNode *newCaseOrDefault(uint32_t begin, ParseNode *expr, ParseNode *body) {
TokenPos pos = TokenPos::make(begin, body->pn_pos.end);
return new_<BinaryNode>(expr ? PNK_CASE : PNK_DEFAULT, JSOP_NOP, pos, expr, body);
}
ParseNode *newBreak(PropertyName *label, uint32_t begin, uint32_t end) {
return new_<BreakStatement>(label, begin, end);
}
ParseNode *newContinue(PropertyName *label, uint32_t begin, uint32_t end) {
return new_<ContinueStatement>(label, begin, end);
}
ParseNode *newDebuggerStatement(const TokenPos &pos) {
return new_<DebuggerStatement>(pos);
}
@ -193,8 +202,6 @@ class FullParseHandler
inline bool addCatchBlock(ParseNode *catchList, ParseNode *letBlock,
ParseNode *catchName, ParseNode *catchGuard, ParseNode *catchBody);
inline void morphNameIntoLabel(ParseNode *name, ParseNode *statement);
inline void setLeaveBlockResult(ParseNode *block, ParseNode *kid, bool leaveBlockExpr);
inline void setLastFunctionArgumentDefault(ParseNode *funcpn, ParseNode *pn);
@ -213,7 +220,6 @@ class FullParseHandler
return pn->isKind(kind) && !pn->isInParens();
}
inline void noteLValue(ParseNode *pn);
inline bool finishInitializerAssignment(ParseNode *pn, ParseNode *init, JSOp op);
void setBeginPosition(ParseNode *pn, ParseNode *oth) {
@ -292,9 +298,6 @@ class FullParseHandler
}
return NULL;
}
bool isEmptySemicolon(ParseNode *pn) {
return pn->isKind(PNK_SEMI) && !pn->pn_kid;
}
inline ParseNode *makeAssignment(ParseNode *pn, ParseNode *rhs);
@ -367,14 +370,6 @@ FullParseHandler::addCatchBlock(ParseNode *catchList, ParseNode *letBlock,
return true;
}
inline void
FullParseHandler::morphNameIntoLabel(ParseNode *name, ParseNode *statement)
{
name->setKind(PNK_COLON);
name->pn_pos.end = statement->pn_pos.end;
name->pn_expr = statement;
}
inline void
FullParseHandler::setLeaveBlockResult(ParseNode *block, ParseNode *kid, bool leaveBlockExpr)
{
@ -419,15 +414,6 @@ FullParseHandler::newLexicalScope(ObjectBox *blockbox)
return pn;
}
inline void
FullParseHandler::noteLValue(ParseNode *pn)
{
if (pn->isUsed())
pn->pn_lexdef->pn_dflags |= PND_ASSIGNED;
pn->pn_dflags |= PND_ASSIGNED;
}
inline bool
FullParseHandler::finishInitializerAssignment(ParseNode *pn, ParseNode *init, JSOp op)
{
@ -445,7 +431,7 @@ FullParseHandler::finishInitializerAssignment(ParseNode *pn, ParseNode *init, JS
? JSOP_SETCONST
: JSOP_SETNAME);
noteLValue(pn);
pn->markAsAssigned();
/* The declarator's position must include the initializer. */
pn->pn_pos.end = init->pn_pos.end;

Просмотреть файл

@ -8,10 +8,13 @@
#include "jsfun.h"
#include "jsprf.h"
#include "frontend/BytecodeCompiler.h"
#include "frontend/ParseNode.h"
#include "frontend/SharedContext.h"
#include "jsfuninlines.h"
#include "vm/String-inl.h"
#include "vm/StringBuffer.h"
@ -175,8 +178,6 @@ class NameResolver
JSAtom *resolveFun(ParseNode *pn, HandleAtom prefix) {
JS_ASSERT(pn != NULL && pn->isKind(PNK_FUNCTION));
RootedFunction fun(cx, pn->pn_funbox->function());
if (nparents == 0)
return NULL;
StringBuffer buf(cx);
this->buf = &buf;
@ -184,7 +185,7 @@ class NameResolver
/* If the function already has a name, use that */
if (fun->displayAtom() != NULL) {
if (prefix == NULL)
return fun->atom();
return fun->displayAtom();
if (!buf.append(prefix) ||
!buf.append("/") ||
!buf.append(fun->displayAtom()))

Просмотреть файл

@ -530,7 +530,7 @@ Parser<FullParseHandler>::cloneLeftHandSide(ParseNode *opn)
pn2 = handler.new_<BinaryNode>(PNK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
} else if (opn2->isArity(PN_NULLARY)) {
JS_ASSERT(opn2->isKind(PNK_COMMA));
JS_ASSERT(opn2->isKind(PNK_ELISION));
pn2 = cloneParseTree(opn2);
} else {
pn2 = cloneLeftHandSide(opn2);

Просмотреть файл

@ -75,7 +75,9 @@ class UpvarCookie
F(DOT) \
F(ELEM) \
F(ARRAY) \
F(ELISION) \
F(STATEMENTLIST) \
F(LABEL) \
F(OBJECT) \
F(CALL) \
F(NAME) \
@ -181,7 +183,8 @@ class UpvarCookie
*
* The long comment after this enum block describes the kinds in detail.
*/
enum ParseNodeKind {
enum ParseNodeKind
{
#define EMIT_ENUM(name) PNK_##name,
FOR_EACH_PARSE_NODE_KIND(EMIT_ENUM)
#undef EMIT_ENUM
@ -284,7 +287,7 @@ enum ParseNodeKind {
* pn_prologue: true if Directive Prologue member
* in original source, not introduced via
* constant folding or other tree rewriting
* PNK_COLON name pn_atom: label, pn_expr: labeled statement
* PNK_LABEL name pn_atom: label, pn_expr: labeled statement
*
* <Expressions>
* All left-associated binary trees of the same type are optimized into lists
@ -357,7 +360,7 @@ enum ParseNodeKind {
* PNK_GENEXP list Exactly like PNK_CALL, used for the implicit call
* in the desugaring of a generator-expression.
* PNK_ARRAY list pn_head: list of pn_count array element exprs
* [,,] holes are represented by PNK_COMMA nodes
* [,,] holes are represented by PNK_ELISION nodes
* pn_xflags: PN_ENDCOMMA if extra comma at end
* PNK_OBJECT list pn_head: list of pn_count binary PNK_COLON nodes
* PNK_COLON binary key-value pair in object initializer or
@ -392,7 +395,8 @@ enum ParseNodeKind {
* pn_kid: array comprehension expression
* PNK_NOP nullary
*/
enum ParseNodeArity {
enum ParseNodeArity
{
PN_NULLARY, /* 0 kids, only pn_atom/pn_dval/etc. */
PN_UNARY, /* one kid, plus a couple of scalars */
PN_BINARY, /* two kids, plus a couple of scalars */
@ -404,6 +408,7 @@ enum ParseNodeArity {
struct Definition;
class LabeledStatement;
class LoopControlStatement;
class BreakStatement;
class ContinueStatement;
@ -411,7 +416,8 @@ class ConditionalExpression;
class PropertyAccess;
class ModuleBox;
struct ParseNode {
struct ParseNode
{
private:
uint32_t pn_type : 16, /* PNK_* type */
pn_op : 8, /* see JSOp enum and jsopcode.tbl */
@ -723,11 +729,6 @@ struct ParseNode {
/* Return true if this node appears in a Directive Prologue. */
bool isDirectivePrologueMember() const { return pn_prologue; }
#ifdef JS_HAS_DESTRUCTURING
/* Return true if this represents a hole in an array literal. */
bool isArrayHole() const { return isKind(PNK_COMMA) && isArity(PN_NULLARY); }
#endif
#ifdef JS_HAS_GENERATOR_EXPRS
ParseNode *generatorExpr() const {
JS_ASSERT(isKind(PNK_GENEXP));
@ -738,6 +739,8 @@ struct ParseNode {
}
#endif
inline void markAsAssigned();
/*
* Compute a pointer to the last element in a singly-linked list. NB: list
* must be non-empty for correct PN_LAST usage -- this is asserted!
@ -813,7 +816,11 @@ struct ParseNode {
#endif
};
struct NullaryNode : public ParseNode {
struct NullaryNode : public ParseNode
{
NullaryNode(ParseNodeKind kind, const TokenPos &pos)
: ParseNode(kind, JSOP_NOP, PN_NULLARY, pos) {}
static inline NullaryNode *create(ParseNodeKind kind, FullParseHandler *handler) {
return (NullaryNode *) ParseNode::create(kind, PN_NULLARY, handler);
}
@ -827,7 +834,8 @@ struct NullaryNode : public ParseNode {
#endif
};
struct UnaryNode : public ParseNode {
struct UnaryNode : public ParseNode
{
UnaryNode(ParseNodeKind kind, JSOp op, const TokenPos &pos, ParseNode *kid)
: ParseNode(kind, op, PN_UNARY, pos)
{
@ -847,7 +855,8 @@ struct UnaryNode : public ParseNode {
#endif
};
struct BinaryNode : public ParseNode {
struct BinaryNode : public ParseNode
{
BinaryNode(ParseNodeKind kind, JSOp op, const TokenPos &pos, ParseNode *left, ParseNode *right)
: ParseNode(kind, op, PN_BINARY, pos)
{
@ -875,7 +884,8 @@ struct BinaryNode : public ParseNode {
#endif
};
struct TernaryNode : public ParseNode {
struct TernaryNode : public ParseNode
{
TernaryNode(ParseNodeKind kind, JSOp op, ParseNode *kid1, ParseNode *kid2, ParseNode *kid3)
: ParseNode(kind, op, PN_TERNARY,
TokenPos::make((kid1 ? kid1 : kid2 ? kid2 : kid3)->pn_pos.begin,
@ -921,7 +931,8 @@ struct ListNode : public ParseNode
#endif
};
struct CodeNode : public ParseNode {
struct CodeNode : public ParseNode
{
static inline CodeNode *create(ParseNodeKind kind, FullParseHandler *handler) {
return (CodeNode *) ParseNode::create(kind, PN_CODE, handler);
}
@ -935,7 +946,8 @@ struct CodeNode : public ParseNode {
#endif
};
struct NameNode : public ParseNode {
struct NameNode : public ParseNode
{
static NameNode *create(ParseNodeKind kind, JSAtom *atom,
FullParseHandler *handler, ParseContext<FullParseHandler> *pc);
@ -950,13 +962,41 @@ struct NameNode : public ParseNode {
#endif
};
struct LexicalScopeNode : public ParseNode {
struct LexicalScopeNode : public ParseNode
{
static inline LexicalScopeNode *create(ParseNodeKind kind, FullParseHandler *handler) {
return (LexicalScopeNode *) ParseNode::create(kind, PN_NAME, handler);
}
};
class LoopControlStatement : public ParseNode {
class LabeledStatement : public ParseNode
{
public:
LabeledStatement(PropertyName *label, ParseNode *stmt, uint32_t begin)
: ParseNode(PNK_LABEL, JSOP_NOP, PN_NAME, TokenPos::make(begin, stmt->pn_pos.end))
{
pn_atom = label;
pn_expr = stmt;
}
PropertyName *label() const {
return pn_atom->asPropertyName();
}
ParseNode *statement() const {
return pn_expr;
}
static bool test(const ParseNode &node) {
bool match = node.isKind(PNK_LABEL);
JS_ASSERT_IF(match, node.isArity(PN_NAME));
JS_ASSERT_IF(match, node.isOp(JSOP_NOP));
return match;
}
};
class LoopControlStatement : public ParseNode
{
protected:
LoopControlStatement(ParseNodeKind kind, PropertyName *label, uint32_t begin, uint32_t end)
: ParseNode(kind, JSOP_NOP, PN_NULLARY, TokenPos::make(begin, end))
@ -979,7 +1019,8 @@ class LoopControlStatement : public ParseNode {
}
};
class BreakStatement : public LoopControlStatement {
class BreakStatement : public LoopControlStatement
{
public:
BreakStatement(PropertyName *label, uint32_t begin, uint32_t end)
: LoopControlStatement(PNK_BREAK, label, begin, end)
@ -993,7 +1034,8 @@ class BreakStatement : public LoopControlStatement {
}
};
class ContinueStatement : public LoopControlStatement {
class ContinueStatement : public LoopControlStatement
{
public:
ContinueStatement(PropertyName *label, uint32_t begin, uint32_t end)
: LoopControlStatement(PNK_CONTINUE, label, begin, end)
@ -1007,14 +1049,16 @@ class ContinueStatement : public LoopControlStatement {
}
};
class DebuggerStatement : public ParseNode {
class DebuggerStatement : public ParseNode
{
public:
DebuggerStatement(const TokenPos &pos)
: ParseNode(PNK_DEBUGGER, JSOP_NOP, PN_NULLARY, pos)
{ }
};
class ConditionalExpression : public ParseNode {
class ConditionalExpression : public ParseNode
{
public:
ConditionalExpression(ParseNode *condition, ParseNode *thenExpr, ParseNode *elseExpr)
: ParseNode(PNK_CONDITIONAL, JSOP_NOP, PN_TERNARY,
@ -1048,24 +1092,28 @@ class ConditionalExpression : public ParseNode {
}
};
class ThisLiteral : public ParseNode {
class ThisLiteral : public ParseNode
{
public:
ThisLiteral(const TokenPos &pos) : ParseNode(PNK_THIS, JSOP_THIS, PN_NULLARY, pos) { }
};
class NullLiteral : public ParseNode {
class NullLiteral : public ParseNode
{
public:
NullLiteral(const TokenPos &pos) : ParseNode(PNK_NULL, JSOP_NULL, PN_NULLARY, pos) { }
};
class BooleanLiteral : public ParseNode {
class BooleanLiteral : public ParseNode
{
public:
BooleanLiteral(bool b, const TokenPos &pos)
: ParseNode(b ? PNK_TRUE : PNK_FALSE, b ? JSOP_TRUE : JSOP_FALSE, PN_NULLARY, pos)
{ }
};
class PropertyAccess : public ParseNode {
class PropertyAccess : public ParseNode
{
public:
PropertyAccess(ParseNode *lhs, PropertyName *name, uint32_t begin, uint32_t end)
: ParseNode(PNK_DOT, JSOP_GETPROP, PN_NAME, TokenPos::make(begin, end))
@ -1091,7 +1139,8 @@ class PropertyAccess : public ParseNode {
}
};
class PropertyByValue : public ParseNode {
class PropertyByValue : public ParseNode
{
public:
PropertyByValue(ParseNode *lhs, ParseNode *propExpr, uint32_t begin, uint32_t end)
: ParseNode(PNK_ELEM, JSOP_GETELEM, PN_BINARY, TokenPos::make(begin, end))
@ -1239,7 +1288,8 @@ struct Definition : public ParseNode
}
};
class ParseNodeAllocator {
class ParseNodeAllocator
{
public:
explicit ParseNodeAllocator(JSContext *cx) : cx(cx), freelist(NULL) {}
@ -1268,6 +1318,15 @@ ParseNode::test(unsigned flag) const
return !!(pn_dflags & flag);
}
inline void
ParseNode::markAsAssigned()
{
JS_ASSERT(js_CodeSpec[pn_op].format & JOF_NAME);
if (isUsed())
pn_lexdef->pn_dflags |= PND_ASSIGNED;
pn_dflags |= PND_ASSIGNED;
}
inline Definition *
ParseNode::resolve()
{
@ -1295,7 +1354,8 @@ ParseNode::isConstant()
}
}
class ObjectBox {
class ObjectBox
{
public:
JSObject *object;
@ -1316,7 +1376,8 @@ class ObjectBox {
ObjectBox(Module *module, ObjectBox *traceLink);
};
enum ParseReportKind {
enum ParseReportKind
{
ParseError,
ParseWarning,
ParseExtraWarning,

Просмотреть файл

@ -48,6 +48,7 @@
#include "vm/Shape.h"
#include "jsatominlines.h"
#include "jsobjinlines.h"
#include "jsscriptinlines.h"
#include "frontend/ParseMaps-inl.h"
@ -419,9 +420,6 @@ Parser<ParseHandler>::Parser(JSContext *cx, const CompileOptions &options,
abortedSyntaxParse(false),
handler(cx, tokenStream, foldConstants, syntaxParser, lazyOuterFunction)
{
// XXX bug 678037 always disable syntax parsing for now.
handler.disableSyntaxParser();
cx->runtime()->activeCompilations++;
// The Mozilla specific JSOPTION_EXTRA_WARNINGS option adds extra warnings
@ -487,6 +485,8 @@ FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fu
inGenexpLambda(false),
useAsm(false),
insideUseAsm(outerpc && outerpc->useAsmOrInsideUseAsm()),
usesArguments(false),
usesApply(false),
funCxFlags()
{
JS_ASSERT(fun->isTenured());
@ -925,6 +925,7 @@ Parser<FullParseHandler>::checkFunctionArguments()
dn->pn_dflags |= PND_IMPLICITARGUMENTS;
if (!pc->define(context, arguments, dn, Definition::VAR))
return false;
pc->sc->asFunctionBox()->usesArguments = true;
break;
}
}
@ -1014,11 +1015,15 @@ template <>
bool
Parser<SyntaxParseHandler>::checkFunctionArguments()
{
if (pc->sc->asFunctionBox()->function()->hasRest()) {
if (pc->lexdeps->lookup(context->names().arguments)) {
bool hasRest = pc->sc->asFunctionBox()->function()->hasRest();
if (pc->lexdeps->lookup(context->names().arguments)) {
pc->sc->asFunctionBox()->usesArguments = true;
if (hasRest) {
report(ParseError, false, null(), JSMSG_ARGUMENTS_AND_REST);
return false;
}
} else if (hasRest) {
DefinitionNode maybeArgDef = pc->decls().lookupFirst(context->names().arguments);
if (maybeArgDef && handler.getDefinitionKind(maybeArgDef) != Definition::ARG) {
report(ParseError, false, null(), JSMSG_ARGUMENTS_AND_REST);
@ -1074,27 +1079,6 @@ Parser<ParseHandler>::functionBody(FunctionSyntaxKind kind, FunctionBodyType typ
return pn;
}
static void
ForgetUse(ParseNode *pn)
{
if (!pn->isUsed()) {
JS_ASSERT(!pn->isDefn());
return;
}
ParseNode **pnup = &pn->lexdef()->dn_uses;
ParseNode *pnu;
while ((pnu = *pnup) != pn)
pnup = &pnu->pn_link;
*pnup = pn->pn_link;
pn->setUsed(false);
}
static void
ForgetUse(SyntaxParseHandler::Node pn)
{
}
/* See comment for use in Parser::functionDef. */
template <>
bool
@ -1341,14 +1325,6 @@ Parser<FullParseHandler>::leaveFunction(ParseNode *fn, HandlePropertyName funNam
continue;
}
/*
* If there are no uses of this placeholder (e.g., it was created
* for an identifierName that turned out to be a label), there is
* nothing left to do.
*/
if (!dn->dn_uses)
continue;
Definition *outer_dn = outerpc->decls().lookupFirst(atom);
/*
@ -2046,7 +2022,7 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox *funbo
size_t numFreeVariables = pc->lexdeps->count();
size_t numInnerFunctions = pc->innerFunctions.length();
LazyScript *lazy = LazyScript::Create(context, numFreeVariables, numInnerFunctions,
LazyScript *lazy = LazyScript::Create(context, numFreeVariables, numInnerFunctions, versionNumber(),
funbox->bufStart, funbox->bufEnd,
funbox->startLine, funbox->startColumn);
if (!lazy)
@ -2064,6 +2040,8 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox *funbo
if (pc->sc->strict)
lazy->setStrict();
if (funbox->usesArguments && funbox->usesApply)
lazy->setUsesArgumentsAndApply();
PropagateTransitiveParseFlags(funbox, lazy);
funbox->object->toFunction()->initLazyScript(lazy);
@ -2173,6 +2151,11 @@ Parser<SyntaxParseHandler>::functionArgsAndBody(Node pn, HandleFunction fun,
*becameStrict = false;
ParseContext<SyntaxParseHandler> *outerpc = pc;
// As from a full parse handler, abort if functions are defined within
// lexical scopes.
if (pc->topScopeStmt)
return abortIfSyntaxParser();
// Create box for fun->object early to protect against last-ditch GC.
FunctionBox *funbox = newFunctionBox(fun, pc, strict);
if (!funbox)
@ -2503,7 +2486,7 @@ Parser<ParseHandler>::maybeParseDirective(Node pn, bool *cont)
template <>
void
Parser<FullParseHandler>::addStatementToList(ParseNode *pn, ParseNode *kid, bool *hasFunctionStmt)
Parser<FullParseHandler>::addStatementToList(ParseNode *pn, ParseNode *kid)
{
JS_ASSERT(pn->isKind(PNK_STATEMENTLIST));
@ -2512,21 +2495,12 @@ Parser<FullParseHandler>::addStatementToList(ParseNode *pn, ParseNode *kid, bool
* PNX_FUNCDEFS notifies the emitter that the block contains body-
* level function definitions that should be processed before the
* rest of nodes.
*
* |hasFunctionStmt| is for the TOK_LC case in Statement. It
* is relevant only for function definitions not at body-level,
* which we call function statements.
*/
if (pc->atBodyLevel()) {
pn->pn_xflags |= PNX_FUNCDEFS;
} else {
/*
* General deoptimization was done in functionDef, here we just
* need to tell TOK_LC in Parser::statement to add braces.
*/
/* General deoptimization was done in functionDef. */
JS_ASSERT_IF(pc->sc->isFunctionBox(), pc->sc->asFunctionBox()->hasExtensibleScope());
if (hasFunctionStmt)
*hasFunctionStmt = true;
}
}
@ -2536,7 +2510,7 @@ Parser<FullParseHandler>::addStatementToList(ParseNode *pn, ParseNode *kid, bool
template <>
void
Parser<SyntaxParseHandler>::addStatementToList(Node pn, Node kid, bool *hasFunctionStmt)
Parser<SyntaxParseHandler>::addStatementToList(Node pn, Node kid)
{
}
@ -2547,11 +2521,9 @@ Parser<SyntaxParseHandler>::addStatementToList(Node pn, Node kid, bool *hasFunct
*/
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::statements(bool *hasFunctionStmt)
Parser<ParseHandler>::statements()
{
JS_CHECK_RECURSION(context, return null());
if (hasFunctionStmt)
*hasFunctionStmt = false;
Node pn = handler.newList(PNK_STATEMENTLIST);
if (!pn)
@ -2584,7 +2556,7 @@ Parser<ParseHandler>::statements(bool *hasFunctionStmt)
return null();
}
addStatementToList(pn, next, hasFunctionStmt);
addStatementToList(pn, next);
}
/*
@ -2993,7 +2965,7 @@ Parser<FullParseHandler>::bindDestructuringVar(BindData<FullParseHandler> *data,
if (data->op == JSOP_DEFCONST)
pn->pn_dflags |= PND_CONST;
handler.noteLValue(pn);
pn->markAsAssigned();
return true;
}
@ -3021,7 +2993,7 @@ Parser<FullParseHandler>::bindDestructuringLHS(ParseNode *pn)
{
switch (pn->getKind()) {
case PNK_NAME:
handler.noteLValue(pn);
pn->markAsAssigned();
/* FALL THROUGH */
case PNK_DOT:
@ -3105,8 +3077,7 @@ Parser<FullParseHandler>::checkDestructuring(BindData<FullParseHandler> *data,
if (left->isKind(PNK_ARRAY)) {
for (ParseNode *pn = left->pn_head; pn; pn = pn->pn_next) {
/* Nullary comma is an elision; binary comma is an expression.*/
if (!pn->isArrayHole()) {
if (!pn->isKind(PNK_ELISION)) {
if (pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT)) {
ok = checkDestructuring(data, pn, false);
} else {
@ -3542,7 +3513,10 @@ Parser<ParseHandler>::switchStatement()
bool seenDefault = false;
TokenKind tt;
while ((tt = tokenStream.getToken()) != TOK_RC) {
Node casepn;
uint32_t caseBegin = tokenStream.currentToken().pos.begin;
ParseNodeKind caseKind;
Node caseExpr;
switch (tt) {
case TOK_DEFAULT:
if (seenDefault) {
@ -3550,21 +3524,16 @@ Parser<ParseHandler>::switchStatement()
return null();
}
seenDefault = true;
casepn = handler.newBinary(PNK_DEFAULT);
if (!casepn)
return null();
caseKind = PNK_DEFAULT;
caseExpr = null();
break;
case TOK_CASE:
{
Node left = expr();
if (!left)
return null();
casepn = handler.newBinary(PNK_CASE, left);
if (!casepn)
caseKind = PNK_CASE;
caseExpr = expr();
if (!caseExpr)
return null();
break;
}
case TOK_ERROR:
return null();
@ -3574,8 +3543,6 @@ Parser<ParseHandler>::switchStatement()
return null();
}
handler.addList(caseList, casepn);
MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
Node body = handler.newList(PNK_STATEMENTLIST);
@ -3593,7 +3560,10 @@ Parser<ParseHandler>::switchStatement()
handler.addList(body, stmt);
}
handler.setBinaryRHS(casepn, body);
Node casepn = handler.newCaseOrDefault(caseBegin, caseExpr, body);
if (!casepn)
return null();
handler.addList(caseList, casepn);
}
/*
@ -3916,7 +3886,7 @@ Parser<FullParseHandler>::forStatement()
switch (pn2->getKind()) {
case PNK_NAME:
/* Beware 'for (arguments in ...)' with or without a 'var'. */
handler.noteLValue(pn2);
pn2->markAsAssigned();
break;
#if JS_HAS_DESTRUCTURING
@ -4099,6 +4069,7 @@ Parser<SyntaxParseHandler>::forStatement()
/* Check that the left side of the 'in' or 'of' is valid. */
if (!forDecl &&
lhsNode != SyntaxParseHandler::NodeName &&
lhsNode != SyntaxParseHandler::NodeGetProp &&
lhsNode != SyntaxParseHandler::NodeLValue)
{
JS_ALWAYS_FALSE(abortIfSyntaxParser());
@ -4311,12 +4282,15 @@ Parser<ParseHandler>::tryStatement()
return pn;
}
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::withStatement()
template <>
ParseNode *
Parser<FullParseHandler>::withStatement()
{
if (!abortIfSyntaxParser())
if (handler.syntaxParser) {
handler.disableSyntaxParser();
abortedSyntaxParse = true;
return null();
}
JS_ASSERT(tokenStream.isCurrentTokenType(TOK_WITH));
uint32_t begin = tokenStream.currentToken().pos.begin;
@ -4354,7 +4328,7 @@ Parser<ParseHandler>::withStatement()
* to safely optimize binding globals (see bug 561923).
*/
for (AtomDefnRange r = pc->lexdeps->all(); !r.empty(); r.popFront()) {
DefinitionNode defn = r.front().value().get<ParseHandler>();
DefinitionNode defn = r.front().value().get<FullParseHandler>();
DefinitionNode lexdep = handler.resolve(defn);
handler.deoptimizeUsesWithin(lexdep,
TokenPos::make(begin, tokenStream.currentToken().pos.begin));
@ -4369,6 +4343,14 @@ Parser<ParseHandler>::withStatement()
return pn;
}
template <>
SyntaxParseHandler::Node
Parser<SyntaxParseHandler>::withStatement()
{
JS_ALWAYS_FALSE(abortIfSyntaxParser());
return null();
}
#if JS_HAS_BLOCK_SCOPE
template <>
ParseNode *
@ -4499,6 +4481,35 @@ Parser<SyntaxParseHandler>::letStatement()
#endif // JS_HAS_BLOCK_SCOPE
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::labeledStatement()
{
uint32_t begin = tokenStream.currentToken().pos.begin;
RootedPropertyName label(context, tokenStream.currentToken().name());
for (StmtInfoPC *stmt = pc->topStmt; stmt; stmt = stmt->down) {
if (stmt->type == STMT_LABEL && stmt->label == label) {
report(ParseError, false, null(), JSMSG_DUPLICATE_LABEL);
return null();
}
}
tokenStream.consumeKnownToken(TOK_COLON);
/* Push a label struct and parse the statement. */
StmtInfoPC stmtInfo(context);
PushStatementPC(pc, &stmtInfo, STMT_LABEL);
stmtInfo.label = label;
Node pn = statement();
if (!pn)
return null();
/* Pop the label, set pn_expr, and return early. */
PopStatementPC(context, pc);
return handler.newLabeledStatement(label, pn, begin);
}
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::expressionStatement()
@ -4508,37 +4519,6 @@ Parser<ParseHandler>::expressionStatement()
if (!pn2)
return null();
if (tokenStream.peekToken() == TOK_COLON) {
RootedAtom label(context, handler.isName(pn2));
if (!label) {
report(ParseError, false, null(), JSMSG_BAD_LABEL);
return null();
}
for (StmtInfoPC *stmt = pc->topStmt; stmt; stmt = stmt->down) {
if (stmt->type == STMT_LABEL && stmt->label == label) {
report(ParseError, false, null(), JSMSG_DUPLICATE_LABEL);
return null();
}
}
ForgetUse(pn2);
(void) tokenStream.getToken();
/* Push a label struct and parse the statement. */
StmtInfoPC stmtInfo(context);
PushStatementPC(pc, &stmtInfo, STMT_LABEL);
stmtInfo.label = label;
Node pn = statement();
if (!pn)
return null();
/* Pop the label, set pn_expr, and return early. */
PopStatementPC(context, pc);
handler.morphNameIntoLabel(pn2, pn);
return pn2;
}
Node pn = handler.newUnary(PNK_SEMI, pn2);
/* Check termination of this primitive statement. */
@ -4566,18 +4546,18 @@ Parser<ParseHandler>::statement()
if (!cond)
return null();
if (tokenStream.peekToken() == TOK_SEMI &&
!report(ParseExtraWarning, false, null(), JSMSG_EMPTY_CONSEQUENT))
{
return null();
}
StmtInfoPC stmtInfo(context);
PushStatementPC(pc, &stmtInfo, STMT_IF);
Node thenBranch = statement();
if (!thenBranch)
return null();
if (handler.isEmptySemicolon(thenBranch) &&
!report(ParseExtraWarning, false, null(), JSMSG_EMPTY_CONSEQUENT))
{
return null();
}
Node elseBranch;
if (tokenStream.matchToken(TOK_ELSE, TSF_OPERAND)) {
stmtInfo.type = STMT_ELSE;
@ -4803,8 +4783,8 @@ Parser<ParseHandler>::statement()
StmtInfoPC stmtInfo(context);
if (!PushBlocklikeStatement(&stmtInfo, STMT_BLOCK, pc))
return null();
bool hasFunctionStmt;
pn = statements(&hasFunctionStmt);
pn = statements();
if (!pn)
return null();
@ -4827,12 +4807,16 @@ Parser<ParseHandler>::statement()
case TOK_ERROR:
return null();
case TOK_NAME:
if (tokenStream.currentToken().name() == context->names().module &&
tokenStream.peekTokenSameLine(TSF_OPERAND) == TOK_STRING)
case TOK_NAME: {
if (tokenStream.peekToken() == TOK_COLON)
return labeledStatement();
if (tokenStream.currentToken().name() == context->names().module
&& tokenStream.peekTokenSameLine() == TOK_STRING)
{
return moduleDecl();
}
}
/* FALL THROUGH */
default:
return expressionStatement();
@ -5200,7 +5184,7 @@ Parser<FullParseHandler>::setAssignmentLhsOps(ParseNode *pn, JSOp op)
if (!checkStrictAssignment(pn))
return false;
pn->setOp(pn->isOp(JSOP_GETLOCAL) ? JSOP_SETLOCAL : JSOP_SETNAME);
handler.noteLValue(pn);
pn->markAsAssigned();
break;
case PNK_DOT:
pn->setOp(JSOP_SETPROP);
@ -5235,8 +5219,12 @@ bool
Parser<SyntaxParseHandler>::setAssignmentLhsOps(Node pn, JSOp op)
{
/* Full syntax checking of valid assignment LHS terms requires a parse tree. */
if (pn != SyntaxParseHandler::NodeName && pn != SyntaxParseHandler::NodeLValue)
if (pn != SyntaxParseHandler::NodeName &&
pn != SyntaxParseHandler::NodeGetProp &&
pn != SyntaxParseHandler::NodeLValue)
{
return abortIfSyntaxParser();
}
return checkStrictAssignment(pn);
}
@ -5337,7 +5325,7 @@ Parser<FullParseHandler>::setIncOpKid(ParseNode *pn, ParseNode *kid, TokenKind t
switch (kid->getKind()) {
case PNK_NAME:
handler.noteLValue(kid);
kid->markAsAssigned();
break;
case PNK_CALL:
@ -5419,8 +5407,12 @@ Parser<SyntaxParseHandler>::checkDeleteExpression(Node *pn)
// Treat deletion of non-lvalues as ambiguous, so that any error associated
// with deleting a call expression is reported.
if (*pn != SyntaxParseHandler::NodeLValue && strictMode())
if (*pn != SyntaxParseHandler::NodeGetProp &&
*pn != SyntaxParseHandler::NodeLValue &&
strictMode())
{
return abortIfSyntaxParser();
}
return true;
}
@ -6444,10 +6436,13 @@ Parser<ParseHandler>::memberExpr(TokenKind tt, bool allowCallSyntax)
}
} else if (JSAtom *atom = handler.isGetProp(lhs)) {
/* Select JSOP_FUNAPPLY given foo.apply(...). */
if (atom == context->names().apply)
if (atom == context->names().apply) {
handler.setOp(nextMember, JSOP_FUNAPPLY);
else if (atom == context->names().call)
if (pc->sc->isFunctionBox())
pc->sc->asFunctionBox()->usesApply = true;
} else if (atom == context->names().call) {
handler.setOp(nextMember, JSOP_FUNCALL);
}
}
handler.setBeginPosition(nextMember, lhs);
@ -6551,7 +6546,17 @@ template <>
SyntaxParseHandler::Node
Parser<SyntaxParseHandler>::newRegExp(const jschar *buf, size_t length, RegExpFlag flags)
{
return SyntaxParseHandler::NodeGeneric;
// Create the regexp even when doing a syntax parse, to check the regexp's syntax.
const StableCharPtr chars(buf, length);
RegExpStatics *res = context->regExpStatics();
RegExpObject *reobj;
if (context->hasfp())
reobj = RegExpObject::create(context, res, chars.get(), length, flags, &tokenStream);
else
reobj = RegExpObject::createNoStatics(context, chars.get(), length, flags, &tokenStream);
return reobj ? SyntaxParseHandler::NodeGeneric : SyntaxParseHandler::NodeFailure;
}
template <typename ParseHandler>
@ -6601,9 +6606,8 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt)
break;
if (tt == TOK_COMMA) {
/* So CURRENT_TOKEN gets TOK_COMMA and not TOK_LB. */
tokenStream.matchToken(TOK_COMMA);
pn2 = handler.newNullary(PNK_COMMA);
pn2 = handler.newElision();
if (!pn2)
return null();
handler.setListFlag(pn, PNX_SPECIALARRAYINIT | PNX_NONCONST);

Просмотреть файл

@ -421,10 +421,11 @@ struct Parser : private AutoGCRooter, public StrictModeGetter
Node moduleDecl();
Node functionStmt();
Node functionExpr();
Node statements(bool *hasFunctionStmt = NULL);
Node statements();
Node switchStatement();
Node forStatement();
Node labeledStatement();
Node tryStatement();
Node withStatement();
#if JS_HAS_BLOCK_SCOPE
@ -482,7 +483,7 @@ struct Parser : private AutoGCRooter, public StrictModeGetter
bool setAssignmentLhsOps(Node pn, JSOp op);
bool matchInOrOf(bool *isForOfp);
void addStatementToList(Node pn, Node kid, bool *hasFunctionStmt);
void addStatementToList(Node pn, Node kid);
bool checkFunctionArguments();
bool makeDefIntoUse(Definition *dn, Node pn, JSAtom *atom);
bool checkFunctionDefinition(HandlePropertyName funName, Node *pn, FunctionSyntaxKind kind,

Просмотреть файл

@ -184,9 +184,9 @@ class GlobalSharedContext : public SharedContext
JSObject *scopeChain() const { return scopeChain_; }
};
class ModuleBox : public ObjectBox, public SharedContext {
public:
class ModuleBox : public ObjectBox, public SharedContext
{
public:
Bindings bindings;
ModuleBox(JSContext *cx, ObjectBox *traceListHead, Module *module,
@ -210,6 +210,10 @@ class FunctionBox : public ObjectBox, public SharedContext
bool useAsm:1; /* function contains "use asm" directive */
bool insideUseAsm:1; /* nested function of function of "use asm" directive */
// Fields for use in heuristics.
bool usesArguments:1; /* contains a free use of 'arguments' */
bool usesApply:1; /* contains an f.apply() call */
FunctionContextFlags funCxFlags;
template <typename ParseHandler>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше