diff --git a/accessible/src/base/FocusManager.cpp b/accessible/src/base/FocusManager.cpp index 792784fb9578..0b7e03bc1c3e 100644 --- a/accessible/src/base/FocusManager.cpp +++ b/accessible/src/base/FocusManager.cpp @@ -5,6 +5,7 @@ #include "FocusManager.h" #include "Accessible-inl.h" +#include "AccIterator.h" #include "DocAccessible-inl.h" #include "nsAccessibilityService.h" #include "nsAccUtils.h" @@ -288,8 +289,30 @@ FocusManager::ProcessFocusEvent(AccEvent* aEvent) // Fire menu start/end events for ARIA menus. if (target->ARIARole() == roles::MENUITEM) { // The focus was moved into menu. - Accessible* ARIAMenubar = - nsAccUtils::GetAncestorWithRole(target, roles::MENUBAR); + Accessible* ARIAMenubar = nullptr; + Accessible* child = target; + Accessible* parent = child->Parent(); + while (parent) { + nsRoleMapEntry* roleMap = parent->ARIARoleMap(); + if (roleMap) { + if (roleMap->Is(nsGkAtoms::menubar)) { + ARIAMenubar = parent; + break; + } + + // Go up in the parent chain of the menu hierarchy. + if (roleMap->Is(nsGkAtoms::menuitem) || roleMap->Is(nsGkAtoms::menu)) { + child = parent; + parent = child->Parent(); + continue; + } + } + + // If no required context role then check aria-owns relation. + RelatedAccIterator iter(child->Document(), child->GetContent(), + nsGkAtoms::aria_owns); + parent = iter.Next(); + } if (ARIAMenubar != mActiveARIAMenubar) { // Leaving ARIA menu. Fire menu_end event on current menubar. diff --git a/accessible/src/base/nsAccUtils.cpp b/accessible/src/base/nsAccUtils.cpp index 3b1bf2447022..4dcc70b08afa 100644 --- a/accessible/src/base/nsAccUtils.cpp +++ b/accessible/src/base/nsAccUtils.cpp @@ -210,22 +210,6 @@ nsAccUtils::GetARIAToken(dom::Element* aElement, nsIAtom* aAttr) return nullptr; } -Accessible* -nsAccUtils::GetAncestorWithRole(Accessible* aDescendant, uint32_t aRole) -{ - Accessible* document = aDescendant->Document(); - Accessible* parent = aDescendant; - while ((parent = parent->Parent())) { - uint32_t testRole = parent->Role(); - if (testRole == aRole) - return parent; - - if (parent == document) - break; - } - return nullptr; -} - Accessible* nsAccUtils::GetSelectableContainer(Accessible* aAccessible, uint64_t aState) { diff --git a/accessible/src/base/nsAccUtils.h b/accessible/src/base/nsAccUtils.h index 2f09a4f88bdc..6b939d2d9ec5 100644 --- a/accessible/src/base/nsAccUtils.h +++ b/accessible/src/base/nsAccUtils.h @@ -116,17 +116,6 @@ public: return GetAccService()->GetDocAccessible(docShell->GetPresShell()); } - /** - * Return ancestor in this document with the given role if it exists. - * - * @param aDescendant [in] descendant to start search with - * @param aRole [in] role to find matching ancestor for - * @return the ancestor accessible with the given role, or - * nullptr if no match is found - */ - static Accessible* GetAncestorWithRole(Accessible* aDescendant, - uint32_t aRole); - /** * Return single or multi selectable container for the given item. * diff --git a/accessible/tests/mochitest/events/test_aria_menu.html b/accessible/tests/mochitest/events/test_aria_menu.html index a361a72013c9..0259c5f57b7a 100644 --- a/accessible/tests/mochitest/events/test_aria_menu.html +++ b/accessible/tests/mochitest/events/test_aria_menu.html @@ -165,6 +165,10 @@ gQueue.push(new focusInsideMenu("menu-edit", "menubar")); gQueue.push(new blurMenu("menubar")); + gQueue.push(new focusMenu("menubar3", "mb3-mi-outside")); + gQueue.push(new showMenu("mb4-menu", document, kViaDisplayStyle)); + gQueue.push(new focusMenu("menubar4", "mb4-item1")); + gQueue.invoke(); // Will call SimpleTest.finish(); } @@ -178,22 +182,27 @@ - Mozilla Bug 606207 + Bug 606207 - Mozilla Bug 614829 + Bug 614829 - Mozilla Bug 615189 + Bug 615189 - Mozilla Bug 673958 + Bug 673958 + + + Bug 933322

@@ -227,6 +236,18 @@
outsidemenu
+ + + + + + +
diff --git a/b2g/installer/Makefile.in b/b2g/installer/Makefile.in index ef39fb37953c..627c00bd512c 100644 --- a/b2g/installer/Makefile.in +++ b/b2g/installer/Makefile.in @@ -52,7 +52,7 @@ endif ifdef MOZ_PKG_MANIFEST_P $(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) FORCE - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $< > $@ + $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $< -o $@) ifdef MOZ_CHROME_MULTILOCALE printf "\n[multilocale]\n" >> $@ for LOCALE in $(MOZ_CHROME_MULTILOCALE) ;\ diff --git a/b2g/locales/Makefile.in b/b2g/locales/Makefile.in index 16ff711c18b1..c10090a9c19c 100644 --- a/b2g/locales/Makefile.in +++ b/b2g/locales/Makefile.in @@ -54,8 +54,8 @@ $(DIST)/branding: libs:: @if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \ - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \ - $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \ + $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \ + $(LOCALE_SRCDIR)/existing-profile-defaults.js -o $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \ fi NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD)) diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in index f495df5dd169..bf74c1e9dc01 100644 --- a/browser/app/Makefile.in +++ b/browser/app/Makefile.in @@ -144,7 +144,7 @@ ifndef LIBXUL_SDK # channel-prefs.js is handled separate from other prefs due to bug 756325 libs:: $(srcdir)/profile/channel-prefs.js $(NSINSTALL) -D $(DIST)/bin/defaults/pref - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(ACDEFINES) $^ > $(DIST)/bin/defaults/pref/channel-prefs.js + $(call py_action,preprocessor,$(PREF_PPFLAGS) $(ACDEFINES) $^ -o $(DIST)/bin/defaults/pref/channel-prefs.js) endif libs:: $(srcdir)/blocklist.xml diff --git a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml index 95744cf5ffd8..e86a5a3d5d5e 100644 --- a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml +++ b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml @@ -61,9 +61,6 @@ .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindow); - // Focus the location bar - mainWindow.focusAndSelectUrlBar(); - function setFavIcon(url) { var icon = document.createElement("link"); icon.setAttribute("rel", "icon"); diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in index bd4fc845b152..eb37d8c9dd24 100644 --- a/browser/installer/Makefile.in +++ b/browser/installer/Makefile.in @@ -79,7 +79,7 @@ ifdef MOZ_PKG_MANIFEST_P MOZ_PKG_MANIFEST = package-manifest $(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) $(GLOBAL_DEPS) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $< > $@ + $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $< -o $@) GARBAGE += $(MOZ_PKG_MANIFEST) endif diff --git a/browser/installer/windows/Makefile.in b/browser/installer/windows/Makefile.in index 001f8d659d7b..93b703282cff 100644 --- a/browser/installer/windows/Makefile.in +++ b/browser/installer/windows/Makefile.in @@ -71,8 +71,8 @@ uninstaller:: $(MKDIR) $(CONFIG_DIR) $(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR) $(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) \ - $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi + $(call py_action,preprocessor,-Fsubstitution $(DEFINES) $(ACDEFINES) \ + $(srcdir)/nsis/defines.nsi.in -o $(CONFIG_DIR)/defines.nsi) $(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \ --preprocess-locale $(topsrcdir) \ $(PPL_LOCALE_ARGS) $(AB_CD) $(CONFIG_DIR) @@ -81,8 +81,8 @@ uninstaller:: ifdef MOZ_MAINTENANCE_SERVICE maintenanceservice_installer:: $(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) \ - $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi + $(call py_action,preprocessor,-Fsubstitution $(DEFINES) $(ACDEFINES) \ + $(srcdir)/nsis/defines.nsi.in -o $(CONFIG_DIR)/defines.nsi) $(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \ --preprocess-locale $(topsrcdir) \ $(PPL_LOCALE_ARGS) $(AB_CD) $(CONFIG_DIR) @@ -93,8 +93,8 @@ $(CONFIG_DIR)/setup.exe:: $(MKDIR) $(CONFIG_DIR) $(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR) $(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) \ - $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi + $(call py_action,preprocessor,-Fsubstitution $(DEFINES) $(ACDEFINES) \ + $(srcdir)/nsis/defines.nsi.in -o $(CONFIG_DIR)/defines.nsi) $(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \ --preprocess-locale $(topsrcdir) \ $(PPL_LOCALE_ARGS) $(AB_CD) $(CONFIG_DIR) diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in index c6294145feb1..12af0b7df1be 100644 --- a/browser/locales/Makefile.in +++ b/browser/locales/Makefile.in @@ -105,12 +105,11 @@ PROFILE_CHROME = userChrome-example.css userContent-example.css NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD)) %/defaults/profile/bookmarks.html: bookmarks.inc generic/profile/bookmarks.html.in - $(SYSINSTALL) -D $(dir $@) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ + $(call py_action,preprocessor, \ -I $< \ -DAB_CD=$(NO_JA_JP_MAC_AB_CD) \ $(srcdir)/generic/profile/bookmarks.html.in \ - > $@ + -o $@) libs:: $(FINAL_TARGET)/defaults/profile/bookmarks.html ; diff --git a/browser/metro/Makefile.in b/browser/metro/Makefile.in index d24a53f55c1e..4aaeac6862d1 100644 --- a/browser/metro/Makefile.in +++ b/browser/metro/Makefile.in @@ -17,7 +17,7 @@ DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID) # 'application.ini' breaks firefox build config. So we use something different. metroapp.ini: metroapp.ini.in $(DEPTH)/config/buildid $(topsrcdir)/config/milestone.txt $(RM) "metroapp.ini" - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@ + $(call py_action,preprocessor,$(DEFINES) $< -o $@) libs:: metroapp.ini $(INSTALL) metroapp.ini $(FINAL_TARGET) diff --git a/browser/metro/locales/import/Makefile.in b/browser/metro/locales/import/Makefile.in index a0b68766f57a..821be825bf57 100644 --- a/browser/metro/locales/import/Makefile.in +++ b/browser/metro/locales/import/Makefile.in @@ -44,9 +44,9 @@ bookmarks-src = $(srcdir)/../generic/profile/bookmarks.json.in # processing of the jar file in the parent directory. bookmarks: bookmarks.inc @echo "Generating: $@" - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ + $(call py_action,preprocessor, \ -I $^ \ -DAB_CD=$(AB_CD) \ - $(bookmarks-src) > ../bookmarks.json + $(bookmarks-src) -o ../bookmarks.json) export:: bookmarks diff --git a/build/Makefile.in b/build/Makefile.in index 768e63da9450..bcf717eb1978 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -106,7 +106,7 @@ _LEAKTEST_FILES = \ $(NULL) leaktest.py: leaktest.py.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $^ > $@ + $(call py_action,preprocessor,$^ -o $@) chmod +x $@ GARBAGE += leaktest.py diff --git a/build/automation-build.mk b/build/automation-build.mk index 567059a9e0d0..1f998485e5f3 100644 --- a/build/automation-build.mk +++ b/build/automation-build.mk @@ -67,7 +67,7 @@ AUTOMATION_PPARGS += -DIS_ASAN=0 endif automation.py: $(MOZILLA_DIR)/build/automation.py.in $(MOZILLA_DIR)/build/automation-build.mk - $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@ + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< -o $@) GARBAGE += automation.py automation.pyc diff --git a/build/docs/preprocessor.rst b/build/docs/preprocessor.rst index 23a7766c8358..ab2d8ecf710d 100644 --- a/build/docs/preprocessor.rst +++ b/build/docs/preprocessor.rst @@ -6,7 +6,7 @@ Text Preprocessor The build system contains a text preprocessor similar to the C preprocessor, meant for processing files which have no built-in preprocessor such as XUL -and JavaScript documents. It is implemented at ``config/Preprocessor.py`` and +and JavaScript documents. It is implemented at ``python/mozbuild/mozbuild/preprocessor.py`` and is typically invoked via :ref:`jar_manifests`. While used to preprocess CSS files, the directives are changed to begin with diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index 63185dc446c6..4bf43b6d2917 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -489,7 +489,8 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx) csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL, fileName, scriptSample, - lineNum); + lineNum, + EmptyString()); } return evalOK; diff --git a/config/Expression.py b/config/Expression.py deleted file mode 100644 index 3e91ae46858c..000000000000 --- a/config/Expression.py +++ /dev/null @@ -1,241 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -""" -Parses and evaluates simple statements for Preprocessor: - -Expression currently supports the following grammar, whitespace is ignored: - -expression : - and_cond ( '||' expression ) ? ; -and_cond: - test ( '&&' and_cond ) ? ; -test: - unary ( ( '==' | '!=' ) unary ) ? ; -unary : - '!'? value ; -value : - [0-9]+ # integer - | 'defined(' \w+ ')' - | \w+ # string identifier or value; -""" - -import re - -class Expression: - def __init__(self, expression_string): - """ - Create a new expression with this string. - The expression will already be parsed into an Abstract Syntax Tree. - """ - self.content = expression_string - self.offset = 0 - self.__ignore_whitespace() - self.e = self.__get_logical_or() - if self.content: - raise Expression.ParseError, self - - def __get_logical_or(self): - """ - Production: and_cond ( '||' expression ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("logical_op") - # test - rv.append(self.__get_logical_and()) - self.__ignore_whitespace() - if self.content[:2] != '||': - # no logical op needed, short cut to our prime element - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_logical_or()) - self.__ignore_whitespace() - return rv - - def __get_logical_and(self): - """ - Production: test ( '&&' and_cond ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("logical_op") - # test - rv.append(self.__get_equality()) - self.__ignore_whitespace() - if self.content[:2] != '&&': - # no logical op needed, short cut to our prime element - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_logical_and()) - self.__ignore_whitespace() - return rv - - def __get_equality(self): - """ - Production: unary ( ( '==' | '!=' ) unary ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("equality") - # unary - rv.append(self.__get_unary()) - self.__ignore_whitespace() - if not re.match('[=!]=', self.content): - # no equality needed, short cut to our prime unary - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_unary()) - self.__ignore_whitespace() - return rv - - def __get_unary(self): - """ - Production: '!'? value - """ - # eat whitespace right away, too - not_ws = re.match('!\s*', self.content) - if not not_ws: - return self.__get_value() - rv = Expression.__AST('not') - self.__strip(not_ws.end()) - rv.append(self.__get_value()) - self.__ignore_whitespace() - return rv - - def __get_value(self): - """ - Production: ( [0-9]+ | 'defined(' \w+ ')' | \w+ ) - Note that the order is important, and the expression is kind-of - ambiguous as \w includes 0-9. One could make it unambiguous by - removing 0-9 from the first char of a string literal. - """ - rv = None - m = re.match('defined\s*\(\s*(\w+)\s*\)', self.content) - if m: - word_len = m.end() - rv = Expression.__ASTLeaf('defined', m.group(1)) - else: - word_len = re.match('[0-9]*', self.content).end() - if word_len: - value = int(self.content[:word_len]) - rv = Expression.__ASTLeaf('int', value) - else: - word_len = re.match('\w*', self.content).end() - if word_len: - rv = Expression.__ASTLeaf('string', self.content[:word_len]) - else: - raise Expression.ParseError, self - self.__strip(word_len) - self.__ignore_whitespace() - return rv - - def __ignore_whitespace(self): - ws_len = re.match('\s*', self.content).end() - self.__strip(ws_len) - return - - def __strip(self, length): - """ - Remove a given amount of chars from the input and update - the offset. - """ - self.content = self.content[length:] - self.offset += length - - def evaluate(self, context): - """ - Evaluate the expression with the given context - """ - - # Helper function to evaluate __get_equality results - def eval_equality(tok): - left = opmap[tok[0].type](tok[0]) - right = opmap[tok[2].type](tok[2]) - rv = left == right - if tok[1].value == '!=': - rv = not rv - return rv - # Helper function to evaluate __get_logical_and and __get_logical_or results - def eval_logical_op(tok): - left = opmap[tok[0].type](tok[0]) - right = opmap[tok[2].type](tok[2]) - if tok[1].value == '&&': - return left and right - elif tok[1].value == '||': - return left or right - raise Expression.ParseError, self - - # Mapping from token types to evaluator functions - # Apart from (non-)equality, all these can be simple lambda forms. - opmap = { - 'logical_op': eval_logical_op, - 'equality': eval_equality, - 'not': lambda tok: not opmap[tok[0].type](tok[0]), - 'string': lambda tok: context[tok.value], - 'defined': lambda tok: tok.value in context, - 'int': lambda tok: tok.value} - - return opmap[self.e.type](self.e); - - class __AST(list): - """ - Internal class implementing Abstract Syntax Tree nodes - """ - def __init__(self, type): - self.type = type - super(self.__class__, self).__init__(self) - - class __ASTLeaf: - """ - Internal class implementing Abstract Syntax Tree leafs - """ - def __init__(self, type, value): - self.value = value - self.type = type - def __str__(self): - return self.value.__str__() - def __repr__(self): - return self.value.__repr__() - - class ParseError(StandardError): - """ - Error raised when parsing fails. - It has two members, offset and content, which give the offset of the - error and the offending content. - """ - def __init__(self, expression): - self.offset = expression.offset - self.content = expression.content[:3] - def __str__(self): - return 'Unexpected content at offset {0}, "{1}"'.format(self.offset, - self.content) - -class Context(dict): - """ - This class holds variable values by subclassing dict, and while it - truthfully reports True and False on - - name in context - - it returns the variable name itself on - - context["name"] - - to reflect the ambiguity between string literals and preprocessor - variables. - """ - def __getitem__(self, key): - if key in self: - return super(self.__class__, self).__getitem__(key) - return key diff --git a/config/Makefile.in b/config/Makefile.in index 9ff0bd2252c5..74d477509956 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -74,7 +74,7 @@ export-preqs = \ $(NULL) export:: $(export-preqs) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \ + $(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) $(ACDEFINES) \ -DMOZ_TREE_CAIRO=$(MOZ_TREE_CAIRO) \ -DMOZ_TREE_PIXMAN=$(MOZ_TREE_PIXMAN) \ -DMOZ_NATIVE_HUNSPELL=$(MOZ_NATIVE_HUNSPELL) \ diff --git a/config/rules.mk b/config/rules.mk index 3728cf28c023..5415605a1dca 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -53,7 +53,7 @@ else REPORT_BUILD = $(info $(shell $(PYTHON) $(MOZILLA_DIR)/config/rebuild_check.py $@ $^)) endif else -REPORT_BUILD = $(info $(notdir $@)) +REPORT_BUILD = $(info $(if $(filter $(DEPTH)/%,$@),$(@:$(DEPTH)/%=%),$(notdir $@))) endif ifeq ($(OS_ARCH),OS2) @@ -1481,6 +1481,11 @@ endif # # Additionally, a FOO_TARGET variable may be added to indicate the target for # which the files and executables are installed. Default is "libs". +# +# Finally, a FOO_KEEP_PATH variable may be set to 1 to indicate the paths given +# in FOO_FILES/FOO_EXECUTABLES are to be kept at the destination. That is, +# if FOO_FILES is bar/baz/qux.h, and FOO_DEST is $(DIST)/include, the installed +# file would be $(DIST)/include/bar/baz/qux.h instead of $(DIST)/include/qux.h # If we're using binary nsinstall and it's not built yet, fallback to python nsinstall. ifneq (,$(filter $(CONFIG_TOOLS)/nsinstall$(HOST_BIN_SUFFIX),$(install_cmd))) @@ -1493,22 +1498,52 @@ endef endif endif -define install_file_template -$(or $(3),libs):: $(2)/$(notdir $(1)) -$(call install_cmd_override,$(2)/$(notdir $(1))) -$(2)/$(notdir $(1)): $(1) - $$(call install_cmd,$(4) "$$<" "$${@D}") +install_target_tier = $(or $($(1)_TARGET),libs) +INSTALL_TARGETS_TIERS := $(sort $(foreach category,$(INSTALL_TARGETS),$(call install_target_tier,$(category)))) + +install_target_result = $($(1)_DEST:%/=%)/$(if $($(1)_KEEP_PATH),$(2),$(notdir $(2))) +install_target_files = $(foreach file,$($(1)_FILES),$(call install_target_result,$(category),$(file))) +install_target_executables = $(foreach file,$($(1)_EXECUTABLES),$(call install_target_result,$(category),$(file))) + +# Work around a GNU make 3.81 bug where it gives $< the wrong value. +# See details in bug 934864. +define create_dependency +$(1): $(2) +$(1): $(2) endef + +define install_target_template +$(call install_cmd_override,$(2)) +$(call create_dependency,$(2),$(1)) +endef + $(foreach category,$(INSTALL_TARGETS),\ - $(if $($(category)_DEST),,$(error Missing $(category)_DEST))\ - $(foreach file,$($(category)_FILES),\ - $(eval $(call install_file_template,$(file),$($(category)_DEST),$($(category)_TARGET),$(IFLAGS1)))\ - )\ - $(foreach file,$($(category)_EXECUTABLES),\ - $(eval $(call install_file_template,$(file),$($(category)_DEST),$($(category)_TARGET),$(IFLAGS2)))\ - )\ + $(if $($(category)_DEST),,$(error Missing $(category)_DEST)) \ + $(foreach tier,$(call install_target_tier,$(category)),\ + $(eval INSTALL_TARGETS_FILES_$(tier) += $(call install_target_files,$(category))) \ + $(eval INSTALL_TARGETS_EXECUTABLES_$(tier) += $(call install_target_executables,$(category))) \ + ) \ + $(foreach file,$($(category)_FILES) $($(category)_EXECUTABLES), \ + $(eval $(call install_target_template,$(file),$(call install_target_result,$(category),$(file)))) \ + ) \ ) +$(foreach tier,$(INSTALL_TARGETS_TIERS), \ + $(eval $(tier):: $(INSTALL_TARGETS_FILES_$(tier)) $(INSTALL_TARGETS_EXECUTABLES_$(tier))) \ +) + +install_targets_sanity = $(if $(filter-out $(notdir $@),$(notdir $(<))),$(error Looks like $@ has an unexpected dependency on $< which breaks INSTALL_TARGETS)) + +$(sort $(foreach tier,$(INSTALL_TARGETS_TIERS),$(INSTALL_TARGETS_FILES_$(tier)))): + $(install_targets_sanity) + $(REPORT_BUILD) + $(call install_cmd,$(IFLAGS1) "$<" "$(@D)") + +$(sort $(foreach tier,$(INSTALL_TARGETS_TIERS),$(INSTALL_TARGETS_EXECUTABLES_$(tier)))): + $(install_targets_sanity) + $(REPORT_BUILD) + $(call install_cmd,$(IFLAGS2) "$<" "$(@D)") + ################################################################################ # Preprocessing rules # @@ -1524,40 +1559,80 @@ $(foreach category,$(INSTALL_TARGETS),\ # If PP_TARGETS lists a category name (like FOO, above), then we consult the # following make variables to see what to do: # -# - lists input files to be preprocessed with config/Preprocessor.py. We -# search VPATH for the names given here. If an input file name ends in '.in', -# that suffix is omitted from the output file name. +# - lists input files to be preprocessed with mozbuild.action.preprocessor. +# We search VPATH for the names given here. If an input file name ends in +# '.in', that suffix is omitted from the output file name. # # - _PATH names the directory in which to place the preprocessed output # files. We create this directory if it does not already exist. Setting # this variable is optional; if unset, we install the files in $(CURDIR). # -# - _FLAGS lists flags to pass to Preprocessor.py, in addition to the usual -# bunch. Setting this variable is optional. +# - _FLAGS lists flags to pass to mozbuild.action.preprocessor, in addition +# to the usual bunch. Setting this variable is optional. # # - _TARGET names the 'make' target that should depend on creating the output # files. Setting this variable is optional; if unset, we preprocess the # files for the 'libs' target. +# +# - _KEEP_PATH may be set to 1 to indicate the paths given in are to be +# kept under _PATH. That is, if is bar/baz/qux.h.in and _PATH is +# $(DIST)/include, the preprocessed file would be $(DIST)/include/bar/baz/qux.h +# instead of $(DIST)/include/qux.h. -# preprocess_file_template defines preprocessing rules. -# $(call preprocess_file_template, source_file, output_file, -# makefile_target, extra_flags) -define preprocess_file_template -$(2): $(1) $$(GLOBAL_DEPS) - $$(RM) "$$@" - $$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(4) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) "$$<" -o "$$@" -$(3):: $(2) -endef +pp_target_tier = $(or $($(1)_TARGET),libs) +PP_TARGETS_TIERS := $(sort $(foreach category,$(PP_TARGETS),$(call pp_target_tier,$(category)))) -$(foreach category,$(PP_TARGETS), \ - $(foreach file,$($(category)), \ - $(eval $(call preprocess_file_template, \ - $(file), \ - $(or $($(category)_PATH),$(CURDIR))/$(notdir $(file:.in=)), \ - $(or $($(category)_TARGET),libs), \ - $($(category)_FLAGS))) \ - ) \ - ) +pp_target_result = $(or $($(1)_PATH:%/=%),$(CURDIR))/$(if $($(1)_KEEP_PATH),$(2:.in=),$(notdir $(2:.in=))) +pp_target_results = $(foreach file,$($(1)),$(call pp_target_result,$(category),$(file))) + +$(foreach category,$(PP_TARGETS), \ + $(foreach tier,$(call pp_target_tier,$(category)), \ + $(eval PP_TARGETS_RESULTS_$(tier) += $(call pp_target_results,$(category))) \ + ) \ + $(foreach file,$($(category)), \ + $(eval $(call create_dependency,$(call pp_target_result,$(category),$(file)), \ + $(file) $(GLOBAL_DEPS))) \ + ) \ + $(eval $(call pp_target_results,$(category)): PP_TARGET_FLAGS=$($(category)_FLAGS)) \ +) + +$(foreach tier,$(PP_TARGETS_TIERS), \ + $(eval $(tier):: $(PP_TARGETS_RESULTS_$(tier))) \ +) + +PP_TARGETS_ALL_RESULTS := $(sort $(foreach tier,$(PP_TARGETS_TIERS),$(PP_TARGETS_RESULTS_$(tier)))) +$(PP_TARGETS_ALL_RESULTS): + $(if $(filter-out $(notdir $@),$(notdir $(<:.in=))),$(error Looks like $@ has an unexpected dependency on $< which breaks PP_TARGETS)) + $(REPORT_BUILD) + $(RM) "$@" + $(call py_action,preprocessor,--depend $(MDDEPDIR)/$(@F).pp $(PP_TARGET_FLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) "$<" -o "$@") + +# The depfile is based on the filename, and we don't want conflicts. So check +# there's only one occurrence of any given filename in PP_TARGETS_ALL_RESULTS. +PP_TARGETS_ALL_RESULT_NAMES := $(notdir $(PP_TARGETS_ALL_RESULTS)) +$(foreach file,$(sort $(PP_TARGETS_ALL_RESULT_NAMES)), \ + $(if $(filter-out 1,$(words $(filter $(file),$(PP_TARGETS_ALL_RESULT_NAMES)))), \ + $(error Multiple preprocessing rules are creating a $(file) file) \ + ) \ +) + +ifneq (,$(filter $(PP_TARGETS_TIERS) $(PP_TARGETS_ALL_RESULTS),$(MAKECMDGOALS))) +# If the depfile for a preprocessed file doesn't exist, add a dep to force +# re-preprocessing. +$(foreach file,$(PP_TARGETS_ALL_RESULTS), \ + $(if $(wildcard $(MDDEPDIR)/$(notdir $(file)).pp), \ + , \ + $(eval $(file): FORCE) \ + ) \ +) + +MDDEPEND_FILES := $(strip $(wildcard $(addprefix $(MDDEPDIR)/,$(addsuffix .pp,$(notdir $(PP_TARGETS_ALL_RESULTS)))))) + +ifneq (,$(MDDEPEND_FILES)) +$(call include_deps,$(MDDEPEND_FILES)) +endif + +endif # Pull in non-recursive targets if this is a partial tree build. ifndef TOPLEVEL_BUILD diff --git a/configure.in b/configure.in index 2f17bbafc445..9f03b613dffb 100644 --- a/configure.in +++ b/configure.in @@ -3557,7 +3557,7 @@ MOZ_ARG_WITH_BOOL(system-nspr, _USE_SYSTEM_NSPR=1 ) if test -n "$_USE_SYSTEM_NSPR"; then - AM_PATH_NSPR(4.9.6, [MOZ_NATIVE_NSPR=1], [AC_MSG_ERROR([your don't have NSPR installed or your version is too old])]) + AM_PATH_NSPR(4.10.2, [MOZ_NATIVE_NSPR=1], [AC_MSG_ERROR([your don't have NSPR installed or your version is too old])]) fi if test -n "$MOZ_NATIVE_NSPR"; then @@ -3668,7 +3668,7 @@ MOZ_ARG_WITH_BOOL(system-nss, _USE_SYSTEM_NSS=1 ) if test -n "$_USE_SYSTEM_NSS"; then - AM_PATH_NSS(3.15.3, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) + AM_PATH_NSS(3.15.4, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) fi if test -n "$MOZ_NATIVE_NSS"; then diff --git a/content/base/public/nsIContentSecurityPolicy.idl b/content/base/public/nsIContentSecurityPolicy.idl index 0c4259e09b98..c353efc00453 100644 --- a/content/base/public/nsIContentSecurityPolicy.idl +++ b/content/base/public/nsIContentSecurityPolicy.idl @@ -15,7 +15,7 @@ interface nsIDocShell; * one of these per document/principal. */ -[scriptable, uuid(e5020ec3-1437-46f5-b4eb-8b60766d02c0)] +[scriptable, uuid(781b6511-f1fa-4e2c-8eff-1739d091eb2f)] interface nsIContentSecurityPolicy : nsISupports { @@ -104,6 +104,24 @@ interface nsIContentSecurityPolicy : nsISupports */ boolean getAllowsInlineStyle(out boolean shouldReportViolations); + /** + * Whether this policy accepts the given nonce + * @param aNonce + * The nonce string to check against the policy + * @param aContentType + * The type of element on which we encountered this nonce + * @param shouldReportViolation + * Whether or not the use of an incorrect nonce should be reported. + * This function always returns "true" for report-only policies, but when + * the report-only policy is violated, shouldReportViolation is true as + * well. + * @return + * Whether or not this nonce is valid + */ + boolean getAllowsNonce(in AString aNonce, + in unsigned long aContentType, + out boolean shouldReportViolation); + /** * For each violated policy (of type violationType), log policy violation on * the Error Console and send a report to report-uris present in the violated @@ -117,15 +135,22 @@ interface nsIContentSecurityPolicy : nsISupports * sample of the violating content (to aid debugging) * @param lineNum * source line number of the violation (if available) + * @param aNonce + * (optional) If this is a nonce violation, include the nonce so we can + * recheck to determine which policies were violated and send the + * appropriate reports. */ void logViolationDetails(in unsigned short violationType, in AString sourceFile, in AString scriptSample, - in int32_t lineNum); + in int32_t lineNum, + [optional] in AString nonce); const unsigned short VIOLATION_TYPE_INLINE_SCRIPT = 1; - const unsigned short VIOLATION_TYPE_EVAL = 2; - const unsigned short VIOLATION_TYPE_INLINE_STYLE = 3; + const unsigned short VIOLATION_TYPE_EVAL = 2; + const unsigned short VIOLATION_TYPE_INLINE_STYLE = 3; + const unsigned short VIOLATION_TYPE_NONCE_SCRIPT = 4; + const unsigned short VIOLATION_TYPE_NONCE_STYLE = 5; /** * Called after the CSP object is created to fill in the appropriate request diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index dfa6afdd1e12..f0e579723d73 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -2171,6 +2171,9 @@ public: virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; } + virtual JSObject* WrapObject(JSContext *aCx, + JS::Handle aScope) MOZ_OVERRIDE; + private: uint64_t mWarnedAbout; SelectorCache mSelectorCache; diff --git a/content/base/src/CSPUtils.jsm b/content/base/src/CSPUtils.jsm index a9898f8a3264..35c9761a0e88 100644 --- a/content/base/src/CSPUtils.jsm +++ b/content/base/src/CSPUtils.jsm @@ -24,7 +24,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Services", // Module stuff this.EXPORTED_SYMBOLS = ["CSPRep", "CSPSourceList", "CSPSource", "CSPHost", - "CSPdebug", "CSPViolationReportListener", "CSPLocalizer"]; + "CSPdebug", "CSPViolationReportListener", "CSPLocalizer", + "CSPPrefObserver"]; var STRINGS_URI = "chrome://global/locale/security/csp.properties"; @@ -65,25 +66,37 @@ const R_EXTHOSTSRC = new RegExp ("^" + R_HOSTSRC.source + "\\/[:print:]+$", 'i') // keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'" const R_KEYWORDSRC = new RegExp ("^('self'|'unsafe-inline'|'unsafe-eval')$", 'i'); +// nonce-source = "'nonce-" nonce-value "'" +// nonce-value = 1*( ALPHA / DIGIT / "+" / "/" ) +const R_NONCESRC = new RegExp ("^'nonce-([a-zA-Z0-9\+\/]+)'$", 'i'); + // source-exp = scheme-source / host-source / keyword-source const R_SOURCEEXP = new RegExp (R_SCHEMESRC.source + "|" + R_HOSTSRC.source + "|" + - R_KEYWORDSRC.source, 'i'); + R_KEYWORDSRC.source + "|" + + R_NONCESRC.source, 'i'); -var gPrefObserver = { +this.CSPPrefObserver = { get debugEnabled () { if (!this._branch) this._initialize(); return this._debugEnabled; }, + get experimentalEnabled () { + if (!this._branch) + this._initialize(); + return this._experimentalEnabled; + }, + _initialize: function() { var prefSvc = Components.classes["@mozilla.org/preferences-service;1"] .getService(Ci.nsIPrefService); this._branch = prefSvc.getBranch("security.csp."); this._branch.addObserver("", this, false); this._debugEnabled = this._branch.getBoolPref("debug"); + this._experimentalEnabled = this._branch.getBoolPref("experimentalEnabled"); }, unregister: function() { @@ -95,11 +108,13 @@ var gPrefObserver = { if (aTopic != "nsPref:changed") return; if (aData === "debug") this._debugEnabled = this._branch.getBoolPref("debug"); + if (aData === "experimentalEnabled") + this._experimentalEnabled = this._branch.getBoolPref("experimentalEnabled"); }, }; this.CSPdebug = function CSPdebug(aMsg) { - if (!gPrefObserver.debugEnabled) return; + if (!CSPPrefObserver.debugEnabled) return; aMsg = 'CSP debug: ' + aMsg + "\n"; Components.classes["@mozilla.org/consoleservice;1"] @@ -793,14 +808,28 @@ CSPRep.prototype = { /** * Determines if this policy accepts a URI. - * @param aContext + * @param aURI + * URI of the requested resource + * @param aDirective * one of the SRC_DIRECTIVES defined above + * @param aContext + * Context of the resource being requested. This is a type inheriting + * from nsIDOMHTMLElement if this is called from shouldLoad to check + * an external resource load, and refers to the HTML element that is + * causing the resource load. Otherwise, it is a string containing + * a nonce from a nonce="" attribute if it is called from + * getAllowsNonce. * @returns * true if the policy permits the URI in given context. */ permits: - function csp_permits(aURI, aContext) { - if (!aURI) return false; + function csp_permits(aURI, aDirective, aContext) { + // In the case where permits is called from getAllowsNonce (for an inline + // element), aURI is null and aContext has a specific value. Otherwise, + // calling permits without aURI is invalid. + let checking_nonce = aContext instanceof Ci.nsIDOMHTMLElement || + typeof aContext === 'string'; + if (!aURI && !checking_nonce) return false; // GLOBALLY ALLOW "about:" SCHEME if (aURI instanceof String && aURI.substring(0,6) === "about:") @@ -811,13 +840,13 @@ CSPRep.prototype = { // make sure the right directive set is used let DIRS = this._specCompliant ? CSPRep.SRC_DIRECTIVES_NEW : CSPRep.SRC_DIRECTIVES_OLD; - let contextIsSrcDir = false; + let directiveInPolicy = false; for (var i in DIRS) { - if (DIRS[i] === aContext) { + if (DIRS[i] === aDirective) { // for catching calls with invalid contexts (below) - contextIsSrcDir = true; - if (this._directives.hasOwnProperty(aContext)) { - return this._directives[aContext].permits(aURI); + directiveInPolicy = true; + if (this._directives.hasOwnProperty(aDirective)) { + return this._directives[aDirective].permits(aURI, aContext); } //found matching dir, can stop looking break; @@ -825,15 +854,15 @@ CSPRep.prototype = { } // frame-ancestors is a special case; it doesn't fall back to default-src. - if (aContext === DIRS.FRAME_ANCESTORS) + if (aDirective === DIRS.FRAME_ANCESTORS) return true; // All directives that don't fall back to default-src should have an escape // hatch above (like frame-ancestors). - if (!contextIsSrcDir) { + if (!directiveInPolicy) { // if this code runs, there's probably something calling permits() that // shouldn't be calling permits(). - CSPdebug("permits called with invalid load type: " + aContext); + CSPdebug("permits called with invalid load type: " + aDirective); return false; } @@ -842,7 +871,7 @@ CSPRep.prototype = { // indicates no relevant directives were present and the load should be // permitted). if (this._directives.hasOwnProperty(DIRS.DEFAULT_SRC)) { - return this._directives[DIRS.DEFAULT_SRC].permits(aURI); + return this._directives[DIRS.DEFAULT_SRC].permits(aURI, aContext); } // no relevant directives present -- this means for CSP 1.0 that the load @@ -1081,12 +1110,12 @@ CSPSourceList.prototype = { * true if the URI matches a source in this source list. */ permits: - function cspsd_permits(aURI) { + function cspsd_permits(aURI, aContext) { if (this.isNone()) return false; if (this.isAll()) return true; for (var i in this._sources) { - if (this._sources[i].permits(aURI)) { + if (this._sources[i].permits(aURI, aContext)) { return true; } } @@ -1102,6 +1131,7 @@ this.CSPSource = function CSPSource() { this._scheme = undefined; this._port = undefined; this._host = undefined; + this._nonce = undefined; //when set to true, this allows all source this._permitAll = false; @@ -1346,6 +1376,19 @@ CSPSource.fromString = function(aStr, aCSPRep, self, enforceSelfChecks) { return sObj; } + // check for a nonce-source match + if (R_NONCESRC.test(aStr)) { + // We can't put this check outside of the regex test because R_NONCESRC is + // included in R_SOURCEEXP, which is const. By testing here, we can + // explicitly return null for nonces if experimental is not enabled, + // instead of letting it fall through and assuming it won't accidentally + // match something later in this function. + if (!CSPPrefObserver.experimentalEnabled) return null; + var nonceSrcMatch = R_NONCESRC.exec(aStr); + sObj._nonce = nonceSrcMatch[1]; + return sObj; + } + // check for 'self' (case insensitive) if (aStr.toUpperCase() === "'SELF'") { if (!self) { @@ -1450,6 +1493,8 @@ CSPSource.prototype = { s = s + this._host; if (this.port) s = s + ":" + this.port; + if (this._nonce) + s = s + "'nonce-" + this._nonce + "'"; return s; }, @@ -1465,6 +1510,7 @@ CSPSource.prototype = { aClone._scheme = this._scheme; aClone._port = this._port; aClone._host = this._host ? this._host.clone() : undefined; + aClone._nonce = this._nonce; aClone._isSelf = this._isSelf; aClone._CSPRep = this._CSPRep; return aClone; @@ -1474,11 +1520,24 @@ CSPSource.prototype = { * Determines if this Source accepts a URI. * @param aSource * the URI, or CSPSource in question + * @param aContext + * the context of the resource being loaded * @returns * true if the URI matches a source in this source list. */ permits: - function(aSource) { + function(aSource, aContext) { + if (this._nonce && CSPPrefObserver.experimentalEnabled) { + if (aContext instanceof Ci.nsIDOMHTMLElement) { + return this._nonce === aContext.getAttribute('nonce'); + } else if (typeof aContext === 'string') { + return this._nonce === aContext; + } + } + // We only use aContext for nonce checks. If it's otherwise provided, + // ignore it. + if (!CSPPrefObserver.experimentalEnabled && aContext) return false; + if (!aSource) return false; if (!(aSource instanceof CSPSource)) diff --git a/content/base/src/contentSecurityPolicy.js b/content/base/src/contentSecurityPolicy.js index 06cf4b69beca..f5be9abe93c7 100644 --- a/content/base/src/contentSecurityPolicy.js +++ b/content/base/src/contentSecurityPolicy.js @@ -31,6 +31,8 @@ const ERROR_FLAG = Ci.nsIScriptError.ERROR_FLAG; const INLINE_STYLE_VIOLATION_OBSERVER_SUBJECT = 'violated base restriction: Inline Stylesheets will not apply'; const INLINE_SCRIPT_VIOLATION_OBSERVER_SUBJECT = 'violated base restriction: Inline Scripts will not execute'; const EVAL_VIOLATION_OBSERVER_SUBJECT = 'violated base restriction: Code will not be created from strings'; +const SCRIPT_NONCE_VIOLATION_OBSERVER_SUBJECT = 'Inline Script had invalid nonce' +const STYLE_NONCE_VIOLATION_OBSERVER_SUBJECT = 'Inline Style had invalid nonce' // The cutoff length of content location in creating CSP cache key. const CSP_CACHE_URI_CUTOFF_SIZE = 512; @@ -189,6 +191,28 @@ ContentSecurityPolicy.prototype = { }); }, + getAllowsNonce: function(aNonce, aContentType, shouldReportViolation) { + if (!CSPPrefObserver.experimentalEnabled) + return false; + + if (!(aContentType == Ci.nsIContentPolicy.TYPE_SCRIPT || + aContentType == Ci.nsIContentPolicy.TYPE_STYLESHEET)) { + CSPdebug("Nonce check requested for an invalid content type (not script or style): " + aContentType); + return false; + } + let ct = ContentSecurityPolicy._MAPPINGS[aContentType]; + + // allow it to execute? + let policyAllowsNonce = [ policy.permits(null, ct, aNonce) for (policy of this._policies) ]; + + shouldReportViolation.value = policyAllowsNonce.some(function(a) { return !a; }); + + // allow it to execute? (Do all the policies allow it to execute)? + return this._policies.every(function(policy, i) { + return policy._reportOnlyMode || policyAllowsNonce[i]; + }); + }, + /** * For each policy, log any violation on the Error Console and send a report * if a report-uri is present in the policy @@ -201,9 +225,13 @@ ContentSecurityPolicy.prototype = { * sample of the violating content (to aid debugging) * @param aLineNum * source line number of the violation (if available) + * @param aNonce + * (optional) If this is a nonce violation, include the nonce should we + * can recheck to determine which policies were violated and send the + * appropriate reports. */ logViolationDetails: - function(aViolationType, aSourceFile, aScriptSample, aLineNum, violatedPolicyIndex) { + function(aViolationType, aSourceFile, aScriptSample, aLineNum, aNonce) { for (let policyIndex=0; policyIndex < this._policies.length; policyIndex++) { let policy = this._policies[policyIndex]; @@ -237,6 +265,24 @@ ContentSecurityPolicy.prototype = { aSourceFile, aScriptSample, aLineNum); } break; + case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_NONCE_SCRIPT: + let scriptType = ContentSecurityPolicy._MAPPINGS[Ci.nsIContentPolicy.TYPE_SCRIPT]; + if (!policy.permits(null, scriptType, aNonce)) { + var violatedDirective = this._buildViolatedDirectiveString('SCRIPT_SRC', policy); + this._asyncReportViolation('self', null, violatedDirective, policyIndex, + SCRIPT_NONCE_VIOLATION_OBSERVER_SUBJECT, + aSourceFile, aScriptSample, aLineNum); + } + break; + case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_NONCE_STYLE: + let styleType = ContentSecurityPolicy._MAPPINGS[Ci.nsIContentPolicy.TYPE_STYLE]; + if (!policy.permits(null, styleType, aNonce)) { + var violatedDirective = this._buildViolatedDirectiveString('STYLE_SRC', policy); + this._asyncReportViolation('self', null, violatedDirective, policyIndex, + STYLE_NONCE_VIOLATION_OBSERVER_SUBJECT, + aSourceFile, aScriptSample, aLineNum); + } + break; } } }, @@ -628,6 +674,14 @@ ContentSecurityPolicy.prototype = { let cp = Ci.nsIContentPolicy; + // Infer if this is a preload for elements that use nonce-source. Since, + // for preloads, aContext is the document and not the element associated + // with the resource, we cannot determine the nonce. See Bug 612921 and + // Bug 855326. + var possiblePreloadNonceConflict = + (aContentType == cp.TYPE_SCRIPT || aContentType == cp.TYPE_STYLESHEET) && + aContext instanceof Ci.nsIDOMHTMLDocument; + // iterate through all the _policies and send reports where a policy is // violated. After the check, determine the overall effect (blocked or // loaded?) and cache it. @@ -661,15 +715,18 @@ ContentSecurityPolicy.prototype = { // otherwise, honor the translation // var source = aContentLocation.scheme + "://" + aContentLocation.hostPort; - var res = policy.permits(aContentLocation, cspContext) - ? cp.ACCEPT : cp.REJECT_SERVER; + let context = CSPPrefObserver.experimentalEnabled ? aContext : null; + var res = policy.permits(aContentLocation, cspContext, context) ? + cp.ACCEPT : cp.REJECT_SERVER; // record whether the thing should be blocked or just reported. policyAllowsLoadArray.push(res == cp.ACCEPT || policy._reportOnlyMode); // frame-ancestors is taken care of early on (as this document is loaded) // If the result is *NOT* ACCEPT, then send report - if (res != Ci.nsIContentPolicy.ACCEPT) { + // Do not send report if this is a nonce-source preload - the decision may + // be wrong and will incorrectly fail the unit tests. + if (res != Ci.nsIContentPolicy.ACCEPT && !possiblePreloadNonceConflict) { CSPdebug("blocking request for " + aContentLocation.asciiSpec); try { let directive = "unknown directive", @@ -704,7 +761,8 @@ ContentSecurityPolicy.prototype = { let ret = (policyAllowsLoadArray.some(function(a,b) { return !a; }) ? cp.REJECT_SERVER : cp.ACCEPT); - if (key) { + // Do not cache the result if this is a nonce-source preload + if (key && !possiblePreloadNonceConflict) { this._cache[key] = ret; } return ret; diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index d4e7f1e0d9dc..6a4d68ff9369 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -11329,6 +11329,57 @@ nsDocument::Evaluate(const nsAString& aExpression, nsIDOMNode* aContextNode, aInResult, aResult); } +// This is just a hack around the fact that window.document is not +// [Unforgeable] yet. +JSObject* +nsIDocument::WrapObject(JSContext *aCx, JS::Handle aScope) +{ + MOZ_ASSERT(IsDOMBinding()); + + JS::Rooted obj(aCx, nsINode::WrapObject(aCx, aScope)); + if (!obj) { + return nullptr; + } + + nsCOMPtr win = do_QueryInterface(GetInnerWindow()); + if (!win) { + // No window, nothing else to do here + return obj; + } + + if (this != win->GetExtantDoc()) { + // We're not the current document; we're also done here + return obj; + } + + JSAutoCompartment ac(aCx, obj); + + JS::Rooted winVal(aCx); + nsCOMPtr holder; + nsresult rv = nsContentUtils::WrapNative(aCx, obj, win, + &NS_GET_IID(nsIDOMWindow), + &winVal, + getter_AddRefs(holder), + false); + if (NS_FAILED(rv)) { + Throw(aCx, rv); + return nullptr; + } + + NS_NAMED_LITERAL_STRING(doc_str, "document"); + + if (!JS_DefineUCProperty(aCx, JSVAL_TO_OBJECT(winVal), + reinterpret_cast + (doc_str.get()), + doc_str.Length(), JS::ObjectValue(*obj), + JS_PropertyStub, JS_StrictPropertyStub, + JSPROP_READONLY | JSPROP_ENUMERATE)) { + return nullptr; + } + + return obj; +} + XPathEvaluator* nsIDocument::XPathEvaluator() { diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index ad96f8ccfc42..b8f1eb7f9055 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -608,6 +608,7 @@ GK_ATOM(nodeSet, "node-set") GK_ATOM(noembed, "noembed") GK_ATOM(noframes, "noframes") GK_ATOM(nohref, "nohref") +GK_ATOM(nonce, "nonce") GK_ATOM(none, "none") GK_ATOM(noresize, "noresize") GK_ATOM(normal, "normal") diff --git a/content/base/src/nsNodeInfoManager.cpp b/content/base/src/nsNodeInfoManager.cpp index 9638cf546441..ea7bf5104393 100644 --- a/content/base/src/nsNodeInfoManager.cpp +++ b/content/base/src/nsNodeInfoManager.cpp @@ -47,13 +47,7 @@ nsNodeInfoManager::GetNodeInfoInnerHashValue(const void *key) const nsINodeInfo::nsNodeInfoInner *node = reinterpret_cast(key); - if (node->mName) { - // Ideally, we'd return node->mName->hash() here. But that doesn't work at - // the moment because node->mName->hash() is not the same as - // HashString(*(node->mNameString)). See bug 732815. - return HashString(nsDependentAtomString(node->mName)); - } - return HashString(*(node->mNameString)); + return node->mName ? node->mName->hash() : HashString(*(node->mNameString)); } diff --git a/content/base/src/nsScriptLoader.cpp b/content/base/src/nsScriptLoader.cpp index 3b26af68f12e..4d92be0b33bf 100644 --- a/content/base/src/nsScriptLoader.cpp +++ b/content/base/src/nsScriptLoader.cpp @@ -624,13 +624,31 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) NS_ENSURE_SUCCESS(rv, false); if (csp) { - PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("New ScriptLoader i ****with CSP****")); - bool inlineOK = true; - bool reportViolations = false; - rv = csp->GetAllowsInlineScript(&reportViolations, &inlineOK); + PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("New ScriptLoader ****with CSP****")); + + bool reportViolation = false; + bool allowInlineScript = true; + rv = csp->GetAllowsInlineScript(&reportViolation, &allowInlineScript); NS_ENSURE_SUCCESS(rv, false); - if (reportViolations) { + bool foundNonce = false; + nsAutoString nonce; + if (!allowInlineScript) { + foundNonce = scriptContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce); + if (foundNonce) { + // We can overwrite the outparams from GetAllowsInlineScript because + // if the nonce is correct, then we don't want to report the original + // inline violation (it has been whitelisted by the nonce), and if + // the nonce is incorrect, then we want to return just the specific + // "nonce violation" rather than both a "nonce violation" and + // a generic "inline violation". + rv = csp->GetAllowsNonce(nonce, nsIContentPolicy::TYPE_SCRIPT, + &reportViolation, &allowInlineScript); + NS_ENSURE_SUCCESS(rv, false); + } + } + + if (reportViolation) { // gather information to log with violation report nsIURI* uri = mDocument->GetDocumentURI(); nsAutoCString asciiSpec; @@ -641,17 +659,21 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) // cap the length of the script sample at 40 chars if (scriptText.Length() > 40) { scriptText.Truncate(40); - scriptText.Append(NS_LITERAL_STRING("...")); + scriptText.AppendLiteral("..."); } - csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT, - NS_ConvertUTF8toUTF16(asciiSpec), - scriptText, - aElement->GetScriptLineNumber()); + // The type of violation to report is determined by whether there was + // a nonce present. + unsigned short violationType = foundNonce ? + nsIContentSecurityPolicy::VIOLATION_TYPE_NONCE_SCRIPT : + nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT; + csp->LogViolationDetails(violationType, NS_ConvertUTF8toUTF16(asciiSpec), + scriptText, aElement->GetScriptLineNumber(), nonce); } - if (!inlineOK) { - PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP blocked inline scripts (2)")); + if (!allowInlineScript) { + NS_ASSERTION(reportViolation, + "CSP blocked inline script but is not reporting a violation"); return false; } } diff --git a/content/base/src/nsStyleLinkElement.cpp b/content/base/src/nsStyleLinkElement.cpp index 808f6124385c..b560237840db 100644 --- a/content/base/src/nsStyleLinkElement.cpp +++ b/content/base/src/nsStyleLinkElement.cpp @@ -360,7 +360,10 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument *aOldDocument, nsAutoString text; nsContentUtils::GetNodeTextContent(thisContent, false, text); - if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent->NodePrincipal(), + MOZ_ASSERT(thisContent->Tag() != nsGkAtoms::link, + " is not 'inline', and needs different CSP checks"); + if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent, + thisContent->NodePrincipal(), doc->GetDocumentURI(), mLineNumber, text, &rv)) return rv; diff --git a/content/base/src/nsStyledElement.cpp b/content/base/src/nsStyledElement.cpp index a60887185a57..5b5c91fc73e5 100644 --- a/content/base/src/nsStyledElement.cpp +++ b/content/base/src/nsStyledElement.cpp @@ -236,7 +236,7 @@ nsStyledElementNotElementCSSInlineStyle::ParseStyleAttribute(const nsAString& aV { nsIDocument* doc = OwnerDoc(); - if (!nsStyleUtil::CSPAllowsInlineStyle(NodePrincipal(), + if (!nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(), doc->GetDocumentURI(), 0, aValue, nullptr)) return; diff --git a/content/base/test/csp/file_nonce_source.html b/content/base/test/csp/file_nonce_source.html new file mode 100644 index 000000000000..e146467448ce --- /dev/null +++ b/content/base/test/csp/file_nonce_source.html @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
  1. + (inline style with correct nonce) This text should be green +
  2. +
  3. + (inline style with incorrect nonce) This text should be black +
  4. +
  5. + (inline style with correct script, not style, nonce) This text should be black +
  6. +
  7. + (inline style with no nonce) This text should be black +
  8. +
+ + + + + + diff --git a/content/base/test/csp/file_nonce_source.html^headers^ b/content/base/test/csp/file_nonce_source.html^headers^ new file mode 100644 index 000000000000..865e5fe98439 --- /dev/null +++ b/content/base/test/csp/file_nonce_source.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: script-src 'self' 'nonce-correctscriptnonce' 'nonce-anothercorrectscriptnonce'; style-src 'nonce-correctstylenonce'; +Cache-Control: no-cache diff --git a/content/base/test/csp/mochitest.ini b/content/base/test/csp/mochitest.ini index b0634e0c3afd..42b7767a1b7a 100644 --- a/content/base/test/csp/mochitest.ini +++ b/content/base/test/csp/mochitest.ini @@ -85,6 +85,8 @@ support-files = file_policyuri_regression_from_multipolicy.html file_policyuri_regression_from_multipolicy.html^headers^ file_policyuri_regression_from_multipolicy_policy + file_nonce_source.html + file_nonce_source.html^headers^ [test_CSP.html] [test_CSP_bug663567.html] @@ -103,3 +105,4 @@ support-files = [test_CSP_bug910139.html] [test_CSP_bug909029.html] [test_policyuri_regression_from_multipolicy.html] +[test_nonce_source.html] diff --git a/content/base/test/csp/test_nonce_source.html b/content/base/test/csp/test_nonce_source.html new file mode 100644 index 000000000000..e5d47453d8f1 --- /dev/null +++ b/content/base/test/csp/test_nonce_source.html @@ -0,0 +1,149 @@ + + + + Test CSP 1.1 nonce-source for scripts and styles + + + + + +

+ + + + + diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 211aa72708cb..3cc88c88c239 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -228,10 +228,11 @@ nsEventListenerManager::AddEventListenerInternal( uint32_t count = mListeners.Length(); for (uint32_t i = 0; i < count; i++) { ls = &mListeners.ElementAt(i); - if (ls->mListener == aListener && - ls->mListenerIsHandler == aHandler && + // mListener == aListener is the last one, since it can be a bit slow. + if (ls->mListenerIsHandler == aHandler && ls->mFlags == aFlags && - EVENT_TYPE_EQUALS(ls, aType, aTypeAtom, aTypeString, aAllEvents)) { + EVENT_TYPE_EQUALS(ls, aType, aTypeAtom, aTypeString, aAllEvents) && + ls->mListener == aListener) { return; } } @@ -728,7 +729,8 @@ nsEventListenerManager::SetEventHandler(nsIAtom *aName, csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT, NS_ConvertUTF8toUTF16(asciiSpec), scriptSample, - 0); + 0, + EmptyString()); } // return early if CSP wants us to block inline scripts diff --git a/content/html/document/test/Makefile.in b/content/html/document/test/Makefile.in index 73a216d04741..0cbab9038a4a 100644 --- a/content/html/document/test/Makefile.in +++ b/content/html/document/test/Makefile.in @@ -35,6 +35,7 @@ MOCHITEST_FILES = test_bug1682.html \ test_viewport.html \ test_documentAll.html \ test_document-element-inserted.html \ + test_document.watch.html \ $(filter disabled-temporarily--bug-559932, test_bug445004.html) \ bug445004-inner.js \ bug445004-outer-rel.html \ diff --git a/content/html/document/test/test_document.watch.html b/content/html/document/test/test_document.watch.html new file mode 100644 index 000000000000..54509823bef0 --- /dev/null +++ b/content/html/document/test/test_document.watch.html @@ -0,0 +1,129 @@ + + + + + + Test for Bug 903332 + + + + + +Mozilla Bug 903332 +

+ +
+
+ + diff --git a/content/media/test/crashtests/933156.html b/content/media/test/crashtests/933156.html new file mode 100644 index 000000000000..b89445a43dc3 --- /dev/null +++ b/content/media/test/crashtests/933156.html @@ -0,0 +1,23 @@ + + + + diff --git a/content/media/test/crashtests/crashtests.list b/content/media/test/crashtests/crashtests.list index 2fdf7318e70d..3baaff36fe59 100644 --- a/content/media/test/crashtests/crashtests.list +++ b/content/media/test/crashtests/crashtests.list @@ -61,6 +61,7 @@ load 925619-1.html load 925619-2.html load 926619.html load 933151.html +load 933156.html load offline-buffer-source-ended-1.html skip-if(B2G) load oscillator-ended-1.html # intermittent B2G timeouts, bug 920338 skip-if(B2G) load oscillator-ended-2.html # intermittent B2G timeouts, bug 920338 diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index a559f7f36bc0..c757d574a6b4 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -535,6 +535,8 @@ AudioContext::Shutdown() Suspend(); + mDecoder.Shutdown(); + // Release references to active nodes. // Active AudioNodes don't unregister in destructors, at which point the // Node is already unregistered. diff --git a/content/media/webaudio/MediaBufferDecoder.cpp b/content/media/webaudio/MediaBufferDecoder.cpp index a847b335030c..51fc9e6b4fed 100644 --- a/content/media/webaudio/MediaBufferDecoder.cpp +++ b/content/media/webaudio/MediaBufferDecoder.cpp @@ -539,6 +539,17 @@ MediaBufferDecoder::EnsureThreadPoolInitialized() return true; } +void +MediaBufferDecoder::Shutdown() { + if (mThreadPool) { + // Setting threadLimit to 0 causes threads to exit when all events have + // been run, like nsIThreadPool::Shutdown(), but doesn't run a nested event + // loop nor wait until this has happened. + mThreadPool->SetThreadLimit(0); + mThreadPool = nullptr; + } +} + WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType, AudioContext* aContext, const ArrayBuffer& aBuffer, diff --git a/content/media/webaudio/MediaBufferDecoder.h b/content/media/webaudio/MediaBufferDecoder.h index c5c42aa46b7d..56bad005bbf6 100644 --- a/content/media/webaudio/MediaBufferDecoder.h +++ b/content/media/webaudio/MediaBufferDecoder.h @@ -80,6 +80,8 @@ public: bool SyncDecodeMedia(const char* aContentType, uint8_t* aBuffer, uint32_t aLength, WebAudioDecodeJob& aDecodeJob); + void Shutdown(); + private: bool EnsureThreadPoolInitialized(); diff --git a/content/media/webaudio/test/test_pannerNodeTail.html b/content/media/webaudio/test/test_pannerNodeTail.html index c60fbc0cab86..12efbae4d6f4 100644 --- a/content/media/webaudio/test/test_pannerNodeTail.html +++ b/content/media/webaudio/test/test_pannerNodeTail.html @@ -27,7 +27,7 @@ // // Web Audio doesn't provide a means to precisely time connect()s but we can // test that the output of delay nodes matches the output from a reference -// PannerNodes that we know will not be GCed. +// PannerNode that we know will not be GCed. // // Another set of delay nodes is added upstream to ensure that the source node // has removed its self-reference after dispatching its "ended" event. @@ -41,15 +41,14 @@ const blockSize = 128; const bufferSize = 4096; const pannerCount = bufferSize / blockSize; // sourceDelayBufferCount should be long enough to allow the source node -// onended to finish. Because of the way blocks are processed in sets on -// the graph thread, this also affects when the graph thread receives the -// disconnect. +// onended to finish and remove the source self-reference. const sourceDelayBufferCount = 3; var gotEnded = false; // ccDelayLength should be long enough to allow CC to run var ccDelayBufferCount = 20; const ccDelayLength = ccDelayBufferCount * bufferSize; +var ctx; var testPanners = []; var referencePanner; var referenceProcessCount = 0; @@ -58,18 +57,27 @@ var referenceOutput = [new Float32Array(bufferSize), var testProcessor; var testProcessCount = 0; +function isChannelSilent(channel) { + for (var i = 0; i < channel.length; ++i) { + if (channel[i] != 0.0) { + dump("input at " + i + "\n"); + return false; + } + } + return true; +} + function onReferenceOutput(e) { switch(referenceProcessCount) { case sourceDelayBufferCount - 1: // The panners are about to finish. if (!gotEnded) { - todo(false, "Oscillator hasn't ended. Increase sourceDelayBufferCount?"); + todo(false, "Source hasn't ended. Increase sourceDelayBufferCount?"); } // Connect each PannerNode output to a downstream DelayNode, // and connect ScriptProcessors to compare test and reference panners. - var ctx = e.target.context; var delayDuration = ccDelayLength / ctx.sampleRate; for (var i = 0; i < pannerCount; ++i) { var delay = ctx.createDelay(delayDuration); @@ -80,6 +88,9 @@ function onReferenceOutput(e) { testProcessor = null; testPanners = null; + // The panning effect is linear so only one reference panner is required. + // This also checks that the individual panners don't chop their output + // too soon. referencePanner.connect(e.target); // Assuming the above operations have already scheduled an event to run in @@ -101,16 +112,13 @@ function onReferenceOutput(e) { e.target.onaudioprocess = null; e.target.disconnect(); - for (var i = 0; i < referenceOutput[0].length; ++i) { - if (referenceOutput[0][i] != 0.0) { - return; // good - a connection must have been received by the graph - } - } // If the buffer is silent, there is probably not much point just // increasing the buffer size, because, with the buffer size already // significantly larger than panner tail time, it demonstrates that the // lag between threads is much greater than the tail time. - todo(false, "Connections not detected."); + if (isChannelSilent(referenceOutput[0])) { + todo(false, "Connections not detected."); + } } referenceProcessCount++; @@ -131,36 +139,30 @@ function onTestOutput(e) { } function startTest() { - var ctx = new AudioContext(); - // Place the listener to the side of the origin, where the panners are - // positioned, to maximize delay in one ear. - ctx.listener.setPosition(1,0,0); - // 0.002 is MaxDelayTimeSeconds in HRTFpanner.cpp // and 512 is fftSize() at 48 kHz. const expectedPannerTailTime = 0.002 * ctx.sampleRate + 512; // Create some PannerNodes downstream from DelayNodes with delays long - // enough for their source oscillator to finish, dispatch its "ended" event + // enough for their source to finish, dispatch its "ended" event // and release its playing reference. The DelayNodes should expire their // tail-time references before the PannerNodes and so only the PannerNode // lifetimes depends on their tail-time references. Many DelayNodes are // created and timed to finish at different times so that one PannerNode // will be finishing the block processed immediately after the connect is // received. - var oscillator = ctx.createOscillator(); - oscillator.start(0); + var source = ctx.createBufferSource(); // Just short of blockSize here to avoid rounding into the next block - oscillator.stop((blockSize - 1) / ctx.sampleRate); - oscillator.onended = function(e) { + var buffer = ctx.createBuffer(1, blockSize - 1, ctx.sampleRate); + for (var i = 0; i < buffer.length; ++i) { + buffer.getChannelData(0)[i] = Math.cos(Math.PI * i / buffer.length); + } + source.buffer = buffer; + source.start(0); + source.onended = function(e) { gotEnded = true; }; - // The panner effect is linear so only one reference panner is required. - // This also checks that the individual panners don't chop their output too - // soon. - referencePanner = ctx.createPanner(); - // Time the first test panner to finish just before downstream DelayNodes // are about the be connected. Note that DelayNode lifetime depends on // maxDelayTime so set that equal to the delay. @@ -171,11 +173,11 @@ function startTest() { for (var i = 0; i < pannerCount; ++i) { var delay = ctx.createDelay(delayDuration); delay.delayTime.value = delayDuration; - oscillator.connect(delay); + source.connect(delay); delay.connect(referencePanner) var panner = ctx.createPanner(); - delay.connect(panner) + delay.connect(panner); testPanners[i] = panner; delayDuration += blockSize / ctx.sampleRate; @@ -196,7 +198,33 @@ function startTest() { testProcessor.connect(ctx.destination); } -startTest(); +function prepareTest() { + ctx = new AudioContext(); + // Place the listener to the side of the origin, where the panners are + // positioned, to maximize delay in one ear. + ctx.listener.setPosition(1,0,0); + + // A PannerNode will produce no output until it has loaded its HRIR + // database. Wait for this to load before starting the test. + var processor = ctx.createScriptProcessor(bufferSize, 2, 0); + referencePanner = ctx.createPanner(); + referencePanner.connect(processor); + var oscillator = ctx.createOscillator(); + oscillator.connect(referencePanner); + oscillator.start(0); + + processor.onaudioprocess = function(e) { + if (isChannelSilent(e.inputBuffer.getChannelData(0))) + return; + + oscillator.stop(0); + oscillator.disconnect(); + referencePanner.disconnect(); + e.target.onaudioprocess = null; + SimpleTest.executeSoon(startTest); + }; +} +prepareTest(); diff --git a/content/smil/nsSMILCSSValueType.cpp b/content/smil/nsSMILCSSValueType.cpp index a09067d71062..7a0636faf7d4 100644 --- a/content/smil/nsSMILCSSValueType.cpp +++ b/content/smil/nsSMILCSSValueType.cpp @@ -394,7 +394,8 @@ nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID, } nsIDocument* doc = aTargetElement->GetCurrentDoc(); - if (doc && !nsStyleUtil::CSPAllowsInlineStyle(doc->NodePrincipal(), + if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr, + doc->NodePrincipal(), doc->GetDocumentURI(), 0, aString, nullptr)) { return; diff --git a/db/sqlite3/src/Makefile.in b/db/sqlite3/src/Makefile.in index cd5ab62697bf..9ab6d52a37c8 100644 --- a/db/sqlite3/src/Makefile.in +++ b/db/sqlite3/src/Makefile.in @@ -26,8 +26,8 @@ sqlite-version.h: sqlite-version.py sqlite3.h # We have to preprocess our def file because we need different symbols in debug # builds exposed that are not built in non-debug builds. $(DEFFILE): sqlite.def - @$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) \ - $(srcdir)/sqlite.def > $(DEFFILE) + @$(call py_action,preprocessor,$(DEFINES) \ + $(srcdir)/sqlite.def -o $(DEFFILE)) export:: sqlite-version.h endif @@ -118,7 +118,7 @@ include $(topsrcdir)/config/rules.mk LOCAL_INCLUDES += -I$(srcdir) ifeq ($(OS_ARCH),OS2) -ADD_TO_DEF_FILE = $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) \ +ADD_TO_DEF_FILE = $(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) \ $(srcdir)/sqlite.def | sed -e '1,/^EXPORTS$$/ d' -e 's,sqlite3,_\0,' \ -e 's,\ DATA.*$$,,' >> $(DEF_FILE) endif diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index b6ad4c2b3a25..b9222c8b7201 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -3620,17 +3620,19 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } if (!(flags & JSRESOLVE_ASSIGNING) && sDocument_id == id) { + nsCOMPtr document = win->GetDoc(); + JS::Rooted v(cx); + nsCOMPtr holder; + rv = WrapNative(cx, JS::CurrentGlobalOrNull(cx), document, document, + &NS_GET_IID(nsIDOMDocument), &v, getter_AddRefs(holder), + false); + NS_ENSURE_SUCCESS(rv, rv); + + // nsIDocument::WrapObject will handle defining the property. + *objp = obj; + + // NB: We need to do this for any Xray wrapper. if (xpc::WrapperFactory::IsXrayWrapper(obj)) { - nsCOMPtr document = win->GetDoc(); - JS::Rooted v(cx); - nsCOMPtr holder; - rv = WrapNative(cx, JS::CurrentGlobalOrNull(cx), document, document, - &NS_GET_IID(nsIDOMDocument), &v, getter_AddRefs(holder), - false); - NS_ENSURE_SUCCESS(rv, rv); - - *objp = obj; - *_retval = JS_WrapValue(cx, &v) && JS_DefineProperty(cx, obj, "document", v, JS_PropertyStub, JS_StrictPropertyStub, diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 7796643a2050..b6721c8916ec 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -613,6 +613,11 @@ public: virtual bool enumerate(JSContext *cx, JS::Handle proxy, JS::AutoIdVector &props) MOZ_OVERRIDE; + virtual bool watch(JSContext *cx, JS::Handle proxy, + JS::Handle id, JS::Handle callable) MOZ_OVERRIDE; + virtual bool unwatch(JSContext *cx, JS::Handle proxy, + JS::Handle id) MOZ_OVERRIDE; + // Derived traps virtual bool has(JSContext *cx, JS::Handle proxy, JS::Handle id, bool *bp) MOZ_OVERRIDE; @@ -962,6 +967,20 @@ nsOuterWindowProxy::AppendIndexedPropertyNames(JSContext *cx, JSObject *proxy, return true; } +bool +nsOuterWindowProxy::watch(JSContext *cx, JS::Handle proxy, + JS::Handle id, JS::Handle callable) +{ + return js::WatchGuts(cx, proxy, id, callable); +} + +bool +nsOuterWindowProxy::unwatch(JSContext *cx, JS::Handle proxy, + JS::Handle id) +{ + return js::UnwatchGuts(cx, proxy, id); +} + nsOuterWindowProxy nsOuterWindowProxy::singleton; diff --git a/dom/base/nsJSTimeoutHandler.cpp b/dom/base/nsJSTimeoutHandler.cpp index 3cc8311999fb..154d0ae6e1ed 100644 --- a/dom/base/nsJSTimeoutHandler.cpp +++ b/dom/base/nsJSTimeoutHandler.cpp @@ -181,7 +181,7 @@ CheckCSPForEval(JSContext* aCx, nsGlobalWindow* aWindow, ErrorResult& aError) } csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL, - fileNameString, scriptSample, lineNum); + fileNameString, scriptSample, lineNum, EmptyString()); } return allowsEval; diff --git a/dom/bindings/DOMJSProxyHandler.cpp b/dom/bindings/DOMJSProxyHandler.cpp index 3bb3185d181a..495d11abee3c 100644 --- a/dom/bindings/DOMJSProxyHandler.cpp +++ b/dom/bindings/DOMJSProxyHandler.cpp @@ -235,6 +235,19 @@ BaseDOMProxyHandler::enumerate(JSContext* cx, JS::Handle proxy, (!proto || js::GetPropertyNames(cx, proto, 0, &props)); } +bool +BaseDOMProxyHandler::watch(JSContext* cx, JS::Handle proxy, JS::Handle id, + JS::Handle callable) +{ + return js::WatchGuts(cx, proxy, id, callable); +} + +bool +BaseDOMProxyHandler::unwatch(JSContext* cx, JS::Handle proxy, JS::Handle id) +{ + return js::UnwatchGuts(cx, proxy, id); +} + bool DOMProxyHandler::has(JSContext* cx, JS::Handle proxy, JS::Handle id, bool* bp) { diff --git a/dom/bindings/DOMJSProxyHandler.h b/dom/bindings/DOMJSProxyHandler.h index 9b27d082d0ab..891f4d87533a 100644 --- a/dom/bindings/DOMJSProxyHandler.h +++ b/dom/bindings/DOMJSProxyHandler.h @@ -58,6 +58,11 @@ public: JS::Handle id, JS::MutableHandle desc, unsigned flags) MOZ_OVERRIDE; + + bool watch(JSContext* cx, JS::Handle proxy, JS::Handle id, + JS::Handle callable) MOZ_OVERRIDE; + bool unwatch(JSContext* cx, JS::Handle proxy, + JS::Handle id) MOZ_OVERRIDE; }; class DOMProxyHandler : public BaseDOMProxyHandler diff --git a/dom/bindings/Makefile.in b/dom/bindings/Makefile.in index 18f23256405c..634d05e62866 100644 --- a/dom/bindings/Makefile.in +++ b/dom/bindings/Makefile.in @@ -157,14 +157,14 @@ $(test_webidl_files): %: $(srcdir)/test/% # a symlink, which will clobber files in the srcdir, which is bad. $(preprocessed_webidl_files): %: $(webidl_base)/% $(GLOBAL_DEPS) $(RM) $@ - PYTHONDONTWRITEBYTECODE=1 $(PYTHON) \ - $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(webidl_base)/$* -o $@ + $(call py_action,preprocessor, \ + $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(webidl_base)/$* -o $@) # See the comment about PP_TARGETS for $(preprocessed_webidl_files) $(preprocessed_test_webidl_files): %: $(srcdir)/test/% $(GLOBAL_DEPS) $(RM) $@ - PYTHONDONTWRITEBYTECODE=1 $(PYTHON) \ - $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(srcdir)/test/$* -o $@ + $(call py_action,preprocessor, \ + $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(srcdir)/test/$* -o $@) # Make is dumb and can get confused between "foo" and "$(CURDIR)/foo". Make # sure that the latter depends on the former, since the latter gets used in .pp diff --git a/dom/datastore/DataStore.jsm b/dom/datastore/DataStore.jsm index 45884bf2f260..f6b3ad6b6d0f 100644 --- a/dom/datastore/DataStore.jsm +++ b/dom/datastore/DataStore.jsm @@ -177,17 +177,17 @@ this.DataStore.prototype = { getInternalRequest(); }, - updateInternal: function(aResolve, aStore, aRevisionStore, aId, aObj) { - debug("UpdateInternal " + aId); + putInternal: function(aResolve, aStore, aRevisionStore, aObj, aId) { + debug("putInternal " + aId); let self = this; let request = aStore.put(aObj, aId); request.onsuccess = function(aEvent) { - debug("UpdateInternal success"); + debug("putInternal success"); self.addRevision(aRevisionStore, aId, REVISION_UPDATED, function() { - debug("UpdateInternal - revisionId increased"); + debug("putInternal - revisionId increased"); // No wrap here because the result is always a int. aResolve(aEvent.target.result); } @@ -195,11 +195,11 @@ this.DataStore.prototype = { }; }, - addInternal: function(aResolve, aStore, aRevisionStore, aObj) { + addInternal: function(aResolve, aStore, aRevisionStore, aObj, aId) { debug("AddInternal"); let self = this; - let request = aStore.put(aObj); + let request = aStore.add(aObj, aId); request.onsuccess = function(aEvent) { debug("Request successful. Id: " + aEvent.target.result); self.addRevision(aRevisionStore, aEvent.target.result, REVISION_ADDED, @@ -384,7 +384,7 @@ this.DataStore.prototype = { ); }, - update: function(aId, aObj) { + put: function(aObj, aId) { aId = parseInt(aId); if (isNaN(aId) || aId <= 0) { return throwInvalidArg(this._window); @@ -399,12 +399,19 @@ this.DataStore.prototype = { // Promise return this.newDBPromise("readwrite", function(aResolve, aReject, aTxn, aStore, aRevisionStore) { - self.updateInternal(aResolve, aStore, aRevisionStore, aId, aObj); + self.putInternal(aResolve, aStore, aRevisionStore, aObj, aId); } ); }, - add: function(aObj) { + add: function(aObj, aId) { + if (aId) { + aId = parseInt(aId); + if (isNaN(aId) || aId <= 0) { + return throwInvalidArg(this._window); + } + } + if (this._readOnly) { return throwReadOnly(this._window); } @@ -414,7 +421,7 @@ this.DataStore.prototype = { // Promise return this.newDBPromise("readwrite", function(aResolve, aReject, aTxn, aStore, aRevisionStore) { - self.addInternal(aResolve, aStore, aRevisionStore, aObj); + self.addInternal(aResolve, aStore, aRevisionStore, aObj, aId); } ); }, @@ -458,104 +465,6 @@ this.DataStore.prototype = { return this._revisionId; }, - getChanges: function(aRevisionId) { - debug("GetChanges: " + aRevisionId); - - if (aRevisionId === null || aRevisionId === undefined) { - return this._window.Promise.reject( - new this._window.DOMError("SyntaxError", "Invalid revisionId")); - } - - let self = this; - - // Promise - return new this._window.Promise(function(aResolve, aReject) { - debug("GetChanges promise started"); - self._db.revisionTxn( - 'readonly', - function(aTxn, aStore) { - debug("GetChanges transaction success"); - - let request = self._db.getInternalRevisionId( - aRevisionId, - aStore, - function(aInternalRevisionId) { - if (aInternalRevisionId == undefined) { - aResolve(undefined); - return; - } - - // This object is the return value of this promise. - // Initially we use maps, and then we convert them in array. - let changes = { - revisionId: '', - addedIds: {}, - updatedIds: {}, - removedIds: {} - }; - - let request = aStore.mozGetAll(IDBKeyRange.lowerBound(aInternalRevisionId, true)); - request.onsuccess = function(aEvent) { - for (let i = 0; i < aEvent.target.result.length; ++i) { - let data = aEvent.target.result[i]; - - switch (data.operation) { - case REVISION_ADDED: - changes.addedIds[data.objectId] = true; - break; - - case REVISION_UPDATED: - // We don't consider an update if this object has been added - // or if it has been already modified by a previous - // operation. - if (!(data.objectId in changes.addedIds) && - !(data.objectId in changes.updatedIds)) { - changes.updatedIds[data.objectId] = true; - } - break; - - case REVISION_REMOVED: - let id = data.objectId; - - // If the object has been added in this range of revisions - // we can ignore it and remove it from the list. - if (id in changes.addedIds) { - delete changes.addedIds[id]; - } else { - changes.removedIds[id] = true; - } - - if (id in changes.updatedIds) { - delete changes.updatedIds[id]; - } - break; - } - } - - // The last revisionId. - if (aEvent.target.result.length) { - changes.revisionId = aEvent.target.result[aEvent.target.result.length - 1].revisionId; - } - - // From maps to arrays. - changes.addedIds = Object.keys(changes.addedIds).map(function(aKey) { return parseInt(aKey, 10); }); - changes.updatedIds = Object.keys(changes.updatedIds).map(function(aKey) { return parseInt(aKey, 10); }); - changes.removedIds = Object.keys(changes.removedIds).map(function(aKey) { return parseInt(aKey, 10); }); - - let wrappedObject = ObjectWrapper.wrap(changes, self._window); - aResolve(wrappedObject); - }; - } - ); - }, - function(aEvent) { - debug("GetChanges transaction failed"); - aReject(createDOMError(self._window, aEvent)); - } - ); - }); - }, - getLength: function() { let self = this; diff --git a/dom/datastore/DataStoreDB.jsm b/dom/datastore/DataStoreDB.jsm index c7f94a881a55..75c3fdb8af17 100644 --- a/dom/datastore/DataStoreDB.jsm +++ b/dom/datastore/DataStoreDB.jsm @@ -83,10 +83,10 @@ DataStoreDB.prototype = { ); }, - addRevision: function(aStore, aId, aType, aSuccessCb) { - debug("AddRevision: " + aId + " - " + aType); + addRevision: function(aStore, aKey, aType, aSuccessCb) { + debug("AddRevision: " + aKey + " - " + aType); let revisionId = uuidgen.generateUUID().toString(); - let request = aStore.put({ revisionId: revisionId, objectId: aId, operation: aType }); + let request = aStore.put({ revisionId: revisionId, objectId: aKey, operation: aType }); request.onsuccess = function() { aSuccessCb(revisionId); } diff --git a/dom/datastore/tests/file_arrays.html b/dom/datastore/tests/file_arrays.html index 263b5180cba9..3bff02693af1 100644 --- a/dom/datastore/tests/file_arrays.html +++ b/dom/datastore/tests/file_arrays.html @@ -34,7 +34,7 @@ var store = stores[0]; ok("get" in store, "store.get exists"); - ok("update" in store, "store.update exists"); + ok("put" in store, "store.put exists"); ok("add" in store, "store.add exists"); ok("remove" in store, "store.remove exists"); ok("clear" in store, "store.clear exists"); diff --git a/dom/datastore/tests/file_basic.html b/dom/datastore/tests/file_basic.html index addff1283c63..d46fe44fa030 100644 --- a/dom/datastore/tests/file_basic.html +++ b/dom/datastore/tests/file_basic.html @@ -34,12 +34,11 @@ var store = stores[0]; ok("get" in store, "store.get exists"); - ok("update" in store, "store.update exists"); + ok("put" in store, "store.put exists"); ok("add" in store, "store.add exists"); ok("remove" in store, "store.remove exists"); ok("clear" in store, "store.clear exists"); ok("revisionId" in store, "store.revisionId exists"); - ok("getChanges" in store, "store.getChanges exists"); ok("getLength" in store, "store.getLength exists"); ok("sync" in store, "store.sync exists"); @@ -66,9 +65,9 @@ }, cbError); } - function testStoreUpdate(id, value) { - return gStore.update(id, value).then(function() { - ok(true, "store.update() is called"); + function testStorePut(value, id) { + return gStore.put(value, id).then(function() { + ok(true, "store.put() is called"); }, cbError); } @@ -114,8 +113,8 @@ gId = id; runTest(); }, cbError); }, function() { testStoreGet(gId, "hello world"); }, - // Update + Get - string - function() { testStoreUpdate(gId, "hello world 2").then(function() { + // Put + Get - string + function() { testStorePut("hello world 2", gId).then(function() { runTest(); }, cbError); }, function() { testStoreGet(gId, "hello world 2"); }, diff --git a/dom/datastore/tests/file_changes.html b/dom/datastore/tests/file_changes.html index 31ed89cc01a9..8f54936fad16 100644 --- a/dom/datastore/tests/file_changes.html +++ b/dom/datastore/tests/file_changes.html @@ -49,9 +49,9 @@ }, cbError); } - function testStoreUpdate(id, value) { - gStore.update(id, value).then(function(retId) { - is(id, retId, "store.update() is called with the right id"); + function testStorePut(value, id) { + gStore.put(value, id).then(function(retId) { + is(id, retId, "store.put() is called with the right id"); }, cbError); } @@ -84,9 +84,9 @@ function() { gChangeId = 1; gChangeOperation = 'added'; testStoreAdd({ number: 42 }, 1); }, - // Update + // Put function() { gChangeId = 1; gChangeOperation = 'updated'; - testStoreUpdate(1, { number: 43 }); }, + testStorePut({ number: 43 }, 1); }, // Remove function() { gChangeId = 1; gChangeOperation = 'removed'; @@ -103,9 +103,9 @@ function() { gChangeId = 2; gChangeOperation = 'added'; testStoreAdd({ number: 42 }, 2); }, - // Update + // Put function() { gChangeId = 2; gChangeOperation = 'updated'; - testStoreUpdate(2, { number: 43 }); }, + testStorePut({ number: 43 }, 2); }, // Remove function() { gChangeId = 2; gChangeOperation = 'removed'; diff --git a/dom/datastore/tests/file_readonly.html b/dom/datastore/tests/file_readonly.html index 64fbe31e7d91..f478a45dc8e1 100644 --- a/dom/datastore/tests/file_readonly.html +++ b/dom/datastore/tests/file_readonly.html @@ -33,7 +33,7 @@ var store = stores[0]; ok("get" in store, "store.get exists"); - ok("update" in store, "store.update exists"); + ok("put" in store, "store.put exists"); ok("add" in store, "store.add exists"); ok("remove" in store, "store.remove exists"); ok("clear" in store, "store.clear exists"); @@ -51,11 +51,11 @@ f = f.then(cbError, function() { ok(true, "store.add() fails because the db is readonly"); - return store.update(123, {}); + return store.put({}, 123); }) f = f.then(cbError, function() { - ok(true, "store.update() fails because the db is readonly"); + ok(true, "store.put() fails because the db is readonly"); }) f.then(function() { diff --git a/dom/datastore/tests/file_revision.html b/dom/datastore/tests/file_revision.html deleted file mode 100644 index 8781412145b7..000000000000 --- a/dom/datastore/tests/file_revision.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - Test for DataStore - basic operation on a readonly db - - -

- -
-  
-
- - - diff --git a/dom/datastore/tests/file_sync.html b/dom/datastore/tests/file_sync.html index 0f00d5fcf98f..b6a20bf47a97 100644 --- a/dom/datastore/tests/file_sync.html +++ b/dom/datastore/tests/file_sync.html @@ -133,14 +133,14 @@ function() { gExpectedEvents = true; - gStore.add(1).then(function(id) { + gStore.add(1,2).then(function(id) { gRevisions.push(gStore.revisionId); ok(true, "Iteme: " + id + " added"); }); }, function() { - gStore.add(2).then(function(id) { + gStore.add(2,3).then(function(id) { gRevisions.push(gStore.revisionId); ok(true, "Iteme: " + id + " added"); }); @@ -150,8 +150,8 @@ gExpectedEvents = false; var cursor = gStore.sync(); var steps = [ { operation: 'clear', }, - { operation: 'add', id: 1, data: 1 }, - { operation: 'add', id: 2, data: 2 }, + { operation: 'add', id: 2, data: 1 }, + { operation: 'add', id: 3, data: 2 }, { operation: 'done' }]; testCursor(cursor, steps); }, @@ -159,23 +159,23 @@ function() { var cursor = gStore.sync('wrong revision ID'); var steps = [ { operation: 'clear', }, - { operation: 'add', id: 1, data: 1 }, - { operation: 'add', id: 2, data: 2 }, + { operation: 'add', id: 2, data: 1 }, + { operation: 'add', id: 3, data: 2 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[0]); - var steps = [ { operation: 'add', id: 1, data: 1 }, - { operation: 'add', id: 2, data: 2 }, + var steps = [ { operation: 'add', id: 2, data: 1 }, + { operation: 'add', id: 3, data: 2 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[1]); - var steps = [ { operation: 'add', id: 2, data: 2 }, + var steps = [ { operation: 'add', id: 3, data: 2 }, { operation: 'done' }]; testCursor(cursor, steps); }, @@ -189,7 +189,7 @@ // Test after an update function() { gExpectedEvents = true; - gStore.update(1, 3).then(function() { + gStore.put(3, 2).then(function() { gRevisions.push(gStore.revisionId); }); }, @@ -198,8 +198,8 @@ gExpectedEvents = false; var cursor = gStore.sync(); var steps = [ { operation: 'clear', }, - { operation: 'add', id: 1, data: 3 }, - { operation: 'add', id: 2, data: 2 }, + { operation: 'add', id: 2, data: 3 }, + { operation: 'add', id: 3, data: 2 }, { operation: 'done' }]; testCursor(cursor, steps); }, @@ -207,31 +207,31 @@ function() { var cursor = gStore.sync('wrong revision ID'); var steps = [ { operation: 'clear', }, - { operation: 'add', id: 1, data: 3 }, - { operation: 'add', id: 2, data: 2 }, + { operation: 'add', id: 2, data: 3 }, + { operation: 'add', id: 3, data: 2 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[0]); - var steps = [ { operation: 'add', id: 1, data: 3 }, - { operation: 'add', id: 2, data: 2 }, + var steps = [ { operation: 'add', id: 2, data: 3 }, + { operation: 'add', id: 3, data: 2 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[1]); - var steps = [ { operation: 'add', id: 2, data: 2 }, - { operation: 'update', id: 1, data: 3 }, + var steps = [ { operation: 'add', id: 3, data: 2 }, + { operation: 'update', id: 2, data: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[2]); - var steps = [ { operation: 'update', id: 1, data: 3 }, + var steps = [ { operation: 'update', id: 2, data: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, @@ -245,7 +245,7 @@ // Test after a remove function() { gExpectedEvents = true; - gStore.remove(2).then(function() { + gStore.remove(3).then(function() { gRevisions.push(gStore.revisionId); }); }, @@ -254,7 +254,7 @@ gExpectedEvents = false; var cursor = gStore.sync(); var steps = [ { operation: 'clear', }, - { operation: 'add', id: 1, data: 3 }, + { operation: 'add', id: 2, data: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, @@ -262,36 +262,36 @@ function() { var cursor = gStore.sync('wrong revision ID'); var steps = [ { operation: 'clear', }, - { operation: 'add', id: 1, data: 3 }, + { operation: 'add', id: 2, data: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[0]); - var steps = [ { operation: 'add', id: 1, data: 3 }, + var steps = [ { operation: 'add', id: 2, data: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[1]); - var steps = [ { operation: 'update', id: 1, data: 3 }, + var steps = [ { operation: 'update', id: 2, data: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[2]); - var steps = [ { operation: 'update', id: 1, data: 3 }, - { operation: 'remove', id: 2 }, + var steps = [ { operation: 'update', id: 2, data: 3 }, + { operation: 'remove', id: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, function() { var cursor = gStore.sync(gRevisions[3]); - var steps = [ { operation: 'remove', id: 2 }, + var steps = [ { operation: 'remove', id: 3 }, { operation: 'done' }]; testCursor(cursor, steps); }, @@ -306,7 +306,7 @@ function() { gCursor = gStore.sync(); var steps = [ { operation: 'clear', }, - { operation: 'add', id: 1, data: 3 } ]; + { operation: 'add', id: 2, data: 3 } ]; testCursor(gCursor, steps); }, @@ -320,31 +320,31 @@ // New events when the cursor is active function() { - var steps = [ { operation: 'add', id: 3, data: 42 } ]; + var steps = [ { operation: 'add', id: 4, data: 42 } ]; testCursor(gCursor, steps); }, function() { - gStore.update(1, 42).then(function(id) { + gStore.put(42, 2).then(function(id) { gRevisions.push(gStore.revisionId); runTest(); }); }, function() { - var steps = [ { operation: 'update', id: 1, data: 42 } ]; + var steps = [ { operation: 'update', id: 2, data: 42 } ]; testCursor(gCursor, steps); }, function() { - gStore.remove(1).then(function(id) { + gStore.remove(2).then(function(id) { gRevisions.push(gStore.revisionId); runTest(); }); }, function() { - var steps = [ { operation: 'remove', id: 1 } ]; + var steps = [ { operation: 'remove', id: 2 } ]; testCursor(gCursor, steps); }, @@ -357,7 +357,7 @@ }, function() { - var steps = [ { operation: 'add', id: 4, data: 42 } ]; + var steps = [ { operation: 'add', id: 5, data: 42 } ]; testCursor(gCursor, steps); }, @@ -378,7 +378,7 @@ function() { var steps = [ { operation: 'clear' }, - { operation: 'add', id: 5, data: 42 }, + { operation: 'add', id: 6, data: 42 }, { operation: 'done' } ]; testCursor(gCursor, steps); }, diff --git a/dom/datastore/tests/mochitest.ini b/dom/datastore/tests/mochitest.ini index cf3056acfce1..a13df2499244 100644 --- a/dom/datastore/tests/mochitest.ini +++ b/dom/datastore/tests/mochitest.ini @@ -3,7 +3,6 @@ support-files = file_app_install.html file_readonly.html file_basic.html - file_revision.html file_changes.html file_changes2.html file_app.sjs @@ -16,7 +15,6 @@ support-files = [test_app_install.html] [test_readonly.html] [test_basic.html] -[test_revision.html] [test_changes.html] [test_arrays.html] [test_oop.html] diff --git a/dom/datastore/tests/test_revision.html b/dom/datastore/tests/test_revision.html deleted file mode 100644 index 23846c8469b7..000000000000 --- a/dom/datastore/tests/test_revision.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - Test for DataStore - basic operation on a readonly db - - - - -

- -
-  
-
- - - diff --git a/dom/src/jsurl/nsJSProtocolHandler.cpp b/dom/src/jsurl/nsJSProtocolHandler.cpp index 453b37511b54..6fb55a490ca5 100644 --- a/dom/src/jsurl/nsJSProtocolHandler.cpp +++ b/dom/src/jsurl/nsJSProtocolHandler.cpp @@ -179,7 +179,8 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel, csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT, NS_ConvertUTF8toUTF16(asciiSpec), NS_ConvertUTF8toUTF16(mURL), - 0); + 0, + EmptyString()); } //return early if inline scripts are not allowed diff --git a/dom/webidl/DataStore.webidl b/dom/webidl/DataStore.webidl index 320bb0ddd503..e349f6a29646 100644 --- a/dom/webidl/DataStore.webidl +++ b/dom/webidl/DataStore.webidl @@ -24,10 +24,10 @@ interface DataStore : EventTarget { Promise get(sequence id); // Promise - Promise update(unsigned long id, any obj); + Promise put(any obj, unsigned long id); // Promise - Promise add(any obj); + Promise add(any obj, optional unsigned long id); // Promise Promise remove(unsigned long id); @@ -39,22 +39,12 @@ interface DataStore : EventTarget { attribute EventHandler onchange; - // Promise - Promise getChanges(DOMString revisionId); - // Promise Promise getLength(); DataStoreCursor sync(optional DOMString revisionId = ""); }; -dictionary DataStoreChanges { - DOMString revisionId; - sequence addedIds; - sequence updatedIds; - sequence removedIds; -}; - [Pref="dom.datastore.enabled", JSImplementation="@mozilla.org/dom/datastore-cursor;1"] interface DataStoreCursor { diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index 5c784eec4485..18c0c9a74904 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -28,7 +28,7 @@ typedef any Transferable; // the current browsing context [Unforgeable, Throws] readonly attribute WindowProxy window; [Replaceable, Throws] readonly attribute WindowProxy self; - [Unforgeable] readonly attribute Document? document; + //[Unforgeable] readonly attribute Document? document; [Throws] attribute DOMString name; [PutForwards=href, Unforgeable, Throws] readonly attribute Location? location; [Throws] readonly attribute History history; diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index d6dbd2c1d574..df477c6af9a0 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -707,7 +707,7 @@ public: "Call to eval() or related function blocked by CSP."); if (mWorkerPrivate->GetReportCSPViolations()) { csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL, - mFileName, scriptSample, mLineNum); + mFileName, scriptSample, mLineNum, EmptyString()); } } diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index ada6a857fbbf..3141e40269d3 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -68,6 +68,8 @@ enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 }; #ifdef HAVE_CPUID_H +#if !(defined(__SSE2__) || defined(_M_X64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP >= 2)) // cpuid.h is available on gcc 4.3 and higher on i386 and x86_64 #include @@ -78,6 +80,7 @@ HasCPUIDBit(unsigned int level, CPUIDRegister reg, unsigned int bit) return __get_cpuid(level, ®s[0], ®s[1], ®s[2], ®s[3]) && (regs[reg] & bit); } +#endif #define HAVE_CPU_DETECTION #else diff --git a/gfx/layers/ThebesLayerBuffer.cpp b/gfx/layers/ThebesLayerBuffer.cpp index 6af984379586..d080e87aeb38 100644 --- a/gfx/layers/ThebesLayerBuffer.cpp +++ b/gfx/layers/ThebesLayerBuffer.cpp @@ -738,6 +738,8 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, mDTBuffer->ReleaseBits(data); if (mode == Layer::SURFACE_COMPONENT_ALPHA) { + EnsureBufferOnWhite(); + MOZ_ASSERT(mDTBufferOnWhite); mDTBufferOnWhite->LockBits(&data, &size, &stride, &format); uint8_t bytesPerPixel = BytesPerPixel(format); BufferUnrotate(data, @@ -834,7 +836,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, NS_ASSERTION(destDTBufferOnWhite, "Must have a white buffer!"); destDTBufferOnWhite->SetTransform(mat); EnsureBufferOnWhite(); - MOZ_ASSERT(destDTBufferOnWhite, "Have we got a Thebes buffer for some reason?"); + MOZ_ASSERT(mDTBufferOnWhite, "Have we got a Thebes buffer for some reason?"); DrawBufferWithRotation(destDTBufferOnWhite, BUFFER_WHITE, 1.0, OP_SOURCE); destDTBufferOnWhite->SetTransform(Matrix()); } diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index a2301bdbe8ba..dd8029726834 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -231,7 +231,8 @@ ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix) } nsEventStatus -APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) +APZCTreeManager::ReceiveInputEvent(const InputData& aEvent, + ScrollableLayerGuid* aOutTargetGuid) { nsEventStatus result = nsEventStatus_eIgnore; gfx3DMatrix transformToApzc; @@ -261,6 +262,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) APZC_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get()); } if (mApzcForInputBlock) { + mApzcForInputBlock->GetGuid(aOutTargetGuid); // Use the cached transform to compute the point to send to the APZC. // This ensures that the sequence of touch points an APZC sees in an // input block are all in the same coordinate space. @@ -290,6 +292,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) const PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput(); nsRefPtr apzc = GetTargetAPZC(pinchInput.mFocusPoint); if (apzc) { + apzc->GetGuid(aOutTargetGuid); GetInputTransforms(apzc, transformToApzc, transformToGecko); PinchGestureInput inputForApzc(pinchInput); ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc); @@ -300,6 +303,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) const TapGestureInput& tapInput = aEvent.AsTapGestureInput(); nsRefPtr apzc = GetTargetAPZC(ScreenPoint(tapInput.mPoint)); if (apzc) { + apzc->GetGuid(aOutTargetGuid); GetInputTransforms(apzc, transformToApzc, transformToGecko); TapGestureInput inputForApzc(tapInput); ApplyTransform(&(inputForApzc.mPoint), transformToApzc); @@ -342,6 +346,7 @@ APZCTreeManager::GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, nsEventStatus APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent, + ScrollableLayerGuid* aOutTargetGuid, WidgetTouchEvent* aOutEvent) { nsEventStatus ret = nsEventStatus_eIgnore; @@ -355,6 +360,7 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent, } if (mApzcForInputBlock) { + mApzcForInputBlock->GetGuid(aOutTargetGuid); // For computing the input for the APZC, used the cached transform. // This ensures that the sequence of touch points an APZC sees in an // input block are all in the same coordinate space. @@ -392,14 +398,34 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent, return ret; } +void +APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint, + LayoutDeviceIntPoint* aOutTransformedPoint) +{ + MOZ_ASSERT(aOutTransformedPoint); + nsRefPtr apzc = GetTargetAPZC(aPoint); + if (apzc && aOutTransformedPoint) { + gfx3DMatrix transformToApzc; + gfx3DMatrix transformToGecko; + GetInputTransforms(apzc, transformToApzc, transformToGecko); + gfx3DMatrix outTransform = transformToApzc * transformToGecko; + aOutTransformedPoint->x = aPoint.x; + aOutTransformedPoint->y = aPoint.y; + ApplyTransform(aOutTransformedPoint, outTransform); + } +} + + nsEventStatus APZCTreeManager::ProcessMouseEvent(const WidgetMouseEvent& aEvent, + ScrollableLayerGuid* aOutTargetGuid, WidgetMouseEvent* aOutEvent) { nsRefPtr apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y)); if (!apzc) { return nsEventStatus_eIgnore; } + apzc->GetGuid(aOutTargetGuid); gfx3DMatrix transformToApzc; gfx3DMatrix transformToGecko; GetInputTransforms(apzc, transformToApzc, transformToGecko); @@ -412,6 +438,7 @@ APZCTreeManager::ProcessMouseEvent(const WidgetMouseEvent& aEvent, nsEventStatus APZCTreeManager::ProcessEvent(const WidgetInputEvent& aEvent, + ScrollableLayerGuid* aOutTargetGuid, WidgetInputEvent* aOutEvent) { // Transform the refPoint @@ -419,6 +446,7 @@ APZCTreeManager::ProcessEvent(const WidgetInputEvent& aEvent, if (!apzc) { return nsEventStatus_eIgnore; } + apzc->GetGuid(aOutTargetGuid); gfx3DMatrix transformToApzc; gfx3DMatrix transformToGecko; GetInputTransforms(apzc, transformToApzc, transformToGecko); @@ -429,6 +457,7 @@ APZCTreeManager::ProcessEvent(const WidgetInputEvent& aEvent, nsEventStatus APZCTreeManager::ReceiveInputEvent(const WidgetInputEvent& aEvent, + ScrollableLayerGuid* aOutTargetGuid, WidgetInputEvent* aOutEvent) { MOZ_ASSERT(NS_IsMainThread()); @@ -436,32 +465,33 @@ APZCTreeManager::ReceiveInputEvent(const WidgetInputEvent& aEvent, switch (aEvent.eventStructType) { case NS_TOUCH_EVENT: { const WidgetTouchEvent& touchEvent = *aEvent.AsTouchEvent(); - return ProcessTouchEvent(touchEvent, aOutEvent->AsTouchEvent()); + return ProcessTouchEvent(touchEvent, aOutTargetGuid, aOutEvent->AsTouchEvent()); } case NS_MOUSE_EVENT: { // For b2g emulation const WidgetMouseEvent& mouseEvent = *aEvent.AsMouseEvent(); WidgetMouseEvent* outMouseEvent = aOutEvent->AsMouseEvent(); - return ProcessMouseEvent(mouseEvent, outMouseEvent); + return ProcessMouseEvent(mouseEvent, aOutTargetGuid, outMouseEvent); } default: { - return ProcessEvent(aEvent, aOutEvent); + return ProcessEvent(aEvent, aOutTargetGuid, aOutEvent); } } } nsEventStatus -APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent) +APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent, + ScrollableLayerGuid* aOutTargetGuid) { MOZ_ASSERT(NS_IsMainThread()); switch (aEvent.eventStructType) { case NS_TOUCH_EVENT: { WidgetTouchEvent& touchEvent = *aEvent.AsTouchEvent(); - return ProcessTouchEvent(touchEvent, &touchEvent); + return ProcessTouchEvent(touchEvent, aOutTargetGuid, &touchEvent); } default: { - return ProcessEvent(aEvent, &aEvent); + return ProcessEvent(aEvent, aOutTargetGuid, &aEvent); } } } @@ -567,7 +597,7 @@ APZCTreeManager::HandleOverscroll(AsyncPanZoomController* aChild, ScreenPoint aS } bool -APZCTreeManager::HitTestAPZC(const ScreenPoint& aPoint) +APZCTreeManager::HitTestAPZC(const ScreenIntPoint& aPoint) { MonitorAutoLock lock(mTreeLock); nsRefPtr target; diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h index 551f23ec71e8..c28a82726282 100644 --- a/gfx/layers/composite/APZCTreeManager.h +++ b/gfx/layers/composite/APZCTreeManager.h @@ -44,6 +44,14 @@ struct ScrollableLayerGuid { uint32_t mPresShellId; FrameMetrics::ViewID mScrollId; + ScrollableLayerGuid() + : mLayersId(0) + , mPresShellId(0) + , mScrollId(0) + { + MOZ_COUNT_CTOR(ScrollableLayerGuid); + } + ScrollableLayerGuid(uint64_t aLayersId, uint32_t aPresShellId, FrameMetrics::ViewID aScrollId) : mLayersId(aLayersId) @@ -142,8 +150,13 @@ public: * General handler for incoming input events. Manipulates the frame metrics * based on what type of input it is. For example, a PinchGestureEvent will * cause scaling. This should only be called externally to this class. + * + * @param aEvent input event object, will not be modified + * @param aOutTargetGuid returns the guid of the apzc this event was + * delivered to. May be null. */ - nsEventStatus ReceiveInputEvent(const InputData& aEvent); + nsEventStatus ReceiveInputEvent(const InputData& aEvent, + ScrollableLayerGuid* aOutTargetGuid); /** * WidgetInputEvent handler. Sets |aOutEvent| (which is assumed to be an @@ -158,9 +171,12 @@ public: * to the appropriate apz as such. * * @param aEvent input event object, will not be modified + * @param aOutTargetGuid returns the guid of the apzc this event was + * delivered to. May be null. * @param aOutEvent event object transformed to DOM coordinate space. */ nsEventStatus ReceiveInputEvent(const WidgetInputEvent& aEvent, + ScrollableLayerGuid* aOutTargetGuid, WidgetInputEvent* aOutEvent); /** @@ -168,8 +184,20 @@ public: * WidgetInputEvent. Must be called on the main thread. * * @param aEvent input event object + * @param aOutTargetGuid returns the guid of the apzc this event was + * delivered to. May be null. */ - nsEventStatus ReceiveInputEvent(WidgetInputEvent& aEvent); + nsEventStatus ReceiveInputEvent(WidgetInputEvent& aEvent, + ScrollableLayerGuid* aOutTargetGuid); + + /** + * A helper for transforming coordinates to gecko coordinate space. + * + * @param aPoint point to transform + * @param aOutTransformedPoint resulting transformed point + */ + void TransformCoordinateToGecko(const ScreenIntPoint& aPoint, + LayoutDeviceIntPoint* aOutTransformedPoint); /** * Updates the composition bounds, i.e. the dimensions of the final size of @@ -235,7 +263,7 @@ public: /** * Tests if a screen point intersect an apz in the tree. */ - bool HitTestAPZC(const ScreenPoint& aPoint); + bool HitTestAPZC(const ScreenIntPoint& aPoint); /** * Set the dpi value used by all AsyncPanZoomControllers. @@ -285,9 +313,9 @@ private: AsyncPanZoomController* CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2); AsyncPanZoomController* RootAPZCForLayersId(AsyncPanZoomController* aApzc); AsyncPanZoomController* GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, ScreenPoint aPoint); - nsEventStatus ProcessTouchEvent(const WidgetTouchEvent& touchEvent, WidgetTouchEvent* aOutEvent); - nsEventStatus ProcessMouseEvent(const WidgetMouseEvent& mouseEvent, WidgetMouseEvent* aOutEvent); - nsEventStatus ProcessEvent(const WidgetInputEvent& inputEvent, WidgetInputEvent* aOutEvent); + nsEventStatus ProcessTouchEvent(const WidgetTouchEvent& touchEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetTouchEvent* aOutEvent); + nsEventStatus ProcessMouseEvent(const WidgetMouseEvent& mouseEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetMouseEvent* aOutEvent); + nsEventStatus ProcessEvent(const WidgetInputEvent& inputEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetInputEvent* aOutEvent); /** * Recursive helper function to build the APZC tree. The tree of APZC instances has diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index af5f28c6b1a7..50768cd8ed27 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -1544,5 +1544,15 @@ bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid) return aGuid.mLayersId == mLayersId && aGuid.mScrollId == mFrameMetrics.mScrollId; } +void AsyncPanZoomController::GetGuid(ScrollableLayerGuid* aGuidOut) +{ + if (!aGuidOut) { + return; + } + aGuidOut->mLayersId = mLayersId; + aGuidOut->mScrollId = mFrameMetrics.mScrollId; + aGuidOut->mPresShellId = mFrameMetrics.mPresShellId; +} + } } diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index 92b8a1c5f3b6..69b648b05920 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -231,6 +231,11 @@ public: */ nsEventStatus HandleInputEvent(const InputData& aEvent); + /** + * Populates the provided object with the scrollable guid of this apzc. + */ + void GetGuid(ScrollableLayerGuid* aGuidOut); + /** * Returns true if this APZC instance is for the layer identified by the guid. */ diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 7e7968bb3cb6..af141779b42a 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -113,6 +113,25 @@ void ApzcPan(AsyncPanZoomController* apzc, int& aTime, int aTouchStartY, int aTo status = apzc->HandleInputEvent(mti); } +static void +ApzcPinch(AsyncPanZoomController* aApzc, int aFocusX, int aFocusY, float aScale) { + aApzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_START, + 0, + ScreenPoint(aFocusX, aFocusY), + 10.0, + 10.0)); + aApzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE, + 0, + ScreenPoint(aFocusX, aFocusY), + 10.0 * aScale, + 10.0)); + aApzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_END, + 0, + ScreenPoint(aFocusX, aFocusY), + 10.0 * aScale, + 10.0 * aScale)); +} + TEST(AsyncPanZoomController, Constructor) { // RefCounted class can't live in the stack nsRefPtr mcc = new MockContentController(); @@ -136,21 +155,7 @@ TEST(AsyncPanZoomController, Pinch) { EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(2); EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_START, - 0, - ScreenPoint(250, 300), - 10.0, - 10.0)); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE, - 0, - ScreenPoint(250, 300), - 12.5, - 10.0)); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_END, - 0, - ScreenPoint(250, 300), - 12.5, - 12.5)); + ApzcPinch(apzc, 250, 300, 1.25); // the visible area of the document in CSS pixels is now x=305 y=310 w=40 h=80 fm = apzc->GetFrameMetrics(); @@ -165,21 +170,7 @@ TEST(AsyncPanZoomController, Pinch) { apzc->SetFrameMetrics(fm); // the visible area of the document in CSS pixels is x=930 y=5 w=50 h=100 - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_START, - 0, - ScreenPoint(250, 300), - 10.0, - 10.0)); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE, - 0, - ScreenPoint(250, 300), - 5.0, - 10.0)); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_END, - 0, - ScreenPoint(250, 300), - 5.0, - 5.0)); + ApzcPinch(apzc, 250, 300, 0.5); // the visible area of the document in CSS pixels is now x=880 y=0 w=100 h=200 fm = apzc->GetFrameMetrics(); @@ -204,26 +195,14 @@ TEST(AsyncPanZoomController, Overzoom) { EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(1); EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_START, - 0, - ScreenPoint(50, 50), - 10.0, - 10.0)); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE, - 0, - ScreenPoint(50, 50), - 5.0, - 10.0)); - apzc->HandleInputEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_END, - 0, - ScreenPoint(50, 50), - 5.0, - 5.0)); + ApzcPinch(apzc, 50, 50, 0.5); fm = apzc->GetFrameMetrics(); EXPECT_EQ(fm.mZoom.scale, 0.8f); - EXPECT_EQ(fm.mScrollOffset.x, 0); - EXPECT_EQ(fm.mScrollOffset.y, 0); + // bug 936721 - PGO builds introduce rounding error so + // use a fuzzy match instead + EXPECT_LT(abs(fm.mScrollOffset.x), 1e-5); + EXPECT_LT(abs(fm.mScrollOffset.y), 1e-5); } TEST(AsyncPanZoomController, SimpleTransform) { diff --git a/intl/uconv/moz.build b/intl/uconv/moz.build index 4f09c49e7575..c14f218d81f9 100644 --- a/intl/uconv/moz.build +++ b/intl/uconv/moz.build @@ -7,7 +7,6 @@ DIRS += [ 'idl', 'public', - 'util', 'ucvja', 'ucvcn', 'ucvlatin', diff --git a/intl/uconv/src/Makefile.in b/intl/uconv/src/Makefile.in index 045a2b1c4a8f..9692903fe185 100644 --- a/intl/uconv/src/Makefile.in +++ b/intl/uconv/src/Makefile.in @@ -13,16 +13,6 @@ LOCAL_INCLUDES = -I$(srcdir)/../util \ -I$(srcdir)/../ucvcn \ $(NULL) -SHARED_LIBRARY_LIBS += \ - ../ucvlatin/$(LIB_PREFIX)ucvlatin_s.$(LIB_SUFFIX) \ - ../ucvibm/$(LIB_PREFIX)ucvibm_s.$(LIB_SUFFIX) \ - ../ucvja/$(LIB_PREFIX)ucvja_s.$(LIB_SUFFIX) \ - ../ucvtw2/$(LIB_PREFIX)ucvtw2_s.$(LIB_SUFFIX) \ - ../ucvtw/$(LIB_PREFIX)ucvtw_s.$(LIB_SUFFIX) \ - ../ucvko/$(LIB_PREFIX)ucvko_s.$(LIB_SUFFIX) \ - ../ucvcn/$(LIB_PREFIX)ucvcn_s.$(LIB_SUFFIX) \ - $(NULL) - include $(topsrcdir)/config/rules.mk ifneq (,$(INTEL_ARCHITECTURE)) diff --git a/intl/uconv/src/moz.build b/intl/uconv/src/moz.build index 0c4a2ce0b346..23de0db794b0 100644 --- a/intl/uconv/src/moz.build +++ b/intl/uconv/src/moz.build @@ -24,6 +24,197 @@ UNIFIED_SOURCES += [ 'nsUTF8ToUnicode.cpp', ] +UNIFIED_SOURCES += [ + '../ucvcn/nsGBKConvUtil.cpp', + '../ucvcn/nsGBKToUnicode.cpp', + '../ucvcn/nsHZToUnicode.cpp', + '../ucvcn/nsISO2022CNToUnicode.cpp', + '../ucvcn/nsUnicodeToGB2312V2.cpp', + '../ucvcn/nsUnicodeToGBK.cpp', + '../ucvcn/nsUnicodeToHZ.cpp', +] + +UNIFIED_SOURCES += [ + '../ucvibm/nsCP850ToUnicode.cpp', + '../ucvibm/nsCP852ToUnicode.cpp', + '../ucvibm/nsCP855ToUnicode.cpp', + '../ucvibm/nsCP857ToUnicode.cpp', + '../ucvibm/nsCP862ToUnicode.cpp', + '../ucvibm/nsCP864ToUnicode.cpp', + '../ucvibm/nsUnicodeToCP850.cpp', + '../ucvibm/nsUnicodeToCP852.cpp', + '../ucvibm/nsUnicodeToCP855.cpp', + '../ucvibm/nsUnicodeToCP857.cpp', + '../ucvibm/nsUnicodeToCP862.cpp', + '../ucvibm/nsUnicodeToCP864.cpp', +] + +UNIFIED_SOURCES += [ + '../ucvja/nsJapaneseToUnicode.cpp', + '../ucvja/nsUnicodeToEUCJP.cpp', + '../ucvja/nsUnicodeToISO2022JP.cpp', + '../ucvja/nsUnicodeToJISx0201.cpp', + '../ucvja/nsUnicodeToSJIS.cpp', +] + +UNIFIED_SOURCES += [ + '../ucvko/nsCP949ToUnicode.cpp', + '../ucvko/nsISO2022KRToUnicode.cpp', + '../ucvko/nsJohabToUnicode.cpp', + '../ucvko/nsUnicodeToCP949.cpp', + '../ucvko/nsUnicodeToJohab.cpp', +] + +UNIFIED_SOURCES += [ + '../ucvlatin/nsARMSCII8ToUnicode.cpp', + '../ucvlatin/nsAsciiToUnicode.cpp', + '../ucvlatin/nsCP1250ToUnicode.cpp', + '../ucvlatin/nsCP1251ToUnicode.cpp', + '../ucvlatin/nsCP1253ToUnicode.cpp', + '../ucvlatin/nsCP1254ToUnicode.cpp', + '../ucvlatin/nsCP1255ToUnicode.cpp', + '../ucvlatin/nsCP1256ToUnicode.cpp', + '../ucvlatin/nsCP1257ToUnicode.cpp', + '../ucvlatin/nsCP1258ToUnicode.cpp', + '../ucvlatin/nsCP866ToUnicode.cpp', + '../ucvlatin/nsCP874ToUnicode.cpp', + '../ucvlatin/nsISO885910ToUnicode.cpp', + '../ucvlatin/nsISO885911ToUnicode.cpp', + '../ucvlatin/nsISO885913ToUnicode.cpp', + '../ucvlatin/nsISO885914ToUnicode.cpp', + '../ucvlatin/nsISO885915ToUnicode.cpp', + '../ucvlatin/nsISO885916ToUnicode.cpp', + '../ucvlatin/nsISO88592ToUnicode.cpp', + '../ucvlatin/nsISO88593ToUnicode.cpp', + '../ucvlatin/nsISO88594ToUnicode.cpp', + '../ucvlatin/nsISO88595ToUnicode.cpp', + '../ucvlatin/nsISO88596EToUnicode.cpp', + '../ucvlatin/nsISO88596IToUnicode.cpp', + '../ucvlatin/nsISO88596ToUnicode.cpp', + '../ucvlatin/nsISO88597ToUnicode.cpp', + '../ucvlatin/nsISO88598EToUnicode.cpp', + '../ucvlatin/nsISO88598IToUnicode.cpp', + '../ucvlatin/nsISO88598ToUnicode.cpp', + '../ucvlatin/nsISO88599ToUnicode.cpp', + '../ucvlatin/nsISOIR111ToUnicode.cpp', + '../ucvlatin/nsKOI8RToUnicode.cpp', + '../ucvlatin/nsKOI8UToUnicode.cpp', + '../ucvlatin/nsMacArabicToUnicode.cpp', + '../ucvlatin/nsMacCEToUnicode.cpp', + '../ucvlatin/nsMacCroatianToUnicode.cpp', + '../ucvlatin/nsMacCyrillicToUnicode.cpp', + '../ucvlatin/nsMacDevanagariToUnicode.cpp', + '../ucvlatin/nsMacFarsiToUnicode.cpp', + '../ucvlatin/nsMacGreekToUnicode.cpp', + '../ucvlatin/nsMacGujaratiToUnicode.cpp', + '../ucvlatin/nsMacGurmukhiToUnicode.cpp', + '../ucvlatin/nsMacHebrewToUnicode.cpp', + '../ucvlatin/nsMacIcelandicToUnicode.cpp', + '../ucvlatin/nsMacRomanianToUnicode.cpp', + '../ucvlatin/nsMacTurkishToUnicode.cpp', + '../ucvlatin/nsMUTF7ToUnicode.cpp', + '../ucvlatin/nsT61ToUnicode.cpp', + '../ucvlatin/nsTCVN5712ToUnicode.cpp', + '../ucvlatin/nsTIS620ToUnicode.cpp', + '../ucvlatin/nsUnicodeToAdobeEuro.cpp', + '../ucvlatin/nsUnicodeToARMSCII8.cpp', + '../ucvlatin/nsUnicodeToAscii.cpp', + '../ucvlatin/nsUnicodeToCP1250.cpp', + '../ucvlatin/nsUnicodeToCP1251.cpp', + '../ucvlatin/nsUnicodeToCP1253.cpp', + '../ucvlatin/nsUnicodeToCP1254.cpp', + '../ucvlatin/nsUnicodeToCP1255.cpp', + '../ucvlatin/nsUnicodeToCP1256.cpp', + '../ucvlatin/nsUnicodeToCP1257.cpp', + '../ucvlatin/nsUnicodeToCP1258.cpp', + '../ucvlatin/nsUnicodeToCP866.cpp', + '../ucvlatin/nsUnicodeToCP874.cpp', + '../ucvlatin/nsUnicodeToISO885910.cpp', + '../ucvlatin/nsUnicodeToISO885911.cpp', + '../ucvlatin/nsUnicodeToISO885913.cpp', + '../ucvlatin/nsUnicodeToISO885914.cpp', + '../ucvlatin/nsUnicodeToISO885915.cpp', + '../ucvlatin/nsUnicodeToISO885916.cpp', + '../ucvlatin/nsUnicodeToISO88592.cpp', + '../ucvlatin/nsUnicodeToISO88593.cpp', + '../ucvlatin/nsUnicodeToISO88594.cpp', + '../ucvlatin/nsUnicodeToISO88595.cpp', + '../ucvlatin/nsUnicodeToISO88596.cpp', + '../ucvlatin/nsUnicodeToISO88596E.cpp', + '../ucvlatin/nsUnicodeToISO88596I.cpp', + '../ucvlatin/nsUnicodeToISO88597.cpp', + '../ucvlatin/nsUnicodeToISO88598.cpp', + '../ucvlatin/nsUnicodeToISO88598E.cpp', + '../ucvlatin/nsUnicodeToISO88598I.cpp', + '../ucvlatin/nsUnicodeToISO88599.cpp', + '../ucvlatin/nsUnicodeToISOIR111.cpp', + '../ucvlatin/nsUnicodeToKOI8R.cpp', + '../ucvlatin/nsUnicodeToKOI8U.cpp', + '../ucvlatin/nsUnicodeToMacArabic.cpp', + '../ucvlatin/nsUnicodeToMacCE.cpp', + '../ucvlatin/nsUnicodeToMacCroatian.cpp', + '../ucvlatin/nsUnicodeToMacCyrillic.cpp', + '../ucvlatin/nsUnicodeToMacDevanagari.cpp', + '../ucvlatin/nsUnicodeToMacFarsi.cpp', + '../ucvlatin/nsUnicodeToMacGreek.cpp', + '../ucvlatin/nsUnicodeToMacGujarati.cpp', + '../ucvlatin/nsUnicodeToMacGurmukhi.cpp', + '../ucvlatin/nsUnicodeToMacHebrew.cpp', + '../ucvlatin/nsUnicodeToMacIcelandic.cpp', + '../ucvlatin/nsUnicodeToMacRomanian.cpp', + '../ucvlatin/nsUnicodeToMacTurkish.cpp', + '../ucvlatin/nsUnicodeToMUTF7.cpp', + '../ucvlatin/nsUnicodeToSymbol.cpp', + '../ucvlatin/nsUnicodeToT61.cpp', + '../ucvlatin/nsUnicodeToTCVN5712.cpp', + '../ucvlatin/nsUnicodeToTIS620.cpp', + '../ucvlatin/nsUnicodeToTSCII.cpp', + '../ucvlatin/nsUnicodeToUserDefined.cpp', + '../ucvlatin/nsUnicodeToUTF16.cpp', + '../ucvlatin/nsUnicodeToUTF7.cpp', + '../ucvlatin/nsUnicodeToVISCII.cpp', + '../ucvlatin/nsUnicodeToVPS.cpp', + '../ucvlatin/nsUnicodeToZapfDingbat.cpp', + '../ucvlatin/nsUserDefinedToUnicode.cpp', + '../ucvlatin/nsUTF16ToUnicode.cpp', + '../ucvlatin/nsUTF7ToUnicode.cpp', + '../ucvlatin/nsVISCIIToUnicode.cpp', + '../ucvlatin/nsVPSToUnicode.cpp', +] + +UNIFIED_SOURCES += [ + '../ucvtw/nsBIG5HKSCSToUnicode.cpp', + '../ucvtw/nsBIG5ToUnicode.cpp', + '../ucvtw/nsUnicodeToBIG5.cpp', + '../ucvtw/nsUnicodeToBIG5HKSCS.cpp', + '../ucvtw/nsUnicodeToHKSCS.cpp', +] + +UNIFIED_SOURCES += [ + '../ucvtw2/nsEUCTWToUnicode.cpp', + '../ucvtw2/nsUnicodeToEUCTW.cpp', +] + +UNIFIED_SOURCES += [ + '../util/nsUCConstructors.cpp', + '../util/nsUCSupport.cpp', + '../util/nsUnicodeDecodeHelper.cpp', + '../util/nsUnicodeEncodeHelper.cpp', + '../util/ugen.c', + '../util/umap.c', + '../util/uscan.c', +] + +if CONFIG['OS_ARCH'] == 'OS2': + UNIFIED_SOURCES += [ + '../ucvibm/nsCP1125ToUnicode.cpp', + '../ucvibm/nsCP1131ToUnicode.cpp', + '../ucvibm/nsCP869ToUnicode.cpp', + '../ucvibm/nsUnicodeToCP1125.cpp', + '../ucvibm/nsUnicodeToCP1131.cpp', + '../ucvibm/nsUnicodeToCP869.cpp', + ] + if CONFIG['INTEL_ARCHITECTURE']: SOURCES += [ 'nsUTF8ToUnicodeSSE2.cpp', @@ -37,3 +228,7 @@ MSVC_ENABLE_PGO = True EXPORT_LIBRARY = True +LOCAL_INCLUDES += [ + '../util', +] + diff --git a/intl/uconv/ucvcn/moz.build b/intl/uconv/ucvcn/moz.build index 559442ff45e8..d6ecb0fca4ab 100644 --- a/intl/uconv/ucvcn/moz.build +++ b/intl/uconv/ucvcn/moz.build @@ -4,26 +4,6 @@ # 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/. -MODULE = 'ucvcn' - EXPORTS += [ 'nsUCvCnCID.h', ] - -UNIFIED_SOURCES += [ - 'nsGBKConvUtil.cpp', - 'nsGBKToUnicode.cpp', - 'nsHZToUnicode.cpp', - 'nsISO2022CNToUnicode.cpp', - 'nsUnicodeToGB2312V2.cpp', - 'nsUnicodeToGBK.cpp', - 'nsUnicodeToHZ.cpp', -] - -LIBRARY_NAME = 'ucvcn_s' - -LIBXUL_LIBRARY = True - -LOCAL_INCLUDES += [ - '../util', -] diff --git a/intl/uconv/ucvibm/moz.build b/intl/uconv/ucvibm/moz.build index 7f0dfb2aa8df..910b7ef474eb 100644 --- a/intl/uconv/ucvibm/moz.build +++ b/intl/uconv/ucvibm/moz.build @@ -4,41 +4,6 @@ # 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/. -MODULE = 'ucvibm' - EXPORTS += [ 'nsUCvIBMCID.h', ] - -UNIFIED_SOURCES += [ - 'nsCP850ToUnicode.cpp', - 'nsCP852ToUnicode.cpp', - 'nsCP855ToUnicode.cpp', - 'nsCP857ToUnicode.cpp', - 'nsCP862ToUnicode.cpp', - 'nsCP864ToUnicode.cpp', - 'nsUnicodeToCP850.cpp', - 'nsUnicodeToCP852.cpp', - 'nsUnicodeToCP855.cpp', - 'nsUnicodeToCP857.cpp', - 'nsUnicodeToCP862.cpp', - 'nsUnicodeToCP864.cpp', -] - -if CONFIG['OS_ARCH'] == 'OS2': - UNIFIED_SOURCES += [ - 'nsCP1125ToUnicode.cpp', - 'nsCP1131ToUnicode.cpp', - 'nsCP869ToUnicode.cpp', - 'nsUnicodeToCP1125.cpp', - 'nsUnicodeToCP1131.cpp', - 'nsUnicodeToCP869.cpp', - ] - -LIBRARY_NAME = 'ucvibm_s' - -LIBXUL_LIBRARY = True - -LOCAL_INCLUDES += [ - '../util', -] diff --git a/intl/uconv/ucvja/moz.build b/intl/uconv/ucvja/moz.build index 6d18f7458bf1..ac23d261a67f 100644 --- a/intl/uconv/ucvja/moz.build +++ b/intl/uconv/ucvja/moz.build @@ -4,25 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'ucvja' - EXPORTS += [ 'nsUCVJA2CID.h', 'nsUCVJACID.h', ] - -UNIFIED_SOURCES += [ - 'nsJapaneseToUnicode.cpp', - 'nsUnicodeToEUCJP.cpp', - 'nsUnicodeToISO2022JP.cpp', - 'nsUnicodeToJISx0201.cpp', - 'nsUnicodeToSJIS.cpp', -] - -LIBRARY_NAME = 'ucvja_s' - -LIBXUL_LIBRARY = True - -LOCAL_INCLUDES += [ - '../util', -] diff --git a/intl/uconv/ucvja/nsJapaneseToUnicode.cpp b/intl/uconv/ucvja/nsJapaneseToUnicode.cpp index 1fd2d4183479..b6c5a1a460d9 100644 --- a/intl/uconv/ucvja/nsJapaneseToUnicode.cpp +++ b/intl/uconv/ucvja/nsJapaneseToUnicode.cpp @@ -13,8 +13,6 @@ #include "mozilla/Assertions.h" -static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); - #ifdef XP_OS2 // HTML5-incompliant behavior for OS/2, see bug 108136 // This is bogus. The right fix would be working around the font problems @@ -388,6 +386,8 @@ NS_IMETHODIMP nsISO2022JPToUnicodeV2::Convert( const char * aSrc, int32_t * aSrcLen, PRUnichar * aDest, int32_t * aDestLen) { + static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); + static const uint16_t fbIdx[128] = { /* 0x8X */ diff --git a/intl/uconv/ucvko/moz.build b/intl/uconv/ucvko/moz.build index 913a76eb3450..a31fc5ae6493 100644 --- a/intl/uconv/ucvko/moz.build +++ b/intl/uconv/ucvko/moz.build @@ -4,24 +4,6 @@ # 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/. -MODULE = 'ucvko' - EXPORTS += [ 'nsUCvKOCID.h', ] - -UNIFIED_SOURCES += [ - 'nsCP949ToUnicode.cpp', - 'nsISO2022KRToUnicode.cpp', - 'nsJohabToUnicode.cpp', - 'nsUnicodeToCP949.cpp', - 'nsUnicodeToJohab.cpp', -] - -LIBRARY_NAME = 'ucvko_s' - -LIBXUL_LIBRARY = True - -LOCAL_INCLUDES += [ - '../util', -] diff --git a/intl/uconv/ucvko/nsISO2022KRToUnicode.cpp b/intl/uconv/ucvko/nsISO2022KRToUnicode.cpp index 703351c9207a..4edb8fe4ca45 100644 --- a/intl/uconv/ucvko/nsISO2022KRToUnicode.cpp +++ b/intl/uconv/ucvko/nsISO2022KRToUnicode.cpp @@ -7,10 +7,10 @@ #include "nsICharsetConverterManager.h" #include "nsServiceManagerUtils.h" -static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); - NS_IMETHODIMP nsISO2022KRToUnicode::Convert(const char * aSrc, int32_t * aSrcLen, PRUnichar * aDest, int32_t * aDestLen) { + static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); + const unsigned char* srcEnd = (unsigned char*)aSrc + *aSrcLen; const unsigned char* src =(unsigned char*) aSrc; PRUnichar* destEnd = aDest + *aDestLen; diff --git a/intl/uconv/ucvlatin/moz.build b/intl/uconv/ucvlatin/moz.build index e94c24e8bc7d..eb850cd23491 100644 --- a/intl/uconv/ucvlatin/moz.build +++ b/intl/uconv/ucvlatin/moz.build @@ -4,134 +4,6 @@ # 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/. -MODULE = 'ucvlatin' - EXPORTS += [ 'nsUCvLatinCID.h', ] - -UNIFIED_SOURCES += [ - 'nsARMSCII8ToUnicode.cpp', - 'nsAsciiToUnicode.cpp', - 'nsCP1250ToUnicode.cpp', - 'nsCP1251ToUnicode.cpp', - 'nsCP1253ToUnicode.cpp', - 'nsCP1254ToUnicode.cpp', - 'nsCP1255ToUnicode.cpp', - 'nsCP1256ToUnicode.cpp', - 'nsCP1257ToUnicode.cpp', - 'nsCP1258ToUnicode.cpp', - 'nsCP866ToUnicode.cpp', - 'nsCP874ToUnicode.cpp', - 'nsISO885910ToUnicode.cpp', - 'nsISO885911ToUnicode.cpp', - 'nsISO885913ToUnicode.cpp', - 'nsISO885914ToUnicode.cpp', - 'nsISO885915ToUnicode.cpp', - 'nsISO885916ToUnicode.cpp', - 'nsISO88592ToUnicode.cpp', - 'nsISO88593ToUnicode.cpp', - 'nsISO88594ToUnicode.cpp', - 'nsISO88595ToUnicode.cpp', - 'nsISO88596EToUnicode.cpp', - 'nsISO88596IToUnicode.cpp', - 'nsISO88596ToUnicode.cpp', - 'nsISO88597ToUnicode.cpp', - 'nsISO88598EToUnicode.cpp', - 'nsISO88598IToUnicode.cpp', - 'nsISO88598ToUnicode.cpp', - 'nsISO88599ToUnicode.cpp', - 'nsISOIR111ToUnicode.cpp', - 'nsKOI8RToUnicode.cpp', - 'nsKOI8UToUnicode.cpp', - 'nsMacArabicToUnicode.cpp', - 'nsMacCEToUnicode.cpp', - 'nsMacCroatianToUnicode.cpp', - 'nsMacCyrillicToUnicode.cpp', - 'nsMacDevanagariToUnicode.cpp', - 'nsMacFarsiToUnicode.cpp', - 'nsMacGreekToUnicode.cpp', - 'nsMacGujaratiToUnicode.cpp', - 'nsMacGurmukhiToUnicode.cpp', - 'nsMacHebrewToUnicode.cpp', - 'nsMacIcelandicToUnicode.cpp', - 'nsMacRomanianToUnicode.cpp', - 'nsMacTurkishToUnicode.cpp', - 'nsMUTF7ToUnicode.cpp', - 'nsT61ToUnicode.cpp', - 'nsTCVN5712ToUnicode.cpp', - 'nsTIS620ToUnicode.cpp', - 'nsUnicodeToAdobeEuro.cpp', - 'nsUnicodeToARMSCII8.cpp', - 'nsUnicodeToAscii.cpp', - 'nsUnicodeToCP1250.cpp', - 'nsUnicodeToCP1251.cpp', - 'nsUnicodeToCP1253.cpp', - 'nsUnicodeToCP1254.cpp', - 'nsUnicodeToCP1255.cpp', - 'nsUnicodeToCP1256.cpp', - 'nsUnicodeToCP1257.cpp', - 'nsUnicodeToCP1258.cpp', - 'nsUnicodeToCP866.cpp', - 'nsUnicodeToCP874.cpp', - 'nsUnicodeToISO885910.cpp', - 'nsUnicodeToISO885911.cpp', - 'nsUnicodeToISO885913.cpp', - 'nsUnicodeToISO885914.cpp', - 'nsUnicodeToISO885915.cpp', - 'nsUnicodeToISO885916.cpp', - 'nsUnicodeToISO88592.cpp', - 'nsUnicodeToISO88593.cpp', - 'nsUnicodeToISO88594.cpp', - 'nsUnicodeToISO88595.cpp', - 'nsUnicodeToISO88596.cpp', - 'nsUnicodeToISO88596E.cpp', - 'nsUnicodeToISO88596I.cpp', - 'nsUnicodeToISO88597.cpp', - 'nsUnicodeToISO88598.cpp', - 'nsUnicodeToISO88598E.cpp', - 'nsUnicodeToISO88598I.cpp', - 'nsUnicodeToISO88599.cpp', - 'nsUnicodeToISOIR111.cpp', - 'nsUnicodeToKOI8R.cpp', - 'nsUnicodeToKOI8U.cpp', - 'nsUnicodeToMacArabic.cpp', - 'nsUnicodeToMacCE.cpp', - 'nsUnicodeToMacCroatian.cpp', - 'nsUnicodeToMacCyrillic.cpp', - 'nsUnicodeToMacDevanagari.cpp', - 'nsUnicodeToMacFarsi.cpp', - 'nsUnicodeToMacGreek.cpp', - 'nsUnicodeToMacGujarati.cpp', - 'nsUnicodeToMacGurmukhi.cpp', - 'nsUnicodeToMacHebrew.cpp', - 'nsUnicodeToMacIcelandic.cpp', - 'nsUnicodeToMacRomanian.cpp', - 'nsUnicodeToMacTurkish.cpp', - 'nsUnicodeToMUTF7.cpp', - 'nsUnicodeToSymbol.cpp', - 'nsUnicodeToT61.cpp', - 'nsUnicodeToTCVN5712.cpp', - 'nsUnicodeToTIS620.cpp', - 'nsUnicodeToTSCII.cpp', - 'nsUnicodeToUserDefined.cpp', - 'nsUnicodeToUTF16.cpp', - 'nsUnicodeToUTF7.cpp', - 'nsUnicodeToVISCII.cpp', - 'nsUnicodeToVPS.cpp', - 'nsUnicodeToZapfDingbat.cpp', - 'nsUserDefinedToUnicode.cpp', - 'nsUTF16ToUnicode.cpp', - 'nsUTF7ToUnicode.cpp', - 'nsVISCIIToUnicode.cpp', - 'nsVPSToUnicode.cpp', -] - -LIBRARY_NAME = 'ucvlatin_s' - -LIBXUL_LIBRARY = True - -LOCAL_INCLUDES += [ - '../src', - '../util', -] diff --git a/intl/uconv/ucvtw/moz.build b/intl/uconv/ucvtw/moz.build index 79a8f2cd25bb..008929c9275d 100644 --- a/intl/uconv/ucvtw/moz.build +++ b/intl/uconv/ucvtw/moz.build @@ -4,24 +4,6 @@ # 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/. -MODULE = 'ucvtw' - EXPORTS += [ 'nsUCvTWCID.h', ] - -UNIFIED_SOURCES += [ - 'nsBIG5HKSCSToUnicode.cpp', - 'nsBIG5ToUnicode.cpp', - 'nsUnicodeToBIG5.cpp', - 'nsUnicodeToBIG5HKSCS.cpp', - 'nsUnicodeToHKSCS.cpp', -] - -LIBRARY_NAME = 'ucvtw_s' - -LIBXUL_LIBRARY = True - -LOCAL_INCLUDES += [ - '../util', -] diff --git a/intl/uconv/ucvtw2/moz.build b/intl/uconv/ucvtw2/moz.build index 1a969969c3c4..a9c8a10e4c59 100644 --- a/intl/uconv/ucvtw2/moz.build +++ b/intl/uconv/ucvtw2/moz.build @@ -4,21 +4,6 @@ # 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/. -MODULE = 'ucvtw2' - EXPORTS += [ 'nsUCvTW2CID.h', ] - -UNIFIED_SOURCES += [ - 'nsEUCTWToUnicode.cpp', - 'nsUnicodeToEUCTW.cpp', -] - -LIBRARY_NAME = 'ucvtw2_s' - -LIBXUL_LIBRARY = True - -LOCAL_INCLUDES += [ - '../util', -] diff --git a/intl/uconv/util/moz.build b/intl/uconv/util/moz.build deleted file mode 100644 index 76682feca4a8..000000000000 --- a/intl/uconv/util/moz.build +++ /dev/null @@ -1,29 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -MODULE = 'uconv' - -UNIFIED_SOURCES += [ - 'nsUCConstructors.cpp', - 'nsUCSupport.cpp', - 'nsUnicodeDecodeHelper.cpp', - 'nsUnicodeEncodeHelper.cpp', -] - -LIBRARY_NAME = 'ucvutil_s' - -LIBXUL_LIBRARY = True - -UNIFIED_SOURCES += [ - 'ugen.c', - 'umap.c', - 'uscan.c', -] - -MSVC_ENABLE_PGO = True - -EXPORT_LIBRARY = True - diff --git a/intl/unicharutil/src/moz.build b/intl/unicharutil/src/moz.build index b42b09b5a71c..f41b5e9dd991 100644 --- a/intl/unicharutil/src/moz.build +++ b/intl/unicharutil/src/moz.build @@ -6,7 +6,7 @@ MODULE = 'unicharutil' -SOURCES += [ +UNIFIED_SOURCES += [ 'nsCaseConversionImp2.cpp', 'nsCategoryImp.cpp', 'nsEntityConverter.cpp', diff --git a/intl/unicharutil/util/internal/moz.build b/intl/unicharutil/util/internal/moz.build index 7d3d5742cb26..6786712345c1 100644 --- a/intl/unicharutil/util/internal/moz.build +++ b/intl/unicharutil/util/internal/moz.build @@ -8,7 +8,7 @@ MODULE = 'unicharutil' include('../objs.mozbuild') -SOURCES += intl_unicharutil_util_cppsrcs +UNIFIED_SOURCES += intl_unicharutil_util_cppsrcs LIBRARY_NAME = 'unicharutil_s' diff --git a/intl/unicharutil/util/moz.build b/intl/unicharutil/util/moz.build index 3349a8964545..d32104e138c6 100644 --- a/intl/unicharutil/util/moz.build +++ b/intl/unicharutil/util/moz.build @@ -18,7 +18,7 @@ EXPORTS += [ include('objs.mozbuild') -SOURCES += intl_unicharutil_util_cppsrcs +UNIFIED_SOURCES += intl_unicharutil_util_cppsrcs LIBRARY_NAME = 'unicharutil_external_s' diff --git a/js/public/Class.h b/js/public/Class.h index 3c0851707371..c3f97e83b9c2 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -377,6 +377,11 @@ typedef bool typedef bool (* DeleteSpecialOp)(JSContext *cx, JS::HandleObject obj, HandleSpecialId sid, bool *succeeded); +typedef bool +(* WatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); + +typedef bool +(* UnwatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id); typedef JSObject * (* ObjectOp)(JSContext *cx, JS::HandleObject obj); @@ -465,6 +470,8 @@ struct ObjectOps DeletePropertyOp deleteProperty; DeleteElementOp deleteElement; DeleteSpecialOp deleteSpecial; + WatchOp watch; + UnwatchOp unwatch; JSNewEnumerateOp enumerate; ObjectOp thisObject; @@ -473,7 +480,7 @@ struct ObjectOps #define JS_NULL_OBJECT_OPS \ {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \ - nullptr,nullptr,nullptr,nullptr,nullptr,nullptr} + nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr} } // namespace js @@ -502,7 +509,7 @@ struct JSClass { JSNative construct; JSTraceOp trace; - void *reserved[40]; + void *reserved[42]; }; #define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot diff --git a/js/src/Makefile.in b/js/src/Makefile.in index af179f3ac852..58889ccf9130 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -179,8 +179,8 @@ ifeq (Linux,$(OS_TARGET)) EXTRA_DSO_LDOPTS += -Wl,-version-script,symverscript symverscript: symverscript.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - -DVERSION="$(subst -,_,$(LIBRARY_NAME))" $< > $@ + $(call py_action,preprocessor, \ + -DVERSION="$(subst -,_,$(LIBRARY_NAME))" $< -o $@) EXTRA_DEPS += symverscript endif @@ -526,14 +526,14 @@ JS_CONFIG_SUBSTITUTIONS=\ $(JS_CONFIG_NAME): js-config.in Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk $(topsrcdir)/config/rules.mk $(RM) $@.tmp - $(PYTHON) $(topsrcdir)/config/Preprocessor.py --marker % $(JS_CONFIG_SUBSTITUTIONS) $< > $@.tmp \ - && mv $@.tmp $@ && chmod +x $@ + $(call py_action,preprocessor,--marker % $(JS_CONFIG_SUBSTITUTIONS) $< -o $@.tmp) + mv $@.tmp $@ && chmod +x $@ SCRIPTS = $(JS_CONFIG_NAME) SDK_BINARY = $(JS_CONFIG_NAME) $(LIBRARY_NAME).pc: js.pc.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(JS_CONFIG_SUBSTITUTIONS) $< > $@ + $(call py_action,preprocessor,$(JS_CONFIG_SUBSTITUTIONS) $< -o $@) install:: $(LIBRARY_NAME).pc $(SYSINSTALL) $^ $(DESTDIR)$(libdir)/pkgconfig diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp index e65d928964a9..0314d2435c42 100644 --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -774,7 +774,7 @@ HashableValue::setValue(JSContext *cx, HandleValue v) { if (v.isString()) { // Atomize so that hash() and operator==() are fast and infallible. - JSString *str = AtomizeString(cx, v.toString(), DoNotInternAtom); + JSString *str = AtomizeString(cx, v.toString(), DoNotInternAtom); if (!str) return false; value = StringValue(str); diff --git a/js/src/builtin/Object.cpp b/js/src/builtin/Object.cpp index 1256b43227a5..70dd5d2161b0 100644 --- a/js/src/builtin/Object.cpp +++ b/js/src/builtin/Object.cpp @@ -525,9 +525,9 @@ obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp) #if JS_HAS_OBJ_WATCHPOINT -static bool -obj_watch_handler(JSContext *cx, JSObject *obj_, jsid id_, jsval old, - jsval *nvp, void *closure) +bool +js::WatchHandler(JSContext *cx, JSObject *obj_, jsid id_, JS::Value old, + JS::Value *nvp, void *closure) { RootedObject obj(cx, obj_); RootedId id(cx, id_); @@ -552,6 +552,15 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); + RootedObject obj(cx, ToObject(cx, args.thisv())); + if (!obj) + return false; + +#if 0 /* pending addressing Firebug's use of this method */ + if (!GlobalObject::warnOnceAboutWatch(cx, obj)) + return false; +#endif + if (args.length() <= 1) { js_ReportMissingArg(cx, args.calleev(), 1); return false; @@ -565,18 +574,16 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp) if (!ValueToId(cx, args[0], &propid)) return false; - RootedObject obj(cx, ToObject(cx, args.thisv())); - if (!obj) - return false; - RootedValue tmp(cx); unsigned attrs; if (!CheckAccess(cx, obj, propid, JSACC_WATCH, &tmp, &attrs)) return false; - args.rval().setUndefined(); + if (!JSObject::watch(cx, obj, propid, callable)) + return false; - return JS_SetWatchPoint(cx, obj, propid, obj_watch_handler, callable); + args.rval().setUndefined(); + return true; } static bool @@ -587,15 +594,25 @@ obj_unwatch(JSContext *cx, unsigned argc, Value *vp) RootedObject obj(cx, ToObject(cx, args.thisv())); if (!obj) return false; - args.rval().setUndefined(); + +#if 0 /* pending addressing Firebug's use of this method */ + if (!GlobalObject::warnOnceAboutWatch(cx, obj)) + return false; +#endif + RootedId id(cx); - if (argc != 0) { + if (args.length() != 0) { if (!ValueToId(cx, args[0], &id)) return false; } else { id = JSID_VOID; } - return JS_ClearWatchPoint(cx, obj, id, nullptr, nullptr); + + if (!JSObject::unwatch(cx, obj, id)) + return false; + + args.rval().setUndefined(); + return true; } #endif /* JS_HAS_OBJ_WATCHPOINT */ diff --git a/js/src/builtin/Object.h b/js/src/builtin/Object.h index 5e528f44aaac..39950d1b1b4f 100644 --- a/js/src/builtin/Object.h +++ b/js/src/builtin/Object.h @@ -8,7 +8,8 @@ #define builtin_Object_h #include "jsapi.h" -#include "js/Value.h" + +namespace JS { class Value; } namespace js { @@ -25,6 +26,10 @@ JSString * ObjectToSource(JSContext *cx, JS::HandleObject obj); #endif // JS_HAS_TOSOURCE +extern bool +WatchHandler(JSContext *cx, JSObject *obj, jsid id, JS::Value old, + JS::Value *nvp, void *closure); + } /* namespace js */ #endif /* builtin_Object_h */ diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 583de578c5fb..287272aa754f 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -2008,7 +2008,7 @@ TypedDatum::obj_deleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeeded) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; if (IsOwnId(cx, obj, id)) @@ -2169,6 +2169,7 @@ const Class TypedObject::class_ = { TypedDatum::obj_deleteProperty, TypedDatum::obj_deleteElement, TypedDatum::obj_deleteSpecial, + nullptr, nullptr, // watch/unwatch TypedDatum::obj_enumerate, nullptr, /* thisObject */ } @@ -2259,6 +2260,7 @@ const Class TypedHandle::class_ = { TypedDatum::obj_deleteProperty, TypedDatum::obj_deleteElement, TypedDatum::obj_deleteSpecial, + nullptr, nullptr, // watch/unwatch TypedDatum::obj_enumerate, nullptr, /* thisObject */ } diff --git a/js/src/config/Expression.py b/js/src/config/Expression.py deleted file mode 100644 index 3e91ae46858c..000000000000 --- a/js/src/config/Expression.py +++ /dev/null @@ -1,241 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -""" -Parses and evaluates simple statements for Preprocessor: - -Expression currently supports the following grammar, whitespace is ignored: - -expression : - and_cond ( '||' expression ) ? ; -and_cond: - test ( '&&' and_cond ) ? ; -test: - unary ( ( '==' | '!=' ) unary ) ? ; -unary : - '!'? value ; -value : - [0-9]+ # integer - | 'defined(' \w+ ')' - | \w+ # string identifier or value; -""" - -import re - -class Expression: - def __init__(self, expression_string): - """ - Create a new expression with this string. - The expression will already be parsed into an Abstract Syntax Tree. - """ - self.content = expression_string - self.offset = 0 - self.__ignore_whitespace() - self.e = self.__get_logical_or() - if self.content: - raise Expression.ParseError, self - - def __get_logical_or(self): - """ - Production: and_cond ( '||' expression ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("logical_op") - # test - rv.append(self.__get_logical_and()) - self.__ignore_whitespace() - if self.content[:2] != '||': - # no logical op needed, short cut to our prime element - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_logical_or()) - self.__ignore_whitespace() - return rv - - def __get_logical_and(self): - """ - Production: test ( '&&' and_cond ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("logical_op") - # test - rv.append(self.__get_equality()) - self.__ignore_whitespace() - if self.content[:2] != '&&': - # no logical op needed, short cut to our prime element - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_logical_and()) - self.__ignore_whitespace() - return rv - - def __get_equality(self): - """ - Production: unary ( ( '==' | '!=' ) unary ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("equality") - # unary - rv.append(self.__get_unary()) - self.__ignore_whitespace() - if not re.match('[=!]=', self.content): - # no equality needed, short cut to our prime unary - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_unary()) - self.__ignore_whitespace() - return rv - - def __get_unary(self): - """ - Production: '!'? value - """ - # eat whitespace right away, too - not_ws = re.match('!\s*', self.content) - if not not_ws: - return self.__get_value() - rv = Expression.__AST('not') - self.__strip(not_ws.end()) - rv.append(self.__get_value()) - self.__ignore_whitespace() - return rv - - def __get_value(self): - """ - Production: ( [0-9]+ | 'defined(' \w+ ')' | \w+ ) - Note that the order is important, and the expression is kind-of - ambiguous as \w includes 0-9. One could make it unambiguous by - removing 0-9 from the first char of a string literal. - """ - rv = None - m = re.match('defined\s*\(\s*(\w+)\s*\)', self.content) - if m: - word_len = m.end() - rv = Expression.__ASTLeaf('defined', m.group(1)) - else: - word_len = re.match('[0-9]*', self.content).end() - if word_len: - value = int(self.content[:word_len]) - rv = Expression.__ASTLeaf('int', value) - else: - word_len = re.match('\w*', self.content).end() - if word_len: - rv = Expression.__ASTLeaf('string', self.content[:word_len]) - else: - raise Expression.ParseError, self - self.__strip(word_len) - self.__ignore_whitespace() - return rv - - def __ignore_whitespace(self): - ws_len = re.match('\s*', self.content).end() - self.__strip(ws_len) - return - - def __strip(self, length): - """ - Remove a given amount of chars from the input and update - the offset. - """ - self.content = self.content[length:] - self.offset += length - - def evaluate(self, context): - """ - Evaluate the expression with the given context - """ - - # Helper function to evaluate __get_equality results - def eval_equality(tok): - left = opmap[tok[0].type](tok[0]) - right = opmap[tok[2].type](tok[2]) - rv = left == right - if tok[1].value == '!=': - rv = not rv - return rv - # Helper function to evaluate __get_logical_and and __get_logical_or results - def eval_logical_op(tok): - left = opmap[tok[0].type](tok[0]) - right = opmap[tok[2].type](tok[2]) - if tok[1].value == '&&': - return left and right - elif tok[1].value == '||': - return left or right - raise Expression.ParseError, self - - # Mapping from token types to evaluator functions - # Apart from (non-)equality, all these can be simple lambda forms. - opmap = { - 'logical_op': eval_logical_op, - 'equality': eval_equality, - 'not': lambda tok: not opmap[tok[0].type](tok[0]), - 'string': lambda tok: context[tok.value], - 'defined': lambda tok: tok.value in context, - 'int': lambda tok: tok.value} - - return opmap[self.e.type](self.e); - - class __AST(list): - """ - Internal class implementing Abstract Syntax Tree nodes - """ - def __init__(self, type): - self.type = type - super(self.__class__, self).__init__(self) - - class __ASTLeaf: - """ - Internal class implementing Abstract Syntax Tree leafs - """ - def __init__(self, type, value): - self.value = value - self.type = type - def __str__(self): - return self.value.__str__() - def __repr__(self): - return self.value.__repr__() - - class ParseError(StandardError): - """ - Error raised when parsing fails. - It has two members, offset and content, which give the offset of the - error and the offending content. - """ - def __init__(self, expression): - self.offset = expression.offset - self.content = expression.content[:3] - def __str__(self): - return 'Unexpected content at offset {0}, "{1}"'.format(self.offset, - self.content) - -class Context(dict): - """ - This class holds variable values by subclassing dict, and while it - truthfully reports True and False on - - name in context - - it returns the variable name itself on - - context["name"] - - to reflect the ambiguity between string literals and preprocessor - variables. - """ - def __getitem__(self, key): - if key in self: - return super(self.__class__, self).__getitem__(key) - return key diff --git a/js/src/config/Makefile.in b/js/src/config/Makefile.in index 25e470e46399..6195d37d8422 100644 --- a/js/src/config/Makefile.in +++ b/js/src/config/Makefile.in @@ -40,7 +40,7 @@ ifdef WRAP_SYSTEM_INCLUDES export:: \ $(call mkdir_deps,system_wrappers_js) \ $(NULL) - $(PYTHON) $(srcdir)/Preprocessor.py $(DEFINES) $(ACDEFINES) \ + $(PYTHON) -m mozbuild.action.preprocessor $(DEFINES) $(ACDEFINES) \ -DMOZ_NATIVE_ICU=$(MOZ_NATIVE_ICU) \ $(srcdir)/system-headers | $(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers_js $(INSTALL) system_wrappers_js $(DIST) diff --git a/js/src/config/Preprocessor.py b/js/src/config/Preprocessor.py deleted file mode 100755 index 86891acaf3c6..000000000000 --- a/js/src/config/Preprocessor.py +++ /dev/null @@ -1,492 +0,0 @@ -""" -This is a very primitive line based preprocessor, for times when using -a C preprocessor isn't an option. -""" - -# 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/. - -import sys -import os -import os.path -import re -from optparse import OptionParser -import errno - -# hack around win32 mangling our line endings -# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443 -if sys.platform == "win32": - import msvcrt - msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) - os.linesep = '\n' - -import Expression - -__all__ = ['Preprocessor', 'preprocess'] - - -class Preprocessor: - """ - Class for preprocessing text files. - """ - class Error(RuntimeError): - def __init__(self, cpp, MSG, context): - self.file = cpp.context['FILE'] - self.line = cpp.context['LINE'] - self.key = MSG - RuntimeError.__init__(self, (self.file, self.line, self.key, context)) - def __init__(self): - self.context = Expression.Context() - for k,v in {'FILE': '', - 'LINE': 0, - 'DIRECTORY': os.path.abspath('.')}.iteritems(): - self.context[k] = v - self.actionLevel = 0 - self.disableLevel = 0 - # ifStates can be - # 0: hadTrue - # 1: wantsTrue - # 2: #else found - self.ifStates = [] - self.checkLineNumbers = False - self.writtenLines = 0 - self.filters = [] - self.cmds = {} - for cmd, level in {'define': 0, - 'undef': 0, - 'if': sys.maxint, - 'ifdef': sys.maxint, - 'ifndef': sys.maxint, - 'else': 1, - 'elif': 1, - 'elifdef': 1, - 'elifndef': 1, - 'endif': sys.maxint, - 'expand': 0, - 'literal': 0, - 'filter': 0, - 'unfilter': 0, - 'include': 0, - 'includesubst': 0, - 'error': 0}.iteritems(): - self.cmds[cmd] = (level, getattr(self, 'do_' + cmd)) - self.out = sys.stdout - self.setMarker('#') - self.LE = '\n' - self.varsubst = re.compile('@(?P\w+)@', re.U) - - def warnUnused(self, file): - if self.actionLevel == 0: - sys.stderr.write('{0}: WARNING: no preprocessor directives found\n'.format(file)) - elif self.actionLevel == 1: - sys.stderr.write('{0}: WARNING: no useful preprocessor directives found\n'.format(file)) - pass - - def setLineEndings(self, aLE): - """ - Set the line endings to be used for output. - """ - self.LE = {'cr': '\x0D', 'lf': '\x0A', 'crlf': '\x0D\x0A'}[aLE] - - def setMarker(self, aMarker): - """ - Set the marker to be used for processing directives. - Used for handling CSS files, with pp.setMarker('%'), for example. - The given marker may be None, in which case no markers are processed. - """ - self.marker = aMarker - if aMarker: - self.instruction = re.compile('{0}(?P[a-z]+)(?:\s(?P.*))?$' - .format(aMarker), - re.U) - self.comment = re.compile(aMarker, re.U) - else: - class NoMatch(object): - def match(self, *args): - return False - self.instruction = self.comment = NoMatch() - - def clone(self): - """ - Create a clone of the current processor, including line ending - settings, marker, variable definitions, output stream. - """ - rv = Preprocessor() - rv.context.update(self.context) - rv.setMarker(self.marker) - rv.LE = self.LE - rv.out = self.out - return rv - - def applyFilters(self, aLine): - for f in self.filters: - aLine = f[1](aLine) - return aLine - - def write(self, aLine): - """ - Internal method for handling output. - """ - if self.checkLineNumbers: - self.writtenLines += 1 - ln = self.context['LINE'] - if self.writtenLines != ln: - self.out.write('//@line {line} "{file}"{le}'.format(line=ln, - file=self.context['FILE'], - le=self.LE)) - self.writtenLines = ln - filteredLine = self.applyFilters(aLine) - if filteredLine != aLine: - self.actionLevel = 2 - # ensure our line ending. Only need to handle \n, as we're reading - # with universal line ending support, at least for files. - filteredLine = re.sub('\n', self.LE, filteredLine) - self.out.write(filteredLine) - - def handleCommandLine(self, args, defaultToStdin = False): - """ - Parse a commandline into this parser. - Uses OptionParser internally, no args mean sys.argv[1:]. - """ - p = self.getCommandLineParser() - (options, args) = p.parse_args(args=args) - includes = options.I - if options.output: - dir = os.path.dirname(options.output) - if dir and not os.path.exists(dir): - try: - os.makedirs(dir) - except OSError as error: - if error.errno != errno.EEXIST: - raise - self.out = open(options.output, 'wb') - if defaultToStdin and len(args) == 0: - args = [sys.stdin] - includes.extend(args) - if includes: - for f in includes: - self.do_include(f, False) - self.warnUnused(f) - pass - - def getCommandLineParser(self, unescapeDefines = False): - escapedValue = re.compile('".*"$') - numberValue = re.compile('\d+$') - def handleE(option, opt, value, parser): - for k,v in os.environ.iteritems(): - self.context[k] = v - def handleD(option, opt, value, parser): - vals = value.split('=', 1) - if len(vals) == 1: - vals.append(1) - elif unescapeDefines and escapedValue.match(vals[1]): - # strip escaped string values - vals[1] = vals[1][1:-1] - elif numberValue.match(vals[1]): - vals[1] = int(vals[1]) - self.context[vals[0]] = vals[1] - def handleU(option, opt, value, parser): - del self.context[value] - def handleF(option, opt, value, parser): - self.do_filter(value) - def handleLE(option, opt, value, parser): - self.setLineEndings(value) - def handleMarker(option, opt, value, parser): - self.setMarker(value) - p = OptionParser() - p.add_option('-I', action='append', type="string", default = [], - metavar="FILENAME", help='Include file') - p.add_option('-E', action='callback', callback=handleE, - help='Import the environment into the defined variables') - p.add_option('-D', action='callback', callback=handleD, type="string", - metavar="VAR[=VAL]", help='Define a variable') - p.add_option('-U', action='callback', callback=handleU, type="string", - metavar="VAR", help='Undefine a variable') - p.add_option('-F', action='callback', callback=handleF, type="string", - metavar="FILTER", help='Enable the specified filter') - p.add_option('-o', '--output', type="string", default=None, - metavar="FILENAME", help='Output to the specified file '+ - 'instead of stdout') - p.add_option('--line-endings', action='callback', callback=handleLE, - type="string", metavar="[cr|lr|crlf]", - help='Use the specified line endings [Default: OS dependent]') - p.add_option('--marker', action='callback', callback=handleMarker, - type="string", - help='Use the specified marker instead of #') - return p - - def handleLine(self, aLine): - """ - Handle a single line of input (internal). - """ - if self.actionLevel == 0 and self.comment.match(aLine): - self.actionLevel = 1 - m = self.instruction.match(aLine) - if m: - args = None - cmd = m.group('cmd') - try: - args = m.group('args') - except IndexError: - pass - if cmd not in self.cmds: - raise Preprocessor.Error(self, 'INVALID_CMD', aLine) - level, cmd = self.cmds[cmd] - if (level >= self.disableLevel): - cmd(args) - if cmd != 'literal': - self.actionLevel = 2 - elif self.disableLevel == 0 and not self.comment.match(aLine): - self.write(aLine) - pass - - # Instruction handlers - # These are named do_'instruction name' and take one argument - - # Variables - def do_define(self, args): - m = re.match('(?P\w+)(?:\s(?P.*))?', args, re.U) - if not m: - raise Preprocessor.Error(self, 'SYNTAX_DEF', args) - val = 1 - if m.group('value'): - val = self.applyFilters(m.group('value')) - try: - val = int(val) - except: - pass - self.context[m.group('name')] = val - def do_undef(self, args): - m = re.match('(?P\w+)$', args, re.U) - if not m: - raise Preprocessor.Error(self, 'SYNTAX_DEF', args) - if args in self.context: - del self.context[args] - # Logic - def ensure_not_else(self): - if len(self.ifStates) == 0 or self.ifStates[-1] == 2: - sys.stderr.write('WARNING: bad nesting of #else\n') - def do_if(self, args, replace=False): - if self.disableLevel and not replace: - self.disableLevel += 1 - return - val = None - try: - e = Expression.Expression(args) - val = e.evaluate(self.context) - except Exception: - # XXX do real error reporting - raise Preprocessor.Error(self, 'SYNTAX_ERR', args) - if type(val) == str: - # we're looking for a number value, strings are false - val = False - if not val: - self.disableLevel = 1 - if replace: - if val: - self.disableLevel = 0 - self.ifStates[-1] = self.disableLevel - else: - self.ifStates.append(self.disableLevel) - pass - def do_ifdef(self, args, replace=False): - if self.disableLevel and not replace: - self.disableLevel += 1 - return - if re.match('\W', args, re.U): - raise Preprocessor.Error(self, 'INVALID_VAR', args) - if args not in self.context: - self.disableLevel = 1 - if replace: - if args in self.context: - self.disableLevel = 0 - self.ifStates[-1] = self.disableLevel - else: - self.ifStates.append(self.disableLevel) - pass - def do_ifndef(self, args, replace=False): - if self.disableLevel and not replace: - self.disableLevel += 1 - return - if re.match('\W', args, re.U): - raise Preprocessor.Error(self, 'INVALID_VAR', args) - if args in self.context: - self.disableLevel = 1 - if replace: - if args not in self.context: - self.disableLevel = 0 - self.ifStates[-1] = self.disableLevel - else: - self.ifStates.append(self.disableLevel) - pass - def do_else(self, args, ifState = 2): - self.ensure_not_else() - hadTrue = self.ifStates[-1] == 0 - self.ifStates[-1] = ifState # in-else - if hadTrue: - self.disableLevel = 1 - return - self.disableLevel = 0 - def do_elif(self, args): - if self.disableLevel == 1: - if self.ifStates[-1] == 1: - self.do_if(args, replace=True) - else: - self.do_else(None, self.ifStates[-1]) - def do_elifdef(self, args): - if self.disableLevel == 1: - if self.ifStates[-1] == 1: - self.do_ifdef(args, replace=True) - else: - self.do_else(None, self.ifStates[-1]) - def do_elifndef(self, args): - if self.disableLevel == 1: - if self.ifStates[-1] == 1: - self.do_ifndef(args, replace=True) - else: - self.do_else(None, self.ifStates[-1]) - def do_endif(self, args): - if self.disableLevel > 0: - self.disableLevel -= 1 - if self.disableLevel == 0: - self.ifStates.pop() - # output processing - def do_expand(self, args): - lst = re.split('__(\w+)__', args, re.U) - do_replace = False - def vsubst(v): - if v in self.context: - return str(self.context[v]) - return '' - for i in range(1, len(lst), 2): - lst[i] = vsubst(lst[i]) - lst.append('\n') # add back the newline - self.write(reduce(lambda x, y: x+y, lst, '')) - def do_literal(self, args): - self.write(args + self.LE) - def do_filter(self, args): - filters = [f for f in args.split(' ') if hasattr(self, 'filter_' + f)] - if len(filters) == 0: - return - current = dict(self.filters) - for f in filters: - current[f] = getattr(self, 'filter_' + f) - filterNames = current.keys() - filterNames.sort() - self.filters = [(fn, current[fn]) for fn in filterNames] - return - def do_unfilter(self, args): - filters = args.split(' ') - current = dict(self.filters) - for f in filters: - if f in current: - del current[f] - filterNames = current.keys() - filterNames.sort() - self.filters = [(fn, current[fn]) for fn in filterNames] - return - # Filters - # - # emptyLines - # Strips blank lines from the output. - def filter_emptyLines(self, aLine): - if aLine == '\n': - return '' - return aLine - # slashslash - # Strips everything after // - def filter_slashslash(self, aLine): - if (aLine.find('//') == -1): - return aLine - [aLine, rest] = aLine.split('//', 1) - if rest: - aLine += '\n' - return aLine - # spaces - # Collapses sequences of spaces into a single space - def filter_spaces(self, aLine): - return re.sub(' +', ' ', aLine).strip(' ') - # substition - # helper to be used by both substition and attemptSubstitution - def filter_substitution(self, aLine, fatal=True): - def repl(matchobj): - varname = matchobj.group('VAR') - if varname in self.context: - return str(self.context[varname]) - if fatal: - raise Preprocessor.Error(self, 'UNDEFINED_VAR', varname) - return matchobj.group(0) - return self.varsubst.sub(repl, aLine) - def filter_attemptSubstitution(self, aLine): - return self.filter_substitution(aLine, fatal=False) - # File ops - def do_include(self, args, filters=True): - """ - Preprocess a given file. - args can either be a file name, or a file-like object. - Files should be opened, and will be closed after processing. - """ - isName = type(args) == str or type(args) == unicode - oldWrittenLines = self.writtenLines - oldCheckLineNumbers = self.checkLineNumbers - self.checkLineNumbers = False - if isName: - try: - args = str(args) - if filters: - args = self.applyFilters(args) - if not os.path.isabs(args): - args = os.path.join(self.context['DIRECTORY'], args) - args = open(args, 'rU') - except Preprocessor.Error: - raise - except: - raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args)) - self.checkLineNumbers = bool(re.search('\.(js|jsm|java)(?:\.in)?$', args.name)) - oldFile = self.context['FILE'] - oldLine = self.context['LINE'] - oldDir = self.context['DIRECTORY'] - if args.isatty(): - # we're stdin, use '-' and '' for file and dir - self.context['FILE'] = '-' - self.context['DIRECTORY'] = '' - else: - abspath = os.path.abspath(args.name) - self.context['FILE'] = abspath - self.context['DIRECTORY'] = os.path.dirname(abspath) - self.context['LINE'] = 0 - self.writtenLines = 0 - for l in args: - self.context['LINE'] += 1 - self.handleLine(l) - args.close() - self.context['FILE'] = oldFile - self.checkLineNumbers = oldCheckLineNumbers - self.writtenLines = oldWrittenLines - self.context['LINE'] = oldLine - self.context['DIRECTORY'] = oldDir - def do_includesubst(self, args): - args = self.filter_substitution(args) - self.do_include(args) - def do_error(self, args): - raise Preprocessor.Error(self, 'Error: ', str(args)) - -def main(): - pp = Preprocessor() - pp.handleCommandLine(None, True) - return - -def preprocess(includes=[sys.stdin], defines={}, - output = sys.stdout, - line_endings='\n', marker='#'): - pp = Preprocessor() - pp.context.update(defines) - pp.setLineEndings(line_endings) - pp.setMarker(marker) - pp.out = output - for f in includes: - pp.do_include(f, False) - -if __name__ == "__main__": - main() diff --git a/js/src/config/rules.mk b/js/src/config/rules.mk index 3728cf28c023..5415605a1dca 100644 --- a/js/src/config/rules.mk +++ b/js/src/config/rules.mk @@ -53,7 +53,7 @@ else REPORT_BUILD = $(info $(shell $(PYTHON) $(MOZILLA_DIR)/config/rebuild_check.py $@ $^)) endif else -REPORT_BUILD = $(info $(notdir $@)) +REPORT_BUILD = $(info $(if $(filter $(DEPTH)/%,$@),$(@:$(DEPTH)/%=%),$(notdir $@))) endif ifeq ($(OS_ARCH),OS2) @@ -1481,6 +1481,11 @@ endif # # Additionally, a FOO_TARGET variable may be added to indicate the target for # which the files and executables are installed. Default is "libs". +# +# Finally, a FOO_KEEP_PATH variable may be set to 1 to indicate the paths given +# in FOO_FILES/FOO_EXECUTABLES are to be kept at the destination. That is, +# if FOO_FILES is bar/baz/qux.h, and FOO_DEST is $(DIST)/include, the installed +# file would be $(DIST)/include/bar/baz/qux.h instead of $(DIST)/include/qux.h # If we're using binary nsinstall and it's not built yet, fallback to python nsinstall. ifneq (,$(filter $(CONFIG_TOOLS)/nsinstall$(HOST_BIN_SUFFIX),$(install_cmd))) @@ -1493,22 +1498,52 @@ endef endif endif -define install_file_template -$(or $(3),libs):: $(2)/$(notdir $(1)) -$(call install_cmd_override,$(2)/$(notdir $(1))) -$(2)/$(notdir $(1)): $(1) - $$(call install_cmd,$(4) "$$<" "$${@D}") +install_target_tier = $(or $($(1)_TARGET),libs) +INSTALL_TARGETS_TIERS := $(sort $(foreach category,$(INSTALL_TARGETS),$(call install_target_tier,$(category)))) + +install_target_result = $($(1)_DEST:%/=%)/$(if $($(1)_KEEP_PATH),$(2),$(notdir $(2))) +install_target_files = $(foreach file,$($(1)_FILES),$(call install_target_result,$(category),$(file))) +install_target_executables = $(foreach file,$($(1)_EXECUTABLES),$(call install_target_result,$(category),$(file))) + +# Work around a GNU make 3.81 bug where it gives $< the wrong value. +# See details in bug 934864. +define create_dependency +$(1): $(2) +$(1): $(2) endef + +define install_target_template +$(call install_cmd_override,$(2)) +$(call create_dependency,$(2),$(1)) +endef + $(foreach category,$(INSTALL_TARGETS),\ - $(if $($(category)_DEST),,$(error Missing $(category)_DEST))\ - $(foreach file,$($(category)_FILES),\ - $(eval $(call install_file_template,$(file),$($(category)_DEST),$($(category)_TARGET),$(IFLAGS1)))\ - )\ - $(foreach file,$($(category)_EXECUTABLES),\ - $(eval $(call install_file_template,$(file),$($(category)_DEST),$($(category)_TARGET),$(IFLAGS2)))\ - )\ + $(if $($(category)_DEST),,$(error Missing $(category)_DEST)) \ + $(foreach tier,$(call install_target_tier,$(category)),\ + $(eval INSTALL_TARGETS_FILES_$(tier) += $(call install_target_files,$(category))) \ + $(eval INSTALL_TARGETS_EXECUTABLES_$(tier) += $(call install_target_executables,$(category))) \ + ) \ + $(foreach file,$($(category)_FILES) $($(category)_EXECUTABLES), \ + $(eval $(call install_target_template,$(file),$(call install_target_result,$(category),$(file)))) \ + ) \ ) +$(foreach tier,$(INSTALL_TARGETS_TIERS), \ + $(eval $(tier):: $(INSTALL_TARGETS_FILES_$(tier)) $(INSTALL_TARGETS_EXECUTABLES_$(tier))) \ +) + +install_targets_sanity = $(if $(filter-out $(notdir $@),$(notdir $(<))),$(error Looks like $@ has an unexpected dependency on $< which breaks INSTALL_TARGETS)) + +$(sort $(foreach tier,$(INSTALL_TARGETS_TIERS),$(INSTALL_TARGETS_FILES_$(tier)))): + $(install_targets_sanity) + $(REPORT_BUILD) + $(call install_cmd,$(IFLAGS1) "$<" "$(@D)") + +$(sort $(foreach tier,$(INSTALL_TARGETS_TIERS),$(INSTALL_TARGETS_EXECUTABLES_$(tier)))): + $(install_targets_sanity) + $(REPORT_BUILD) + $(call install_cmd,$(IFLAGS2) "$<" "$(@D)") + ################################################################################ # Preprocessing rules # @@ -1524,40 +1559,80 @@ $(foreach category,$(INSTALL_TARGETS),\ # If PP_TARGETS lists a category name (like FOO, above), then we consult the # following make variables to see what to do: # -# - lists input files to be preprocessed with config/Preprocessor.py. We -# search VPATH for the names given here. If an input file name ends in '.in', -# that suffix is omitted from the output file name. +# - lists input files to be preprocessed with mozbuild.action.preprocessor. +# We search VPATH for the names given here. If an input file name ends in +# '.in', that suffix is omitted from the output file name. # # - _PATH names the directory in which to place the preprocessed output # files. We create this directory if it does not already exist. Setting # this variable is optional; if unset, we install the files in $(CURDIR). # -# - _FLAGS lists flags to pass to Preprocessor.py, in addition to the usual -# bunch. Setting this variable is optional. +# - _FLAGS lists flags to pass to mozbuild.action.preprocessor, in addition +# to the usual bunch. Setting this variable is optional. # # - _TARGET names the 'make' target that should depend on creating the output # files. Setting this variable is optional; if unset, we preprocess the # files for the 'libs' target. +# +# - _KEEP_PATH may be set to 1 to indicate the paths given in are to be +# kept under _PATH. That is, if is bar/baz/qux.h.in and _PATH is +# $(DIST)/include, the preprocessed file would be $(DIST)/include/bar/baz/qux.h +# instead of $(DIST)/include/qux.h. -# preprocess_file_template defines preprocessing rules. -# $(call preprocess_file_template, source_file, output_file, -# makefile_target, extra_flags) -define preprocess_file_template -$(2): $(1) $$(GLOBAL_DEPS) - $$(RM) "$$@" - $$(PYTHON) $$(topsrcdir)/config/Preprocessor.py $(4) $$(DEFINES) $$(ACDEFINES) $$(XULPPFLAGS) "$$<" -o "$$@" -$(3):: $(2) -endef +pp_target_tier = $(or $($(1)_TARGET),libs) +PP_TARGETS_TIERS := $(sort $(foreach category,$(PP_TARGETS),$(call pp_target_tier,$(category)))) -$(foreach category,$(PP_TARGETS), \ - $(foreach file,$($(category)), \ - $(eval $(call preprocess_file_template, \ - $(file), \ - $(or $($(category)_PATH),$(CURDIR))/$(notdir $(file:.in=)), \ - $(or $($(category)_TARGET),libs), \ - $($(category)_FLAGS))) \ - ) \ - ) +pp_target_result = $(or $($(1)_PATH:%/=%),$(CURDIR))/$(if $($(1)_KEEP_PATH),$(2:.in=),$(notdir $(2:.in=))) +pp_target_results = $(foreach file,$($(1)),$(call pp_target_result,$(category),$(file))) + +$(foreach category,$(PP_TARGETS), \ + $(foreach tier,$(call pp_target_tier,$(category)), \ + $(eval PP_TARGETS_RESULTS_$(tier) += $(call pp_target_results,$(category))) \ + ) \ + $(foreach file,$($(category)), \ + $(eval $(call create_dependency,$(call pp_target_result,$(category),$(file)), \ + $(file) $(GLOBAL_DEPS))) \ + ) \ + $(eval $(call pp_target_results,$(category)): PP_TARGET_FLAGS=$($(category)_FLAGS)) \ +) + +$(foreach tier,$(PP_TARGETS_TIERS), \ + $(eval $(tier):: $(PP_TARGETS_RESULTS_$(tier))) \ +) + +PP_TARGETS_ALL_RESULTS := $(sort $(foreach tier,$(PP_TARGETS_TIERS),$(PP_TARGETS_RESULTS_$(tier)))) +$(PP_TARGETS_ALL_RESULTS): + $(if $(filter-out $(notdir $@),$(notdir $(<:.in=))),$(error Looks like $@ has an unexpected dependency on $< which breaks PP_TARGETS)) + $(REPORT_BUILD) + $(RM) "$@" + $(call py_action,preprocessor,--depend $(MDDEPDIR)/$(@F).pp $(PP_TARGET_FLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) "$<" -o "$@") + +# The depfile is based on the filename, and we don't want conflicts. So check +# there's only one occurrence of any given filename in PP_TARGETS_ALL_RESULTS. +PP_TARGETS_ALL_RESULT_NAMES := $(notdir $(PP_TARGETS_ALL_RESULTS)) +$(foreach file,$(sort $(PP_TARGETS_ALL_RESULT_NAMES)), \ + $(if $(filter-out 1,$(words $(filter $(file),$(PP_TARGETS_ALL_RESULT_NAMES)))), \ + $(error Multiple preprocessing rules are creating a $(file) file) \ + ) \ +) + +ifneq (,$(filter $(PP_TARGETS_TIERS) $(PP_TARGETS_ALL_RESULTS),$(MAKECMDGOALS))) +# If the depfile for a preprocessed file doesn't exist, add a dep to force +# re-preprocessing. +$(foreach file,$(PP_TARGETS_ALL_RESULTS), \ + $(if $(wildcard $(MDDEPDIR)/$(notdir $(file)).pp), \ + , \ + $(eval $(file): FORCE) \ + ) \ +) + +MDDEPEND_FILES := $(strip $(wildcard $(addprefix $(MDDEPDIR)/,$(addsuffix .pp,$(notdir $(PP_TARGETS_ALL_RESULTS)))))) + +ifneq (,$(MDDEPEND_FILES)) +$(call include_deps,$(MDDEPEND_FILES)) +endif + +endif # Pull in non-recursive targets if this is a partial tree build. ifndef TOPLEVEL_BUILD diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 433ddef311a9..c0fc473f71b5 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -282,7 +282,7 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco * Save eval program source in script->atoms[0] for the * eval cache (see EvalCacheLookup in jsobj.cpp). */ - JSAtom *atom = AtomizeString(cx, source); + JSAtom *atom = AtomizeString(cx, source); jsatomid _; if (!atom || !bce.makeAtomIndex(atom, &_)) return nullptr; diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp index a551798be536..ffbfe2f0e2fd 100644 --- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -91,7 +91,7 @@ FoldType(ExclusiveContext *cx, ParseNode *pn, ParseNodeKind kind) case PNK_STRING: if (pn->isKind(PNK_NUMBER)) { - pn->pn_atom = NumberToAtom(cx, pn->pn_dval); + pn->pn_atom = NumberToAtom(cx, pn->pn_dval); if (!pn->pn_atom) return false; pn->setKind(PNK_STRING); @@ -593,7 +593,7 @@ Fold(ExclusiveContext *cx, ParseNode **pnp, JS_ASSERT(*chars == 0); /* Atomize the result string and mutate pn to refer to it. */ - pn->pn_atom = AtomizeString(cx, str); + pn->pn_atom = AtomizeString(cx, str); if (!pn->pn_atom) return false; pn->setKind(PNK_STRING); @@ -614,7 +614,7 @@ Fold(ExclusiveContext *cx, ParseNode **pnp, RootedString str(cx, ConcatStrings(cx, left, right)); if (!str) return false; - pn->pn_atom = AtomizeString(cx, str); + pn->pn_atom = AtomizeString(cx, str); if (!pn->pn_atom) return false; pn->setKind(PNK_STRING); diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index 9aee0dd6b696..1fe045a8fcfb 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -909,7 +909,7 @@ TokenStream::newToken(ptrdiff_t adjust) JS_ALWAYS_INLINE JSAtom * TokenStream::atomize(ExclusiveContext *cx, CharBuffer &cb) { - return AtomizeChars(cx, cb.begin(), cb.length()); + return AtomizeChars(cx, cb.begin(), cb.length()); } #ifdef DEBUG @@ -1178,7 +1178,7 @@ TokenStream::getTokenInternal(Modifier modifier) goto out; } - JSAtom *atom = AtomizeChars(cx, chars, length); + JSAtom *atom = AtomizeChars(cx, chars, length); if (!atom) goto error; tp->type = TOK_NAME; diff --git a/js/src/jit/AsmJSModule.cpp b/js/src/jit/AsmJSModule.cpp index 47a6c2182015..7deff84363d7 100644 --- a/js/src/jit/AsmJSModule.cpp +++ b/js/src/jit/AsmJSModule.cpp @@ -478,7 +478,7 @@ DeserializeName(ExclusiveContext *cx, const uint8_t *cursor, PropertyName **name src = (jschar *)cursor; } - JSAtom *atom = AtomizeChars(cx, src, length); + JSAtom *atom = AtomizeChars(cx, src, length); if (!atom) return nullptr; diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index b620fe22877a..3f11881ff48d 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -108,7 +108,7 @@ BaselineCompiler::compile() return Method_Error; Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::BASELINE_CODE); + IonCode *code = linker.newCode(cx, JSC::BASELINE_CODE); if (!code) return Method_Error; diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index a071e4846ef8..339c5560b71d 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -587,7 +587,7 @@ ICStubCompiler::getStubCode() if (!generateStubCode(masm)) return nullptr; Linker linker(masm); - Rooted newStubCode(cx, linker.newCode(cx, JSC::BASELINE_CODE)); + Rooted newStubCode(cx, linker.newCode(cx, JSC::BASELINE_CODE)); if (!newStubCode) return nullptr; diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index d1a1f320854f..001c45f7aa93 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -4580,7 +4580,7 @@ JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode) masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "StringConcatStub"); @@ -5800,7 +5800,7 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) Linker linker(masm); IonCode *code = (executionMode == SequentialExecution) ? linker.newCodeForIonScript(cx) - : linker.newCode(cx, JSC::ION_CODE); + : linker.newCode(cx, JSC::ION_CODE); if (!code) { // Use js_free instead of IonScript::Destroy: the cache list and // backedge list are still uninitialized. diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 355edff2e08c..4425cd05fca2 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -606,10 +606,11 @@ JitRuntime::getVMWrapper(const VMFunction &f) return p->value; } +template IonCode * IonCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool) { - IonCode *codeObj = gc::NewGCThing(cx, gc::FINALIZE_IONCODE, sizeof(IonCode), gc::DefaultHeap); + IonCode *codeObj = gc::NewGCThing(cx, gc::FINALIZE_IONCODE, sizeof(IonCode), gc::DefaultHeap); if (!codeObj) { pool->release(); return nullptr; @@ -619,6 +620,14 @@ IonCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutableP return codeObj; } +template +IonCode * +IonCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); + +template +IonCode * +IonCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); + void IonCode::copyFrom(MacroAssembler &masm) { diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index c77f51d1f2d6..e271d87de81a 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -106,7 +106,7 @@ IonCache::LinkStatus IonCache::linkCode(JSContext *cx, MacroAssembler &masm, IonScript *ion, IonCode **code) { Linker linker(masm); - *code = linker.newCode(cx, JSC::ION_CODE); + *code = linker.newCode(cx, JSC::ION_CODE); if (!*code) return LINK_ERROR; diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index d9c8d3e11368..314cda55f2ae 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -131,6 +131,7 @@ class IonCode : public gc::BarrieredCell // Allocates a new IonCode object which will be managed by the GC. If no // object can be allocated, nullptr is returned. On failure, |pool| is // automatically released, so the code may be freed. + template static IonCode *New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); public: diff --git a/js/src/jit/IonLinker.h b/js/src/jit/IonLinker.h index 8446f7f38a44..362310fc5ed9 100644 --- a/js/src/jit/IonLinker.h +++ b/js/src/jit/IonLinker.h @@ -28,6 +28,7 @@ class Linker return nullptr; } + template IonCode *newCode(JSContext *cx, JSC::ExecutableAllocator *execAlloc, JSC::CodeKind kind) { JS_ASSERT(kind == JSC::ION_CODE || kind == JSC::BASELINE_CODE || @@ -53,8 +54,8 @@ class Linker // Bump the code up to a nice alignment. codeStart = (uint8_t *)AlignBytes((uintptr_t)codeStart, CodeAlignment); uint32_t headerSize = codeStart - result; - IonCode *code = IonCode::New(cx, codeStart, - bytesNeeded - headerSize, pool); + IonCode *code = IonCode::New(cx, codeStart, + bytesNeeded - headerSize, pool); if (!code) return nullptr; if (masm.oom()) @@ -75,14 +76,15 @@ class Linker masm.finish(); } + template IonCode *newCode(JSContext *cx, JSC::CodeKind kind) { - return newCode(cx, cx->compartment()->jitCompartment()->execAlloc(), kind); + return newCode(cx, cx->compartment()->jitCompartment()->execAlloc(), kind); } IonCode *newCodeForIonScript(JSContext *cx) { #ifdef JS_CPU_ARM // ARM does not yet use implicit interrupt checks, see bug 864220. - return newCode(cx, JSC::ION_CODE); + return newCode(cx, JSC::ION_CODE); #else // The caller must lock the runtime against operation callback triggers, // as the triggering thread may use the executable allocator below. @@ -92,7 +94,7 @@ class Linker if (!alloc) return nullptr; - return newCode(cx, alloc, JSC::ION_CODE); + return newCode(cx, alloc, JSC::ION_CODE); #endif } }; diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 65f637df0854..2e023c1d6477 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -617,7 +617,7 @@ GetDynamicName(JSContext *cx, JSObject *scopeChain, JSString *str, Value *vp) if (str->isAtom()) { atom = &str->asAtom(); } else { - atom = AtomizeString(cx, str); + atom = AtomizeString(cx, str); if (!atom) { vp->setUndefined(); return; diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index cbe0faa9efce..0b19d004c958 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -339,7 +339,7 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) GenerateReturn(masm, true); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "EnterJIT"); @@ -400,7 +400,7 @@ JitRuntime::generateInvalidator(JSContext *cx) masm.branch(bailoutTail); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); IonSpew(IonSpew_Invalidate, " invalidation thunk created at %p", (void *) code->raw()); #ifdef JS_ION_PERF @@ -502,7 +502,7 @@ JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); CodeOffsetLabel returnLabel(returnOffset); returnLabel.fixup(&masm); @@ -626,7 +626,7 @@ JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) GenerateBailoutThunk(cx, masm, frameClass); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutTable"); @@ -642,7 +642,7 @@ JitRuntime::generateBailoutHandler(JSContext *cx) GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutHandler"); @@ -815,7 +815,7 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) f.extraValuesToPop * sizeof(Value))); Linker linker(masm); - IonCode *wrapper = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *wrapper = linker.newCode(cx, JSC::OTHER_CODE); if (!wrapper) return nullptr; @@ -863,7 +863,7 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type) masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "PreBarrier"); @@ -918,7 +918,7 @@ JitRuntime::generateDebugTrapHandler(JSContext *cx) masm.ret(); Linker linker(masm); - IonCode *codeDbg = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *codeDbg = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(codeDbg, "DebugTrapHandler"); @@ -935,7 +935,7 @@ JitRuntime::generateExceptionTailStub(JSContext *cx) masm.handleFailureWithHandlerTail(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "ExceptionTailStub"); @@ -952,7 +952,7 @@ JitRuntime::generateBailoutTailStub(JSContext *cx) masm.generateBailoutTail(r1, r2); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutTailStub"); diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index 1d027c999eaf..c73d4d31bdce 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -292,7 +292,7 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "EnterJIT"); @@ -341,7 +341,7 @@ JitRuntime::generateInvalidator(JSContext *cx) masm.jmp(bailoutTail); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "Invalidator"); @@ -425,7 +425,7 @@ JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "ArgumentsRectifier"); @@ -491,7 +491,7 @@ JitRuntime::generateBailoutHandler(JSContext *cx) GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutHandler"); @@ -671,7 +671,7 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) f.extraValuesToPop * sizeof(Value))); Linker linker(masm); - IonCode *wrapper = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *wrapper = linker.newCode(cx, JSC::OTHER_CODE); if (!wrapper) return nullptr; @@ -713,7 +713,7 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type) masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "PreBarrier"); @@ -772,7 +772,7 @@ JitRuntime::generateDebugTrapHandler(JSContext *cx) masm.ret(); Linker linker(masm); - IonCode *codeDbg = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *codeDbg = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(codeDbg, "DebugTrapHandler"); @@ -789,7 +789,7 @@ JitRuntime::generateExceptionTailStub(JSContext *cx) masm.handleFailureWithHandlerTail(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "ExceptionTailStub"); @@ -806,7 +806,7 @@ JitRuntime::generateBailoutTailStub(JSContext *cx) masm.generateBailoutTail(rdx, r9); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutTailStub"); diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index 3a3bf8a0048c..30f601835fe4 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -275,7 +275,7 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "EnterJIT"); @@ -332,7 +332,7 @@ JitRuntime::generateInvalidator(JSContext *cx) masm.jmp(bailoutTail); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); IonSpew(IonSpew_Invalidate, " invalidation thunk created at %p", (void *) code->raw()); #ifdef JS_ION_PERF @@ -429,7 +429,7 @@ JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "ArgumentsRectifier"); @@ -509,7 +509,7 @@ JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) GenerateBailoutThunk(cx, masm, frameClass); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutHandler"); @@ -526,7 +526,7 @@ JitRuntime::generateBailoutHandler(JSContext *cx) GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutHandler"); @@ -700,7 +700,7 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) f.extraValuesToPop * sizeof(Value))); Linker linker(masm); - IonCode *wrapper = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *wrapper = linker.newCode(cx, JSC::OTHER_CODE); if (!wrapper) return nullptr; @@ -749,7 +749,7 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type) masm.ret(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "PreBarrier"); @@ -808,7 +808,7 @@ JitRuntime::generateDebugTrapHandler(JSContext *cx) masm.ret(); Linker linker(masm); - IonCode *codeDbg = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *codeDbg = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(codeDbg, "DebugTrapHandler"); @@ -825,7 +825,7 @@ JitRuntime::generateExceptionTailStub(JSContext *cx) masm.handleFailureWithHandlerTail(); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "ExceptionTailStub"); @@ -842,7 +842,7 @@ JitRuntime::generateBailoutTailStub(JSContext *cx) masm.generateBailoutTail(edx, ecx); Linker linker(masm); - IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); + IonCode *code = linker.newCode(cx, JSC::OTHER_CODE); #ifdef JS_ION_PERF writePerfSpewerIonCodeProfile(code, "BailoutTailStub"); diff --git a/js/src/js.msg b/js/src/js.msg index 8bd4f8bd0556..296811dcc926 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -244,7 +244,7 @@ MSG_DEF(JSMSG_UNUSED190, 190, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED191, 191, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED192, 192, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 193, 0, JSEXN_SYNTAXERR, "invalid for each loop") -MSG_DEF(JSMSG_UNUSED194, 194, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_OBJECT_WATCH_DEPRECATED,194, 0, JSEXN_TYPEERR, "Object.prototype.watch and unwatch are very slow, non-standard, and deprecated; use a getter/setter instead") MSG_DEF(JSMSG_UNUSED195, 195, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED196, 196, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_INTERNAL_INTL_ERROR, 197, 0, JSEXN_ERR, "internal error while computing Intl data") diff --git a/js/src/jsapi-tests/testStringBuffer.cpp b/js/src/jsapi-tests/testStringBuffer.cpp index b506a4cc9e08..1442e8de40ff 100644 --- a/js/src/jsapi-tests/testStringBuffer.cpp +++ b/js/src/jsapi-tests/testStringBuffer.cpp @@ -15,7 +15,7 @@ BEGIN_TEST(testStringBuffer_finishString) JSString *str = JS_NewStringCopyZ(cx, "foopy"); CHECK(str); - JS::Rooted atom(cx, js::AtomizeString(cx, str)); + JS::Rooted atom(cx, js::AtomizeString(cx, str)); CHECK(atom); js::StringBuffer buffer(cx); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 7eb1e8c432ef..1307c215db6a 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2766,7 +2766,7 @@ JS_LookupElement(JSContext *cx, JSObject *objArg, uint32_t index, MutableHandleV RootedObject obj(cx, objArg); CHECK_REQUEST(cx); RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return JS_LookupPropertyById(cx, obj, id, vp); } @@ -2784,7 +2784,7 @@ JS_LookupUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, size_t MutableHandleValue vp) { RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); return atom && JS_LookupPropertyById(cx, obj, AtomToId(atom), vp); } @@ -2841,7 +2841,7 @@ JS_HasElement(JSContext *cx, JSObject *objArg, uint32_t index, bool *foundp) AssertHeapIsIdle(cx); CHECK_REQUEST(cx); RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return JS_HasPropertyById(cx, obj, id, foundp); } @@ -2858,7 +2858,7 @@ JS_PUBLIC_API(bool) JS_HasUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen, bool *foundp) { RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); return atom && JS_HasPropertyById(cx, obj, AtomToId(atom), foundp); } @@ -2897,7 +2897,7 @@ JS_AlreadyHasOwnElement(JSContext *cx, JSObject *objArg, uint32_t index, bool *f AssertHeapIsIdle(cx); CHECK_REQUEST(cx); RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp); } @@ -2915,7 +2915,7 @@ JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, bool *foundp) { RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); return atom && JS_AlreadyHasOwnPropertyById(cx, obj, AtomToId(atom), foundp); } @@ -3039,7 +3039,7 @@ JS_DefineElement(JSContext *cx, JSObject *objArg, uint32_t index, jsval valueArg AssertHeapIsIdle(cx); CHECK_REQUEST(cx); RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter), SetterWrapper(setter), attrs, 0, 0); @@ -3095,7 +3095,7 @@ DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t nam { RootedValue value(cx, value_); AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); if (!atom) return false; RootedId id(cx, AtomToId(atom)); @@ -3357,7 +3357,7 @@ JS_GetUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, size_t nam MutableHandleValue vp) { RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); return atom && JS_GetPropertyById(cx, obj, AtomToId(atom), vp); } @@ -3400,7 +3400,7 @@ JS_SetUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, size_t nam HandleValue v) { RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); return atom && JS_SetPropertyById(cx, obj, AtomToId(atom), v); } @@ -3475,7 +3475,7 @@ JS_DeleteUCProperty2(JSContext *cx, JSObject *objArg, const jschar *name, size_t assertSameCompartment(cx, obj); JSAutoResolveFlags rf(cx, 0); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); if (!atom) return false; @@ -4140,7 +4140,7 @@ JS_DefineUCFunction(JSContext *cx, JSObject *objArg, AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); + JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); if (!atom) return nullptr; Rooted id(cx, AtomToId(atom)); @@ -5167,7 +5167,7 @@ JS_InternJSString(JSContext *cx, HandleString str) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); - JSAtom *atom = AtomizeString(cx, str, InternAtom); + JSAtom *atom = AtomizeString(cx, str, InternAtom); JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom)); return atom; } @@ -5219,7 +5219,7 @@ JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); - JSAtom *atom = AtomizeChars(cx, s, length, InternAtom); + JSAtom *atom = AtomizeChars(cx, s, length, InternAtom); JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom)); return atom; } @@ -6067,13 +6067,13 @@ BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) JS_PUBLIC_API(bool) JS_IndexToId(JSContext *cx, uint32_t index, MutableHandleId id) { - return IndexToId(cx, index, id); + return IndexToId(cx, index, id.address()); } JS_PUBLIC_API(bool) JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, MutableHandleId idp) { - RootedAtom atom(cx, AtomizeChars(cx, chars.start().get(), chars.length())); + RootedAtom atom(cx, AtomizeChars(cx, chars.start().get(), chars.length())); if (!atom) return false; #ifdef DEBUG diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 5a20ba3429f7..1b05c9ef87ec 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -137,7 +137,7 @@ static bool DoubleIndexToId(JSContext *cx, double index, MutableHandleId id) { if (index == uint32_t(index)) - return IndexToId(cx, uint32_t(index), id); + return IndexToId(cx, uint32_t(index), id.address()); Value tmp = DoubleValue(index); return ValueToId(cx, HandleValue::fromMarkedLocation(&tmp), id); @@ -716,7 +716,7 @@ js::ArraySetLength(typename ExecutionModeTraits::ContextType cxArg, // returned from the function before step 15 above. JSContext *cx = cxArg->asJSContext(); RootedId elementId(cx); - if (!IndexToId(cx, newLen - 1, &elementId)) + if (!IndexToId(cx, newLen - 1, elementId.address())) return false; return arr->reportNotConfigurable(cx, elementId); } diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index 36cede3c9ef3..670f81d1b0de 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -230,7 +230,6 @@ AtomIsInterned(JSContext *cx, JSAtom *atom) * as a new JSAtom's storage without copying. The contract is that the caller no * longer owns the memory and this method is responsible for freeing the memory. */ -template JS_ALWAYS_INLINE static JSAtom * AtomizeAndTakeOwnership(ExclusiveContext *cx, jschar *tbchars, size_t length, InternBehavior ib) @@ -262,9 +261,10 @@ AtomizeAndTakeOwnership(ExclusiveContext *cx, jschar *tbchars, size_t length, In AutoCompartment ac(cx, cx->atomsCompartment()); - JSFlatString *flat = js_NewString(cx, tbchars, length); + JSFlatString *flat = js_NewString(cx, tbchars, length); if (!flat) { js_free(tbchars); + js_ReportOutOfMemory(cx); return nullptr; } @@ -280,7 +280,6 @@ AtomizeAndTakeOwnership(ExclusiveContext *cx, jschar *tbchars, size_t length, In } /* |tbchars| must not point into an inline or short string. */ -template JS_ALWAYS_INLINE static JSAtom * AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length, InternBehavior ib) @@ -308,23 +307,23 @@ AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length, AutoCompartment ac(cx, cx->atomsCompartment()); - JSFlatString *flat = js_NewStringCopyN(cx, tbchars, length); - if (!flat) + JSFlatString *flat = js_NewStringCopyN(cx, tbchars, length); + if (!flat) { + js_ReportOutOfMemory(cx); return nullptr; + } JSAtom *atom = flat->morphAtomizedStringIntoAtom(); if (!atoms.relookupOrAdd(p, AtomHasher::Lookup(tbchars, length), AtomStateEntry(atom, bool(ib)))) { - if (allowGC) - js_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */ + js_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */ return nullptr; } return atom; } -template JSAtom * js::AtomizeString(ExclusiveContext *cx, JSString *str, js::InternBehavior ib /* = js::DoNotInternAtom */) @@ -349,29 +348,11 @@ js::AtomizeString(ExclusiveContext *cx, JSString *str, if (!chars) return nullptr; - if (JSAtom *atom = AtomizeAndCopyChars(cx, chars, str->length(), ib)) - return atom; - - if (!cx->isJSContext() || !allowGC) - return nullptr; - - JSLinearString *linear = str->ensureLinear(cx->asJSContext()); - if (!linear) - return nullptr; - - JS_ASSERT(linear->length() <= JSString::MAX_LENGTH); - return AtomizeAndCopyChars(cx, linear->chars(), linear->length(), ib); + return AtomizeAndCopyChars(cx, chars, str->length(), ib); } -template JSAtom * -js::AtomizeString(ExclusiveContext *cx, JSString *str, InternBehavior ib); - -template JSAtom * -js::AtomizeString(ExclusiveContext *cx, JSString *str, InternBehavior ib); - -template JSAtom * -js::AtomizeMaybeGC(ExclusiveContext *cx, const char *bytes, size_t length, InternBehavior ib) +js::Atomize(ExclusiveContext *cx, const char *bytes, size_t length, InternBehavior ib) { CHECK_REQUEST(cx); @@ -389,30 +370,15 @@ js::AtomizeMaybeGC(ExclusiveContext *cx, const char *bytes, size_t length, Inter */ jschar inflated[ATOMIZE_BUF_MAX]; InflateStringToBuffer(bytes, length, inflated); - return AtomizeAndCopyChars(cx, inflated, length, ib); + return AtomizeAndCopyChars(cx, inflated, length, ib); } jschar *tbcharsZ = InflateString(cx, bytes, &length); if (!tbcharsZ) return nullptr; - return AtomizeAndTakeOwnership(cx, tbcharsZ, length, ib); + return AtomizeAndTakeOwnership(cx, tbcharsZ, length, ib); } -template JSAtom * -js::AtomizeMaybeGC(ExclusiveContext *cx, const char *bytes, size_t length, - InternBehavior ib); - -template JSAtom * -js::AtomizeMaybeGC(ExclusiveContext *cx, const char *bytes, size_t length, - InternBehavior ib); - -JSAtom * -js::Atomize(ExclusiveContext *cx, const char *bytes, size_t length, InternBehavior ib) -{ - return AtomizeMaybeGC(cx, bytes, length, ib); -} - -template JSAtom * js::AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, InternBehavior ib) { @@ -421,21 +387,11 @@ js::AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, Inter if (!JSString::validateLength(cx, length)) return nullptr; - return AtomizeAndCopyChars(cx, chars, length, ib); + return AtomizeAndCopyChars(cx, chars, length, ib); } -template JSAtom * -js::AtomizeChars(ExclusiveContext *cx, - const jschar *chars, size_t length, InternBehavior ib); - -template JSAtom * -js::AtomizeChars(ExclusiveContext *cx, - const jschar *chars, size_t length, InternBehavior ib); - -template bool -js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index, - typename MaybeRooted::MutableHandleType idp) +js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index, jsid *idp) { JS_ASSERT(index > JSID_INT_MAX); @@ -443,20 +399,14 @@ js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index, RangedPtr end(ArrayEnd(buf), buf, ArrayEnd(buf)); RangedPtr start = BackfillIndexInCharBuffer(index, end); - JSAtom *atom = AtomizeChars(cx, start.get(), end - start); + JSAtom *atom = AtomizeChars(cx, start.get(), end - start); if (!atom) return false; - idp.set(JSID_FROM_BITS((size_t)atom)); + *idp = JSID_FROM_BITS((size_t)atom); return true; } -template bool -js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index, MutableHandleId idp); - -template bool -js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index, FakeMutableHandle idp); - template static JSAtom * ToAtomSlow(ExclusiveContext *cx, typename MaybeRooted::HandleType arg) @@ -474,11 +424,11 @@ ToAtomSlow(ExclusiveContext *cx, typename MaybeRooted::HandleTyp } if (v.isString()) - return AtomizeString(cx, v.toString()); + return AtomizeString(cx, v.toString()); if (v.isInt32()) - return Int32ToAtom(cx, v.toInt32()); + return Int32ToAtom(cx, v.toInt32()); if (v.isDouble()) - return NumberToAtom(cx, v.toDouble()); + return NumberToAtom(cx, v.toDouble()); if (v.isBoolean()) return v.toBoolean() ? cx->names().true_ : cx->names().false_; if (v.isNull()) @@ -497,8 +447,7 @@ js::ToAtom(ExclusiveContext *cx, typename MaybeRooted::HandleTyp if (str->isAtom()) return &str->asAtom(); - JS::Anchor anchor(str); - return AtomizeString(cx, str); + return AtomizeString(cx, str); } template JSAtom * @@ -533,7 +482,7 @@ js::XDRAtom(XDRState *xdr, MutableHandleAtom atomp) #if IS_LITTLE_ENDIAN /* Directly access the little endian chars in the XDR buffer. */ const jschar *chars = reinterpret_cast(xdr->buf.read(nchars * sizeof(jschar))); - atom = AtomizeChars(cx, chars, nchars); + atom = AtomizeChars(cx, chars, nchars); #else /* * We must copy chars to a temporary buffer to convert between little and diff --git a/js/src/jsatom.h b/js/src/jsatom.h index 860da0401724..14e68f4600a9 100644 --- a/js/src/jsatom.h +++ b/js/src/jsatom.h @@ -199,21 +199,14 @@ enum InternBehavior InternAtom = true }; -template -extern JSAtom * -AtomizeMaybeGC(ExclusiveContext *cx, const char *bytes, size_t length, - js::InternBehavior ib = js::DoNotInternAtom); - extern JSAtom * Atomize(ExclusiveContext *cx, const char *bytes, size_t length, js::InternBehavior ib = js::DoNotInternAtom); -template extern JSAtom * AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, js::InternBehavior ib = js::DoNotInternAtom); -template extern JSAtom * AtomizeString(ExclusiveContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom); diff --git a/js/src/jsatominlines.h b/js/src/jsatominlines.h index 15a73a5f82e4..c895ac5b3eeb 100644 --- a/js/src/jsatominlines.h +++ b/js/src/jsatominlines.h @@ -104,22 +104,18 @@ BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr end) return end; } -template bool -IndexToIdSlow(ExclusiveContext *cx, uint32_t index, - typename MaybeRooted::MutableHandleType idp); +IndexToIdSlow(ExclusiveContext *cx, uint32_t index, jsid *idp); inline bool -IndexToId(ExclusiveContext *cx, uint32_t index, MutableHandleId idp) +IndexToId(ExclusiveContext *cx, uint32_t index, jsid *idp) { - MaybeCheckStackRoots(cx); - if (index <= JSID_INT_MAX) { - idp.set(INT_TO_JSID(index)); + *idp = INT_TO_JSID(index); return true; } - return IndexToIdSlow(cx, index, idp); + return IndexToIdSlow(cx, index, idp); } inline bool @@ -133,15 +129,6 @@ IndexToIdPure(uint32_t index, jsid *idp) return false; } -inline bool -IndexToIdNoGC(JSContext *cx, uint32_t index, jsid *idp) -{ - if (IndexToIdPure(index, idp)) - return true; - - return IndexToIdSlow(cx, index, idp); -} - static JS_ALWAYS_INLINE JSFlatString * IdToString(JSContext *cx, jsid id) { diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index d0c13dfd9410..2dda4f373b0d 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -1298,6 +1298,33 @@ JS_GetDataViewByteLength(JSObject *obj); JS_FRIEND_API(void *) JS_GetDataViewData(JSObject *obj); +namespace js { + +/* + * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the + * property |id|, using the callable object |callable| as the function to be + * called for notifications. + * + * This is an internal function exposed -- temporarily -- only so that DOM + * proxies can be watchable. Don't use it! We'll soon kill off the + * Object.prototype.{,un}watch functions, at which point this will go too. + */ +extern JS_FRIEND_API(bool) +WatchGuts(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); + +/* + * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for + * the property |id|. + * + * This is an internal function exposed -- temporarily -- only so that DOM + * proxies can be watchable. Don't use it! We'll soon kill off the + * Object.prototype.{,un}watch functions, at which point this will go too. + */ +extern JS_FRIEND_API(bool) +UnwatchGuts(JSContext *cx, JS::HandleObject obj, JS::HandleId id); + +} // namespace js + /* * A class, expected to be passed by value, which represents the CallArgs for a * JSJitGetterOp. diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 15aa014d4e10..ec734286d3a8 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -1117,7 +1117,7 @@ bool js_SuppressDeletedElement(JSContext *cx, HandleObject obj, uint32_t index) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return js_SuppressDeletedProperty(cx, obj, id); } diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 86c9882f4484..5ba9ce7e4108 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -622,18 +622,17 @@ js::Int32ToString(ThreadSafeContext *cx, int32_t si); template JSFlatString * js::Int32ToString(ThreadSafeContext *cx, int32_t si); -template JSAtom * js::Int32ToAtom(ExclusiveContext *cx, int32_t si) { if (JSFlatString *str = LookupInt32ToString(cx, si)) - return js::AtomizeString(cx, str); + return js::AtomizeString(cx, str); char buffer[JSShortString::MAX_SHORT_LENGTH + 1]; size_t length; char *start = BackfillInt32InBuffer(si, buffer, JSShortString::MAX_SHORT_LENGTH + 1, &length); - JSAtom *atom = AtomizeMaybeGC(cx, start, length); + JSAtom *atom = Atomize(cx, start, length); if (!atom) return nullptr; @@ -641,12 +640,6 @@ js::Int32ToAtom(ExclusiveContext *cx, int32_t si) return atom; } -template JSAtom * -js::Int32ToAtom(ExclusiveContext *cx, int32_t si); - -template JSAtom * -js::Int32ToAtom(ExclusiveContext *cx, int32_t si); - /* Returns a non-nullptr pointer to inside cbuf. */ static char * IntToCString(ToCStringBuf *cbuf, int i, size_t *len, int base = 10) @@ -1393,16 +1386,15 @@ js::NumberToString(ThreadSafeContext *cx, double d); template JSString * js::NumberToString(ThreadSafeContext *cx, double d); -template JSAtom * js::NumberToAtom(ExclusiveContext *cx, double d) { int32_t si; if (mozilla::DoubleIsInt32(d, &si)) - return Int32ToAtom(cx, si); + return Int32ToAtom(cx, si); if (JSFlatString *str = LookupDtoaCache(cx, d)) - return AtomizeString(cx, str); + return AtomizeString(cx, str); ToCStringBuf cbuf; char *numStr = FracNumberToCString(cx, &cbuf, d); @@ -1413,7 +1405,7 @@ js::NumberToAtom(ExclusiveContext *cx, double d) JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize); size_t length = strlen(numStr); - JSAtom *atom = AtomizeMaybeGC(cx, numStr, length); + JSAtom *atom = Atomize(cx, numStr, length); if (!atom) return nullptr; @@ -1422,12 +1414,6 @@ js::NumberToAtom(ExclusiveContext *cx, double d) return atom; } -template JSAtom * -js::NumberToAtom(ExclusiveContext *cx, double d); - -template JSAtom * -js::NumberToAtom(ExclusiveContext *cx, double d); - JSFlatString * js::NumberToString(JSContext *cx, double d) { diff --git a/js/src/jsnum.h b/js/src/jsnum.h index f2c4e86ab21f..0596e2743adc 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -52,7 +52,6 @@ template extern JSString * NumberToString(js::ThreadSafeContext *cx, double d); -template extern JSAtom * NumberToAtom(js::ExclusiveContext *cx, double d); @@ -60,7 +59,6 @@ template extern JSFlatString * Int32ToString(ThreadSafeContext *cx, int32_t i); -template extern JSAtom * Int32ToAtom(ExclusiveContext *cx, int32_t si); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 7e05a78fdf21..575165b16197 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -21,6 +21,7 @@ #include "jsarray.h" #include "jsatom.h" #include "jscntxt.h" +#include "jsfriendapi.h" #include "jsfun.h" #include "jsgc.h" #include "jsiter.h" @@ -35,6 +36,7 @@ #include "jswatchpoint.h" #include "jswrapper.h" +#include "builtin/Object.h" #include "frontend/BytecodeCompiler.h" #include "gc/Marking.h" #include "jit/AsmJSModule.h" @@ -1683,7 +1685,7 @@ JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, { if (JS_UNLIKELY(obj->watched())) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; WatchpointMap *wpmap = cx->compartment()->watchpointMap; @@ -3321,7 +3323,7 @@ baseops::DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, H AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, 0, 0); @@ -3911,7 +3913,7 @@ baseops::LookupElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleObject objp, MutableHandleShape propp) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp); @@ -4486,7 +4488,7 @@ baseops::GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint MutableHandleValue vp) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; /* This call site is hot -- use the always-inlined variant of js_GetPropertyHelper(). */ @@ -4867,7 +4869,7 @@ baseops::SetElementHelper(JSContext *cx, HandleObject obj, HandleObject receiver unsigned defineHow, MutableHandleValue vp, bool strict) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return baseops::SetPropertyHelper(cx, obj, receiver, id, defineHow, vp, strict); @@ -4972,7 +4974,7 @@ bool baseops::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeeded) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return baseops::DeleteGeneric(cx, obj, id, succeeded); } @@ -4984,6 +4986,70 @@ baseops::DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, boo return baseops::DeleteGeneric(cx, obj, id, succeeded); } +bool +js::WatchGuts(JSContext *cx, JS::HandleObject origObj, JS::HandleId id, JS::HandleObject callable) +{ + RootedObject obj(cx, GetInnerObject(cx, origObj)); + if (origObj != obj) { + // If by unwrapping and innerizing, we changed the object, check again + // to make sure that we're allowed to set a watch point. + RootedValue v(cx); + unsigned attrs; + if (!CheckAccess(cx, obj, id, JSACC_WATCH, &v, &attrs)) + return false; + } + + if (obj->isNative()) { + // Use sparse indexes for watched objects, as dense elements can be + // written to without checking the watchpoint map. + if (!JSObject::sparsifyDenseElements(cx, obj)) + return false; + + types::MarkTypePropertyConfigured(cx, obj, id); + } + + WatchpointMap *wpmap = cx->compartment()->watchpointMap; + if (!wpmap) { + wpmap = cx->runtime()->new_(); + if (!wpmap || !wpmap->init()) { + js_ReportOutOfMemory(cx); + return false; + } + cx->compartment()->watchpointMap = wpmap; + } + + return wpmap->watch(cx, obj, id, js::WatchHandler, callable); +} + +bool +baseops::Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable) +{ + if (!obj->isNative()) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_WATCH, + obj->getClass()->name); + return false; + } + + return WatchGuts(cx, obj, id, callable); +} + +bool +js::UnwatchGuts(JSContext *cx, JS::HandleObject origObj, JS::HandleId id) +{ + // Looking in the map for an unsupported object will never hit, so we don't + // need to check for nativeness or watchable-ness here. + RootedObject obj(cx, GetInnerObject(cx, origObj)); + if (WatchpointMap *wpmap = cx->compartment()->watchpointMap) + wpmap->unwatch(obj, id, nullptr, nullptr); + return true; +} + +bool +baseops::Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id) +{ + return UnwatchGuts(cx, obj, id); +} + bool js::HasDataProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp) { diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 1d73720e26bc..8909ec0bae45 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -155,6 +155,12 @@ DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, bool *succee extern bool DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded); +extern bool +Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); + +extern bool +Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id); + } /* namespace js::baseops */ extern const Class IntlClass; @@ -1090,6 +1096,10 @@ class JSObject : public js::ObjectImpl static bool deleteByValue(JSContext *cx, js::HandleObject obj, const js::Value &property, bool *succeeded); + static inline bool watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, + JS::HandleObject callable); + static inline bool unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id); + static bool enumerate(JSContext *cx, JS::HandleObject obj, JSIterateOp iterop, JS::MutableHandleValue statep, JS::MutableHandleId idp) { diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index edc32e4c7552..6cdaef257d07 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -51,7 +51,7 @@ JSObject::deleteProperty(JSContext *cx, js::HandleObject obj, js::HandleProperty /* static */ inline bool JSObject::deleteElement(JSContext *cx, js::HandleObject obj, uint32_t index, bool *succeeded) { - JS::RootedId id(cx); + jsid id; if (!js::IndexToId(cx, index, &id)) return false; js::types::MarkTypePropertyConfigured(cx, obj, id); @@ -69,6 +69,21 @@ JSObject::deleteSpecial(JSContext *cx, js::HandleObject obj, js::HandleSpecialId return (op ? op : js::baseops::DeleteSpecial)(cx, obj, sid, succeeded); } +/* static */ inline bool +JSObject::watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, + JS::HandleObject callable) +{ + js::WatchOp op = obj->getOps()->watch; + return (op ? op : js::baseops::Watch)(cx, obj, id, callable); +} + +/* static */ inline bool +JSObject::unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id) +{ + js::UnwatchOp op = obj->getOps()->unwatch; + return (op ? op : js::baseops::Unwatch)(cx, obj, id); +} + inline void JSObject::finalize(js::FreeOp *fop) { @@ -549,7 +564,7 @@ JSObject::getElement(JSContext *cx, js::HandleObject obj, js::HandleObject recei return op(cx, obj, receiver, index, vp); JS::RootedId id(cx); - if (!js::IndexToId(cx, index, &id)) + if (!js::IndexToId(cx, index, id.address())) return false; return getGeneric(cx, obj, receiver, id, vp); } @@ -563,7 +578,7 @@ JSObject::getElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, return false; jsid id; - if (!js::IndexToIdNoGC(cx, index, &id)) + if (!js::IndexToId(cx, index, &id)) return false; return getGenericNoGC(cx, obj, receiver, id, vp); } @@ -583,7 +598,7 @@ JSObject::getElementIfPresent(JSContext *cx, js::HandleObject obj, js::HandleObj * doing index-to-id conversions, we can use those here. */ JS::RootedId id(cx); - if (!js::IndexToId(cx, index, &id)) + if (!js::IndexToId(cx, index, id.address())) return false; JS::RootedObject obj2(cx); diff --git a/js/src/json.cpp b/js/src/json.cpp index 0b9a36d5db71..9f80d8dc39fb 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -688,7 +688,7 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut RootedId id(cx); RootedValue newElement(cx); for (uint32_t i = 0; i < length; i++) { - if (!IndexToId(cx, i, &id)) + if (!IndexToId(cx, i, id.address())) return false; /* Step 2a(iii)(1). */ diff --git a/js/src/jsonparser.cpp b/js/src/jsonparser.cpp index 20c80d00c6b0..fb390d465bda 100644 --- a/js/src/jsonparser.cpp +++ b/js/src/jsonparser.cpp @@ -96,7 +96,7 @@ JSONParser::readString() size_t length = current - start; current++; JSFlatString *str = (ST == JSONParser::PropertyName) - ? AtomizeChars(cx, start.get(), length) + ? AtomizeChars(cx, start.get(), length) : js_NewStringCopyN(cx, start.get(), length); if (!str) return token(OOM); diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 871510bbc40b..34f2d4595f3e 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -156,7 +156,7 @@ BaseProxyHandler::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleO uint32_t index, MutableHandleValue vp, bool *present) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; assertEnteredPolicy(cx, proxy, id); @@ -371,6 +371,19 @@ BaseProxyHandler::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandl return true; } +bool +BaseProxyHandler::watch(JSContext *cx, HandleObject proxy, HandleId id, HandleObject callable) +{ + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_WATCH, + proxy->getClass()->name); + return false; +} + +bool +BaseProxyHandler::unwatch(JSContext *cx, HandleObject proxy, HandleId id) +{ + return true; +} bool DirectProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, @@ -2512,7 +2525,7 @@ Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject recei JS_CHECK_RECURSION(cx, return false); RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; BaseProxyHandler *handler = proxy->as().handler(); @@ -2747,6 +2760,20 @@ Proxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject pro JSObject * const Proxy::LazyProto = reinterpret_cast(0x1); +/* static */ bool +Proxy::watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleObject callable) +{ + JS_CHECK_RECURSION(cx, return false); + return proxy->as().handler()->watch(cx, proxy, id, callable); +} + +/* static */ bool +Proxy::unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id) +{ + JS_CHECK_RECURSION(cx, return false); + return proxy->as().handler()->unwatch(cx, proxy, id); +} + static JSObject * proxy_innerObject(JSContext *cx, HandleObject obj) { @@ -2784,7 +2811,7 @@ proxy_LookupElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleObject objp, MutableHandleShape propp) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return proxy_LookupGeneric(cx, obj, id, objp, propp); } @@ -2824,7 +2851,7 @@ proxy_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue PropertyOp getter, StrictPropertyOp setter, unsigned attrs) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return proxy_DefineGeneric(cx, obj, id, value, getter, setter, attrs); } @@ -2857,7 +2884,7 @@ proxy_GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_ MutableHandleValue vp) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return proxy_GetGeneric(cx, obj, receiver, id, vp); } @@ -2897,7 +2924,7 @@ proxy_SetElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp, bool strict) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return proxy_SetGeneric(cx, obj, id, vp, strict); } @@ -2952,7 +2979,7 @@ static bool proxy_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeeded) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return proxy_DeleteGeneric(cx, obj, id, succeeded); } @@ -3046,6 +3073,18 @@ proxy_Construct(JSContext *cx, unsigned argc, Value *vp) return Proxy::construct(cx, proxy, args); } +static bool +proxy_Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable) +{ + return Proxy::watch(cx, obj, id, callable); +} + +static bool +proxy_Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id) +{ + return Proxy::unwatch(cx, obj, id); +} + #define PROXY_CLASS_EXT \ { \ nullptr, /* outerObject */ \ @@ -3098,6 +3137,7 @@ proxy_Construct(JSContext *cx, unsigned argc, Value *vp) proxy_DeleteProperty, \ proxy_DeleteElement, \ proxy_DeleteSpecial, \ + proxy_Watch, proxy_Unwatch, \ nullptr, /* enumerate */ \ nullptr, /* thisObject */ \ } \ @@ -3155,6 +3195,7 @@ const Class js::OuterWindowProxyObject::class_ = { proxy_DeleteProperty, proxy_DeleteElement, proxy_DeleteSpecial, + proxy_Watch, proxy_Unwatch, nullptr, /* enumerate */ nullptr, /* thisObject */ } diff --git a/js/src/jsproxy.h b/js/src/jsproxy.h index aab5136f6328..0f59cba2549e 100644 --- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -166,6 +166,12 @@ class JS_FRIEND_API(BaseProxyHandler) uint32_t index, MutableHandleValue vp, bool *present); virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); + // These two hooks must be overridden, or not overridden, in tandem -- no + // overriding just one! + virtual bool watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, + JS::HandleObject callable); + virtual bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id); + /* See comment for weakmapKeyDelegateOp in js/Class.h. */ virtual JSObject *weakmapKeyDelegate(JSObject *proxy); }; @@ -275,6 +281,10 @@ class Proxy static bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp); static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop); + static bool watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, + JS::HandleObject callable); + static bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id); + /* IC entry path for handling __noSuchMethod__ on access. */ static bool callProp(JSContext *cx, HandleObject proxy, HandleObject reveiver, HandleId id, MutableHandleValue vp); diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 912d76b839d8..695399ebc199 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -1704,7 +1704,7 @@ class MOZ_STACK_CLASS StringRegExpGuard if (!arg) return false; - fm.patstr = AtomizeString(cx, arg); + fm.patstr = AtomizeString(cx, arg); if (!fm.patstr) return false; } diff --git a/js/src/tests/lib/jittests.py b/js/src/tests/lib/jittests.py index 1bb2890bff4c..fd10c5c5c768 100755 --- a/js/src/tests/lib/jittests.py +++ b/js/src/tests/lib/jittests.py @@ -390,9 +390,9 @@ def print_tinderbox(ok, res): print("INFO exit-status : {}".format(res.rc)) print("INFO timed-out : {}".format(res.timed_out)) for line in res.out.split('\n'): - print("INFO stdout > " + line) - for line in res.out.split('\n'): - print("INFO stderr 2> " + line) + print("INFO stdout > " + line.strip()) + for line in res.err.split('\n'): + print("INFO stderr 2> " + line.strip()) def wrap_parallel_run_test(test, prefix, resultQueue, options): # Ignore SIGINT in the child diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 7e968403356a..26d608832250 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -504,6 +504,23 @@ GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx, Handle globa return !v.isFalse(); } +/* static */ bool +GlobalObject::warnOnceAboutWatch(JSContext *cx, HandleObject obj) +{ + Rooted global(cx, &obj->global()); + HeapSlot &v = global->getSlotRef(WARNED_WATCH_DEPRECATED); + if (v.isUndefined()) { + // Warn only once per global object. + if (!JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, js_GetErrorMessage, NULL, + JSMSG_OBJECT_WATCH_DEPRECATED)) + { + return false; + } + v.init(global, HeapSlot::Slot, WARNED_WATCH_DEPRECATED, BooleanValue(true)); + } + return true; +} + JSFunction * GlobalObject::createConstructor(JSContext *cx, Native ctor, JSAtom *nameArg, unsigned length, gc::AllocKind kind) diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index 401bf8b2c4e3..cbe9ee03d224 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -105,8 +105,8 @@ class GlobalObject : public JSObject static const unsigned NUMBER_FORMAT_PROTO = COLLATOR_PROTO + 1; static const unsigned DATE_TIME_FORMAT_PROTO = NUMBER_FORMAT_PROTO + 1; static const unsigned REGEXP_STATICS = DATE_TIME_FORMAT_PROTO + 1; - static const unsigned FUNCTION_NS = REGEXP_STATICS + 1; - static const unsigned RUNTIME_CODEGEN_ENABLED = FUNCTION_NS + 1; + static const unsigned WARNED_WATCH_DEPRECATED = REGEXP_STATICS + 1; + static const unsigned RUNTIME_CODEGEN_ENABLED = WARNED_WATCH_DEPRECATED + 1; static const unsigned DEBUGGERS = RUNTIME_CODEGEN_ENABLED + 1; static const unsigned INTRINSICS = DEBUGGERS + 1; static const unsigned ARRAY_TYPE = INTRINSICS + 1; @@ -114,14 +114,13 @@ class GlobalObject : public JSObject /* Total reserved-slot count for global objects. */ static const unsigned RESERVED_SLOTS = ARRAY_TYPE + 1; - void staticAsserts() { - /* - * The slot count must be in the public API for JSCLASS_GLOBAL_FLAGS, - * and we aren't going to expose GlobalObject, so just assert that the - * two values are synchronized. - */ - JS_STATIC_ASSERT(JSCLASS_GLOBAL_SLOT_COUNT == RESERVED_SLOTS); - } + /* + * The slot count must be in the public API for JSCLASS_GLOBAL_FLAGS, and + * we won't expose GlobalObject, so just assert that the two values are + * synchronized. + */ + static_assert(JSCLASS_GLOBAL_SLOT_COUNT == RESERVED_SLOTS, + "global object slot counts are inconsistent"); friend JSObject * ::js_InitObjectClass(JSContext *cx, js::HandleObject); @@ -575,6 +574,10 @@ class GlobalObject : public JSObject static bool isRuntimeCodeGenEnabled(JSContext *cx, Handle global); + // Warn about use of the deprecated watch/unwatch functions in the global + // in which |obj| was created, if no prior warning was given. + static bool warnOnceAboutWatch(JSContext *cx, HandleObject obj); + const Value &getOriginalEval() const { JS_ASSERT(getSlot(EVAL).isObject()); return getSlot(EVAL); diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index 6f802a8390fc..1c3ea5a72dc2 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -241,7 +241,7 @@ RegExpObject * RegExpObject::createNoStatics(ExclusiveContext *cx, const jschar *chars, size_t length, RegExpFlag flags, TokenStream *tokenStream) { - RootedAtom source(cx, AtomizeChars(cx, chars, length)); + RootedAtom source(cx, AtomizeChars(cx, chars, length)); if (!source) return nullptr; diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 82b23cb7545f..7686b7121229 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -364,7 +364,7 @@ with_LookupElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleObject objp, MutableHandleShape propp) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return with_LookupGeneric(cx, obj, id, objp, propp); } @@ -398,7 +398,7 @@ with_GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t MutableHandleValue vp) { RootedId id(cx); - if (!IndexToId(cx, index, &id)) + if (!IndexToId(cx, index, id.address())) return false; return with_GetGeneric(cx, obj, receiver, id, vp); } @@ -536,6 +536,7 @@ const Class WithObject::class_ = { with_DeleteProperty, with_DeleteElement, with_DeleteSpecial, + nullptr, nullptr, /* watch/unwatch */ with_Enumerate, with_ThisObject, } diff --git a/js/src/vm/String-inl.h b/js/src/vm/String-inl.h index f12b62d842e4..154b62466c5f 100644 --- a/js/src/vm/String-inl.h +++ b/js/src/vm/String-inl.h @@ -219,7 +219,7 @@ JSFlatString::toPropertyName(JSContext *cx) #endif if (isAtom()) return asAtom().asPropertyName(); - JSAtom *atom = js::AtomizeString(cx, this); + JSAtom *atom = js::AtomizeString(cx, this); if (!atom) return nullptr; return atom->asPropertyName(); diff --git a/js/src/vm/StringBuffer.cpp b/js/src/vm/StringBuffer.cpp index 440399c0e9ca..5978c410ff03 100644 --- a/js/src/vm/StringBuffer.cpp +++ b/js/src/vm/StringBuffer.cpp @@ -75,7 +75,7 @@ StringBuffer::finishAtom() if (length == 0) return cx->names().empty; - JSAtom *atom = AtomizeChars(cx, cb.begin(), length); + JSAtom *atom = AtomizeChars(cx, cb.begin(), length); cb.clear(); return atom; } diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 280587c74447..e527a0eca833 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -1447,7 +1447,7 @@ JSStructuredCloneReader::readId(jsid *idp) JSString *str = readString(data); if (!str) return false; - JSAtom *atom = AtomizeString(context(), str); + JSAtom *atom = AtomizeString(context(), str); if (!atom) return false; *idp = NON_INTEGER_ATOM_TO_JSID(atom); diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 439a7a29c6ea..8f90340191a2 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -3470,6 +3470,7 @@ const Class ArrayBufferObject::class_ = { ArrayBufferObject::obj_deleteProperty, ArrayBufferObject::obj_deleteElement, ArrayBufferObject::obj_deleteSpecial, + nullptr, nullptr, /* watch/unwatch */ ArrayBufferObject::obj_enumerate, nullptr, /* thisObject */ } @@ -3632,6 +3633,7 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double) _typedArray##Object::obj_deleteProperty, \ _typedArray##Object::obj_deleteElement, \ _typedArray##Object::obj_deleteSpecial, \ + nullptr, nullptr, /* watch/unwatch */ \ _typedArray##Object::obj_enumerate, \ nullptr, /* thisObject */ \ } \ diff --git a/js/xpconnect/src/Makefile.in b/js/xpconnect/src/Makefile.in index f0d72f516a8a..13fdb2836383 100644 --- a/js/xpconnect/src/Makefile.in +++ b/js/xpconnect/src/Makefile.in @@ -113,7 +113,7 @@ GeneratedEvents.$(OBJ_SUFFIX): GeneratedEvents.h \ GeneratedEvents.cpp event_impl_gen.conf : $(srcdir)/event_impl_gen.conf.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > event_impl_gen.conf + $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $^ -o event_impl_gen.conf) GeneratedEvents.h: $(srcdir)/dictionary_helper_gen.conf \ event_impl_gen.conf \ diff --git a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp index 53b6f7f72e95..a3a69cf20f21 100644 --- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp +++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp @@ -739,6 +739,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = { nullptr, // deleteProperty nullptr, // deleteElement nullptr, // deleteSpecial + nullptr, nullptr, // watch/unwatch XPC_WN_JSOp_Enumerate, XPC_WN_JSOp_ThisObject, } diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 1e6fe32a6789..35f7722d0672 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -1172,6 +1172,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj); nullptr, /* deleteProperty */ \ nullptr, /* deleteElement */ \ nullptr, /* deleteSpecial */ \ + nullptr, nullptr, /* watch/unwatch */ \ XPC_WN_JSOp_Enumerate, \ XPC_WN_JSOp_ThisObject, \ } @@ -1200,6 +1201,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj); nullptr, /* deleteProperty */ \ nullptr, /* deleteElement */ \ nullptr, /* deleteSpecial */ \ + nullptr, nullptr, /* watch/unwatch */ \ XPC_WN_JSOp_Enumerate, \ XPC_WN_JSOp_ThisObject, \ } diff --git a/js/xpconnect/tests/components/js/Makefile.in b/js/xpconnect/tests/components/js/Makefile.in index 3de3001a593b..c7850db60822 100644 --- a/js/xpconnect/tests/components/js/Makefile.in +++ b/js/xpconnect/tests/components/js/Makefile.in @@ -22,4 +22,4 @@ libs:: $(JS_FILES) $(INSTALL) $^ $(testxpcobjdir)/$(componentdir) libs:: $(MANIFEST_FILE) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $< > $(testxpcobjdir)/$(componentdir)/$(= 0, - "Couldn't find flex in kDisplayKTable"); - - sIndexOfInlineFlexInDisplayTable = - nsCSSProps::FindIndexOfKeyword(eCSSKeyword_inline_flex, - nsCSSProps::kDisplayKTable); - MOZ_ASSERT(sIndexOfInlineFlexInDisplayTable >= 0, - "Couldn't find inline-flex in kDisplayKTable"); - - sAreFlexKeywordIndicesInitialized = true; - } - - // OK -- now, stomp on or restore the "flex" entries in kDisplayKTable, - // depending on whether the flexbox pref is enabled vs. disabled. - if (sIndexOfFlexInDisplayTable >= 0) { - nsCSSProps::kDisplayKTable[sIndexOfFlexInDisplayTable] = - isFlexboxEnabled ? eCSSKeyword_flex : eCSSKeyword_UNKNOWN; - } - if (sIndexOfInlineFlexInDisplayTable >= 0) { - nsCSSProps::kDisplayKTable[sIndexOfInlineFlexInDisplayTable] = - isFlexboxEnabled ? eCSSKeyword_inline_flex : eCSSKeyword_UNKNOWN; - } - - return 0; -} - // When the pref "layout.css.sticky.enabled" changes, this function is invoked // to let us update kPositionKTable, to selectively disable or restore the // entry for "sticky" in that table. @@ -4342,9 +4291,14 @@ nsLayoutUtils::DrawSingleImage(nsRenderingContext* aRenderingContext, { nsIntSize imageSize; if (aImage->GetType() == imgIContainer::TYPE_VECTOR) { - imageSize.width = nsPresContext::AppUnitsToIntCSSPixels(aDest.width); - imageSize.height = nsPresContext::AppUnitsToIntCSSPixels(aDest.height); + // We choose a size for vector images that emulates a raster image which + // is perfectly sized for the destination rect: each pixel in the image + // maps exactly to a single pixel on-screen. + nscoord appUnitsPerDevPx = aRenderingContext->AppUnitsPerDevPixel(); + imageSize.width = NSAppUnitsToIntPixels(aDest.width, appUnitsPerDevPx); + imageSize.height = NSAppUnitsToIntPixels(aDest.height, appUnitsPerDevPx); } else { + // Raster images have an intrinsic size, so we just use that. aImage->GetWidth(&imageSize.width); aImage->GetHeight(&imageSize.height); } @@ -5212,9 +5166,6 @@ nsLayoutUtils::Initialize() Preferences::AddBoolVarCache(&sInvalidationDebuggingIsEnabled, "nglayout.debug.invalidation"); - Preferences::RegisterCallback(FlexboxEnabledPrefChangeCallback, - FLEXBOX_ENABLED_PREF_NAME); - FlexboxEnabledPrefChangeCallback(FLEXBOX_ENABLED_PREF_NAME, nullptr); Preferences::RegisterCallback(StickyEnabledPrefChangeCallback, STICKY_ENABLED_PREF_NAME); StickyEnabledPrefChangeCallback(STICKY_ENABLED_PREF_NAME, nullptr); @@ -5235,8 +5186,6 @@ nsLayoutUtils::Shutdown() sContentMap = nullptr; } - Preferences::UnregisterCallback(FlexboxEnabledPrefChangeCallback, - FLEXBOX_ENABLED_PREF_NAME); Preferences::UnregisterCallback(StickyEnabledPrefChangeCallback, STICKY_ENABLED_PREF_NAME); diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index 3dadddc3c81f..8eb981531acd 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -450,9 +450,9 @@ load 730559.html load first-letter-638937.html load first-letter-638937-2.html load 734777.html -test-pref(layout.css.flexbox.enabled,true) load 737313-1.html -test-pref(layout.css.flexbox.enabled,true) load 737313-2.html -test-pref(layout.css.flexbox.enabled,true) load 737313-3.html +load 737313-1.html +load 737313-2.html +load 737313-3.html load 747688.html load 750066.html test-pref(font.size.inflation.emPerLine,15) asserts(1-100) load font-inflation-762332.html # bug 762332 @@ -467,37 +467,37 @@ load 769120.html load 786740-1.html asserts(0-4) test-pref(font.size.inflation.emPerLine,15) load 791601.xhtml # 3 counts of bug 871327, 1 bug 367185 test-pref(font.size.inflation.minTwips,120) load 794693.html -asserts(8) test-pref(layout.css.flexbox.enabled,true) load 798020-1.html -test-pref(layout.css.flexbox.enabled,true) load 798235-1.html -test-pref(layout.css.flexbox.enabled,true) load 799207-1.html -asserts(12) test-pref(layout.css.flexbox.enabled,true) load 799207-2.html -test-pref(layout.css.flexbox.enabled,true) load 801268-1.html -test-pref(layout.css.flexbox.enabled,true) load 804089-1.xhtml +asserts(8) load 798020-1.html +load 798235-1.html +load 799207-1.html +asserts(12) load 799207-2.html +load 801268-1.html +load 804089-1.xhtml load 810726.html -test-pref(layout.css.flexbox.enabled,true) load 825810-1.html -test-pref(layout.css.flexbox.enabled,true) load 825810-2.html -test-pref(layout.css.flexbox.enabled,true) load 827076.html +load 825810-1.html +load 825810-2.html +load 827076.html load 840818.html -test-pref(layout.css.flexbox.enabled,true) load 812822-1.html -asserts(1) test-pref(layout.css.flexbox.enabled,true) load 824297-1.html # bug 399262 -test-pref(layout.css.flexbox.enabled,true) load 826483-1.html -asserts(1) test-pref(layout.css.flexbox.enabled,true) load 826532-1.html # bug 399262 -test-pref(layout.css.flexbox.enabled,true) load 827168-1.html +load 812822-1.html +asserts(1) load 824297-1.html # bug 399262 +load 826483-1.html +asserts(1) load 826532-1.html # bug 399262 +load 827168-1.html load 836895.html load 840787.html load 842132-1.html -test-pref(layout.css.flexbox.enabled,true) load 844529-1.html +load 844529-1.html load 847130.xhtml load 847208.html asserts(4) load 847209.html # bug 847368 -test-pref(layout.css.flexbox.enabled,true) load 847211-1.html +load 847211-1.html load 849603.html -test-pref(layout.css.flexbox.enabled,true) load 851396-1.html -test-pref(layout.css.flexbox.enabled,true) load 854263-1.html -test-pref(layout.css.flexbox.enabled,true) load 862947-1.html +load 851396-1.html +load 854263-1.html +load 862947-1.html needs-focus pref(accessibility.browsewithcaret,true) load 868906.html -test-pref(layout.css.flexbox.enabled,true) load 866547-1.html -asserts(1-4) test-pref(layout.css.flexbox.enabled,true) load 876074-1.html # bug 876749 +load 866547-1.html +asserts(1-4) load 876074-1.html # bug 876749 load 885009-1.html load 893523.html test-pref(layout.css.sticky.enabled,true) load 914891.html diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 06e9048697d9..cdfe8cc53379 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -830,7 +830,7 @@ RenderFrameParent::NotifyInputEvent(const WidgetInputEvent& aEvent, WidgetInputEvent* aOutEvent) { if (GetApzcTreeManager()) { - GetApzcTreeManager()->ReceiveInputEvent(aEvent, aOutEvent); + GetApzcTreeManager()->ReceiveInputEvent(aEvent, nullptr, aOutEvent); } } diff --git a/layout/mathml/Makefile.in b/layout/mathml/Makefile.in index 381b1577908e..49da8bf433aa 100644 --- a/layout/mathml/Makefile.in +++ b/layout/mathml/Makefile.in @@ -39,7 +39,7 @@ math_properties = mathfont.properties $(DIST)/bin/res/fonts/$(math_properties) $(DESTDIR)$(mozappdir)/res/fonts/$(math_properties): $(math_properties) Makefile test -d $(@D) || $(NSINSTALL) -D $(@D) rm -f $@ - $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py --marker=% $(DEFINES) $(ACDEFINES) $< > $@ + $(call py_action,preprocessor,--marker=% $(DEFINES) $(ACDEFINES) $< -o $@) libs:: $(DIST)/bin/res/fonts/$(math_properties) install:: $(DESTDIR)$(mozappdir)/res/fonts/$(math_properties) diff --git a/layout/media/Makefile.in b/layout/media/Makefile.in index 0637670a0c3a..18e41fbe45b5 100644 --- a/layout/media/Makefile.in +++ b/layout/media/Makefile.in @@ -116,7 +116,7 @@ include $(topsrcdir)/config/rules.mk ifeq (WINNT,$(OS_TARGET)) symbols.def: symbols.def.in $(GLOBAL_DEPS) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(ACDEFINES) $< > $@ + $(call py_action,preprocessor,$(ACDEFINES) $< -o $@) OS_LIBS += $(call EXPAND_LIBNAME, msimg32) diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 1641f71ce973..46812d2ae1da 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1759,7 +1759,7 @@ fails-if(Android&&AndroidVersion<15) == 836844-1.html 836844-1-ref.html == 846144-1.html 846144-1-ref.html == 847850-1.html 847850-1-ref.html == 848421-1.html 848421-1-ref.html -test-pref(layout.css.flexbox.enabled,true) == 849407-1.html 849407-1-ref.html +== 849407-1.html 849407-1-ref.html == 849996-1.html 849996-1-ref.html == 858803-1.html 858803-1-ref.html == 860242-1.html 860242-1-ref.html diff --git a/layout/reftests/flexbox/flexbox-pref-1-disabled-ref.xhtml b/layout/reftests/flexbox/flexbox-pref-1-disabled-ref.xhtml deleted file mode 100644 index 8dc18f44a664..000000000000 --- a/layout/reftests/flexbox/flexbox-pref-1-disabled-ref.xhtml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -

- "display: flex" is: -

disabled
-

-

- "display: inline-flex" is: -

disabled
-

- - diff --git a/layout/reftests/flexbox/flexbox-pref-1-enabled-ref.xhtml b/layout/reftests/flexbox/flexbox-pref-1-enabled-ref.xhtml deleted file mode 100644 index 9bfba5f31505..000000000000 --- a/layout/reftests/flexbox/flexbox-pref-1-enabled-ref.xhtml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -

- "display: flex" is: -

enabled
-

-

- "display: inline-flex" is: -

enabled
-

- - diff --git a/layout/reftests/flexbox/flexbox-pref-1.xhtml b/layout/reftests/flexbox/flexbox-pref-1.xhtml deleted file mode 100644 index 471f388b4e6a..000000000000 --- a/layout/reftests/flexbox/flexbox-pref-1.xhtml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - -

- "display: flex" is: - -

enabled
-
disabled
-

-

- "display: inline-flex" is:
- -

enabled
-
disabled
-

- - diff --git a/layout/reftests/flexbox/reftest.list b/layout/reftests/flexbox/reftest.list index 1fb0234e3d49..3c599e92f256 100644 --- a/layout/reftests/flexbox/reftest.list +++ b/layout/reftests/flexbox/reftest.list @@ -9,18 +9,6 @@ # tests over to the w3c-css directory, so that they can become part of the # W3C's test suite. -# Tests for flexbox pref "layout.css.flexbox.enabled" -# (Note that it defaults to being off in release builds - see bug 841876) -# Check that manually setting the pref on/off w/ test-pref() works correctly: -test-pref(layout.css.flexbox.enabled,false) == flexbox-pref-1.xhtml flexbox-pref-1-disabled-ref.xhtml -test-pref(layout.css.flexbox.enabled,true) == flexbox-pref-1.xhtml flexbox-pref-1-enabled-ref.xhtml - -# Enable pref for remaining tests -# (Most tests only need it in the testcase, but a few use it in the -# reference case, so we'll just enable it using "pref()" to make -# it available for both.) -default-preferences pref(layout.css.flexbox.enabled,true) - # Tests for cross-axis alignment (align-self / align-items properties) fails == flexbox-align-self-baseline-horiz-2.xhtml flexbox-align-self-baseline-horiz-2-ref.xhtml # bug 793456, and possibly others # This one fails on windows R (but not Ru, strangely). On Windows R, the diff --git a/layout/reftests/svg/image/image-svg-inline-zoom-in-01c.html b/layout/reftests/svg/image/image-svg-inline-zoom-in-01c.html new file mode 100644 index 000000000000..9d273c91ec26 --- /dev/null +++ b/layout/reftests/svg/image/image-svg-inline-zoom-in-01c.html @@ -0,0 +1,18 @@ + + + + +
+ + + + +
+ + diff --git a/layout/reftests/svg/image/image-svg-inline-zoom-in-01d.html b/layout/reftests/svg/image/image-svg-inline-zoom-in-01d.html new file mode 100644 index 000000000000..921fa4ec2f12 --- /dev/null +++ b/layout/reftests/svg/image/image-svg-inline-zoom-in-01d.html @@ -0,0 +1,18 @@ + + + + +
+ + + + +
+ + diff --git a/layout/reftests/svg/image/image-svg-inline-zoom-out-01c.html b/layout/reftests/svg/image/image-svg-inline-zoom-out-01c.html new file mode 100644 index 000000000000..5c88134c033c --- /dev/null +++ b/layout/reftests/svg/image/image-svg-inline-zoom-out-01c.html @@ -0,0 +1,17 @@ + + + + +
+ + + + +
+ + diff --git a/layout/reftests/svg/image/image-svg-inline-zoom-out-01d.html b/layout/reftests/svg/image/image-svg-inline-zoom-out-01d.html new file mode 100644 index 000000000000..ad24ce81e5e8 --- /dev/null +++ b/layout/reftests/svg/image/image-svg-inline-zoom-out-01d.html @@ -0,0 +1,17 @@ + + + + +
+ + + + +
+ + diff --git a/layout/reftests/svg/image/lime100x100.svg b/layout/reftests/svg/image/lime100x100.svg new file mode 100644 index 000000000000..bba9d342368a --- /dev/null +++ b/layout/reftests/svg/image/lime100x100.svg @@ -0,0 +1,3 @@ + + + diff --git a/layout/reftests/svg/image/reftest.list b/layout/reftests/svg/image/reftest.list index 492e5d10b878..5a4d59ddfaa5 100644 --- a/layout/reftests/svg/image/reftest.list +++ b/layout/reftests/svg/image/reftest.list @@ -13,8 +13,12 @@ fuzzy-if(Android,4,34) == image-opacity-02.svg image-opacity-02-ref.svg # Bug 77 == image-svg-inline-01.html ../pass.svg == image-svg-inline-zoom-in-01a.html ../pass.svg == image-svg-inline-zoom-in-01b.html ../pass.svg +== image-svg-inline-zoom-in-01c.html ../pass.svg +== image-svg-inline-zoom-in-01d.html ../pass.svg == image-svg-inline-zoom-out-01a.html ../pass.svg == image-svg-inline-zoom-out-01b.html ../pass.svg +== image-svg-inline-zoom-out-01c.html ../pass.svg +== image-svg-inline-zoom-out-01d.html ../pass.svg == image-svg-inline-sprite-zoom-in-01a.html image-svg-inline-sprite-zoom-in-01-ref.html == image-svg-inline-sprite-zoom-in-01b.html image-svg-inline-sprite-zoom-in-01-ref.html == image-svg-inline-sprite-zoom-out-01a.html image-svg-inline-sprite-zoom-out-01-ref.html diff --git a/layout/reftests/w3c-css/submitted/ui3/reftest.list b/layout/reftests/w3c-css/submitted/ui3/reftest.list index f5d9ef532677..b0bde7a753fc 100644 --- a/layout/reftests/w3c-css/submitted/ui3/reftest.list +++ b/layout/reftests/w3c-css/submitted/ui3/reftest.list @@ -8,6 +8,6 @@ == box-sizing-padding-box-001.xht box-sizing-padding-box-001-ref.xht == box-sizing-padding-box-002.xht box-sizing-padding-box-002-ref.xht == box-sizing-padding-box-003.xht box-sizing-padding-box-003-ref.xht -== box-sizing-replaced-001.xht box-sizing-replaced-001-ref.xht +random-if(Android) == box-sizing-replaced-001.xht box-sizing-replaced-001-ref.xht == box-sizing-replaced-002.xht box-sizing-replaced-002-ref.xht == box-sizing-replaced-003.xht box-sizing-replaced-003-ref.xht diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index af92d93337ad..e4e6a896f703 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1603,7 +1603,7 @@ CSS_PROP_POSITION( align_items, AlignItems, CSS_PROPERTY_PARSE_VALUE, - "layout.css.flexbox.enabled", + "", VARIANT_HK, kAlignItemsKTable, offsetof(nsStylePosition, mAlignItems), @@ -1613,7 +1613,7 @@ CSS_PROP_POSITION( align_self, AlignSelf, CSS_PROPERTY_PARSE_VALUE, - "layout.css.flexbox.enabled", + "", VARIANT_HK, kAlignSelfKTable, offsetof(nsStylePosition, mAlignSelf), @@ -1623,7 +1623,7 @@ CSS_PROP_SHORTHAND( flex, Flex, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.flexbox.enabled") + "") CSS_PROP_POSITION( flex-basis, flex_basis, @@ -1631,7 +1631,7 @@ CSS_PROP_POSITION( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | CSS_PROPERTY_STORES_CALC, - "layout.css.flexbox.enabled", + "", // NOTE: The parsing implementation for the 'flex' shorthand property has // its own code to parse each subproperty. It does not depend on the // longhand parsing defined here. @@ -1644,7 +1644,7 @@ CSS_PROP_POSITION( flex_direction, FlexDirection, CSS_PROPERTY_PARSE_VALUE, - "layout.css.flexbox.enabled", + "", VARIANT_HK, kFlexDirectionKTable, offsetof(nsStylePosition, mFlexDirection), @@ -1655,7 +1655,7 @@ CSS_PROP_POSITION( FlexGrow, CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE, - "layout.css.flexbox.enabled", + "", // NOTE: The parsing implementation for the 'flex' shorthand property has // its own code to parse each subproperty. It does not depend on the // longhand parsing defined here. @@ -1669,7 +1669,7 @@ CSS_PROP_POSITION( FlexShrink, CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE, - "layout.css.flexbox.enabled", + "", // NOTE: The parsing implementation for the 'flex' shorthand property has // its own code to parse each subproperty. It does not depend on the // longhand parsing defined here. @@ -1682,7 +1682,7 @@ CSS_PROP_POSITION( order, Order, CSS_PROPERTY_PARSE_VALUE, - "layout.css.flexbox.enabled", + "", VARIANT_HI, nullptr, offsetof(nsStylePosition, mOrder), @@ -1692,7 +1692,7 @@ CSS_PROP_POSITION( justify_content, JustifyContent, CSS_PROPERTY_PARSE_VALUE, - "layout.css.flexbox.enabled", + "", VARIANT_HK, kJustifyContentKTable, offsetof(nsStylePosition, mJustifyContent), diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index a893d010a557..35221d7dc9a8 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -929,7 +929,7 @@ const int32_t nsCSSProps::kDirectionKTable[] = { eCSSKeyword_UNKNOWN,-1 }; -int32_t nsCSSProps::kDisplayKTable[] = { +const int32_t nsCSSProps::kDisplayKTable[] = { eCSSKeyword_none, NS_STYLE_DISPLAY_NONE, eCSSKeyword_inline, NS_STYLE_DISPLAY_INLINE, eCSSKeyword_block, NS_STYLE_DISPLAY_BLOCK, @@ -960,7 +960,6 @@ int32_t nsCSSProps::kDisplayKTable[] = { eCSSKeyword__moz_popup, NS_STYLE_DISPLAY_POPUP, eCSSKeyword__moz_groupbox, NS_STYLE_DISPLAY_GROUPBOX, #endif - // The next two entries are controlled by the layout.css.flexbox.enabled pref. eCSSKeyword_flex, NS_STYLE_DISPLAY_FLEX, eCSSKeyword_inline_flex, NS_STYLE_DISPLAY_INLINE_FLEX, eCSSKeyword_UNKNOWN,-1 diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 63004d6ba47a..bd1fda67631a 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -476,9 +476,7 @@ public: static const int32_t kContentKTable[]; static const int32_t kCursorKTable[]; static const int32_t kDirectionKTable[]; - // Not const because we modify its entries when the pref - // "layout.css.flexbox.enabled" changes: - static int32_t kDisplayKTable[]; + static const int32_t kDisplayKTable[]; static const int32_t kElevationKTable[]; static const int32_t kEmptyCellsKTable[]; static const int32_t kAlignItemsKTable[]; diff --git a/layout/style/nsStyleUtil.cpp b/layout/style/nsStyleUtil.cpp index f2f3532dd1da..925b8b71a2aa 100644 --- a/layout/style/nsStyleUtil.cpp +++ b/layout/style/nsStyleUtil.cpp @@ -10,6 +10,7 @@ #include "nsCSSProps.h" #include "nsRuleNode.h" #include "nsROCSSPrimitiveValue.h" +#include "nsIContentPolicy.h" #include "nsIContentSecurityPolicy.h" #include "nsIURI.h" @@ -441,7 +442,8 @@ nsStyleUtil::IsSignificantChild(nsIContent* aChild, bool aTextIsSignificant, } /* static */ bool -nsStyleUtil::CSPAllowsInlineStyle(nsIPrincipal* aPrincipal, +nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent, + nsIPrincipal* aPrincipal, nsIURI* aSourceURI, uint32_t aLineNumber, const nsSubstring& aStyleText, @@ -453,6 +455,10 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIPrincipal* aPrincipal, *aRv = NS_OK; } + MOZ_ASSERT(!aContent || aContent->Tag() == nsGkAtoms::style, + "aContent passed to CSPAllowsInlineStyle " + "for an element that is not - - -
-
-
-
-
-
- - diff --git a/layout/style/test/file_flexbox_flex_shorthand.html b/layout/style/test/file_flexbox_flex_shorthand.html deleted file mode 100644 index 7ee985325a28..000000000000 --- a/layout/style/test/file_flexbox_flex_shorthand.html +++ /dev/null @@ -1,270 +0,0 @@ - - - - - - -
-
-
-
-
- - diff --git a/layout/style/test/file_flexbox_layout.html b/layout/style/test/file_flexbox_layout.html deleted file mode 100644 index 7a7d9382d608..000000000000 --- a/layout/style/test/file_flexbox_layout.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - -
-
-
-
-
- - diff --git a/layout/style/test/file_flexbox_order.html b/layout/style/test/file_flexbox_order.html deleted file mode 100644 index cf8ebf9b752d..000000000000 --- a/layout/style/test/file_flexbox_order.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - -
- - -
-
-
-
-
-
-
-
- -
- -
-
-
-
-
-
- -
-
-
-
- - diff --git a/layout/style/test/file_flexbox_order_table.html b/layout/style/test/file_flexbox_order_table.html deleted file mode 100644 index 0262dfaea95c..000000000000 --- a/layout/style/test/file_flexbox_order_table.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - -
- - -
-
-
-
-
-
-
-
- -
- -
-
-
-
-
-
- -
-
-
-
- - diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 4fcf577a84d1..e971dc7f2d54 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -2356,6 +2356,8 @@ var gCSSProperties = { prerequisites: { "float": "none", "position": "static" }, other_values: [ "block", + "flex", + "inline-flex", "list-item", "inline-block", "table", @@ -3694,6 +3696,170 @@ var gCSSProperties = { other_values: [ "non-scaling-stroke" ], invalid_values: [] }, + "align-items": { + domProp: "alignItems", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "stretch" ], + other_values: [ "flex-start", "flex-end", "center", "baseline" ], + invalid_values: [ "space-between", "abc", "30px" ] + }, + "align-self": { + domProp: "alignSelf", + inherited: false, + type: CSS_TYPE_LONGHAND, + // (Assuming defaults on the parent, 'auto' will compute to 'stretch'.) + initial_values: [ "auto", "stretch" ], + other_values: [ "flex-start", "flex-end", "center", "baseline" ], + invalid_values: [ "space-between", "abc", "30px" ] + }, + "flex": { + domProp: "flex", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "flex-grow", + "flex-shrink", + "flex-basis" + ], + initial_values: [ "0 1 auto", "auto 0 1", "0 auto", "auto 0" ], + other_values: [ + "none", + "1", + "0", + "0 1", + "0.5", + "1.2 3.4", + "0 0 0", + "0 0 0px", + "0px 0 0", + "5px 0 0", + "2 auto", + "auto 4", + "auto 5.6 7.8", + "-moz-max-content", + "1 -moz-max-content", + "1 2 -moz-max-content", + "-moz-max-content 1", + "-moz-max-content 1 2", + "-0" + ], + invalid_values: [ + "1 2px 3", + "1 auto 3", + "1px 2 3px", + "1px 2 3 4px", + "-1", + "1 -1" + ] + }, + "flex-basis": { + domProp: "flexBasis", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ " auto" ], + // NOTE: This is cribbed directly from the "width" chunk, since this + // property takes the exact same values as width (albeit with + // different semantics on 'auto'). + // XXXdholbert (Maybe these should get separated out into + // a reusable array defined at the top of this file?) + other_values: [ "15px", "3em", "15%", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available", + // valid calc() values + "calc(-2px)", + "calc(2px)", + "calc(50%)", + "calc(50% + 2px)", + "calc( 50% + 2px)", + "calc(50% + 2px )", + "calc( 50% + 2px )", + "calc(50% - -2px)", + "calc(2px - -50%)", + "calc(3*25px)", + "calc(3 *25px)", + "calc(3 * 25px)", + "calc(3* 25px)", + "calc(25px*3)", + "calc(25px *3)", + "calc(25px* 3)", + "calc(25px * 3)", + "calc(3*25px + 50%)", + "calc(50% - 3em + 2px)", + "calc(50% - (3em + 2px))", + "calc((50% - 3em) + 2px)", + "calc(2em)", + "calc(50%)", + "calc(50px/2)", + "calc(50px/(2 - 1))" + ], + invalid_values: [ "none", "-2px", + // invalid calc() values + "calc(50%+ 2px)", + "calc(50% +2px)", + "calc(50%+2px)", + "-moz-min()", + "calc(min())", + "-moz-max()", + "calc(max())", + "-moz-min(5px)", + "calc(min(5px))", + "-moz-max(5px)", + "calc(max(5px))", + "-moz-min(5px,2em)", + "calc(min(5px,2em))", + "-moz-max(5px,2em)", + "calc(max(5px,2em))", + "calc(50px/(2 - 2))", + // If we ever support division by values, which is + // complicated for the reasons described in + // http://lists.w3.org/Archives/Public/www-style/2010Jan/0007.html + // , we should support all 4 of these as described in + // http://lists.w3.org/Archives/Public/www-style/2009Dec/0296.html + "calc((3em / 100%) * 3em)", + "calc(3em / 100% * 3em)", + "calc(3em * (3em / 100%))", + "calc(3em * 3em / 100%)" + ] + }, + "flex-direction": { + domProp: "flexDirection", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "row" ], + other_values: [ "row-reverse", "column", "column-reverse" ], + invalid_values: [ "10px", "30%", "justify", "column wrap" ] + }, + "flex-grow": { + domProp: "flexGrow", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "0" ], + other_values: [ "3", "1", "1.0", "2.5", "123" ], + invalid_values: [ "0px", "-5", "1%", "3em", "stretch", "auto" ] + }, + "flex-shrink": { + domProp: "flexShrink", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "1" ], + other_values: [ "3", "0", "0.0", "2.5", "123" ], + invalid_values: [ "0px", "-5", "1%", "3em", "stretch", "auto" ] + }, + "order": { + domProp: "order", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "0" ], + other_values: [ "1", "99999", "-1", "-50" ], + invalid_values: [ "0px", "1.0", "1.", "1%", "0.2", "3em", "stretch" ] + }, + "justify-content": { + domProp: "justifyContent", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "flex-start" ], + other_values: [ "flex-end", "center", "space-between", "space-around" ], + invalid_values: [ "baseline", "stretch", "30px", "5%" ] + }, // Aliases "-moz-transform": { @@ -4068,182 +4234,6 @@ function get_computed_value(cs, property) return cs.getPropertyValue(property); } -// Automatically add pref-controlled CSS properties & keywords -// to gCSSProperties, if the flexbox pref is enabled. -if (SpecialPowers.getBoolPref("layout.css.flexbox.enabled")) { - var flexProperties = { - "align-items": { - domProp: "alignItems", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "stretch" ], - other_values: [ "flex-start", "flex-end", "center", "baseline" ], - invalid_values: [ "space-between", "abc", "30px" ] - }, - "align-self": { - domProp: "alignSelf", - inherited: false, - type: CSS_TYPE_LONGHAND, - // (Assuming defaults on the parent, 'auto' will compute to 'stretch'.) - initial_values: [ "auto", "stretch" ], - other_values: [ "flex-start", "flex-end", "center", "baseline" ], - invalid_values: [ "space-between", "abc", "30px" ] - }, - "flex": { - domProp: "flex", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "flex-grow", - "flex-shrink", - "flex-basis" - ], - initial_values: [ "0 1 auto", "auto 0 1", "0 auto", "auto 0" ], - other_values: [ - "none", - "1", - "0", - "0 1", - "0.5", - "1.2 3.4", - "0 0 0", - "0 0 0px", - "0px 0 0", - "5px 0 0", - "2 auto", - "auto 4", - "auto 5.6 7.8", - "-moz-max-content", - "1 -moz-max-content", - "1 2 -moz-max-content", - "-moz-max-content 1", - "-moz-max-content 1 2", - "-0" - ], - invalid_values: [ - "1 2px 3", - "1 auto 3", - "1px 2 3px", - "1px 2 3 4px", - "-1", - "1 -1" - ] - }, - "flex-basis": { - domProp: "flexBasis", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ " auto" ], - // NOTE: This is cribbed directly from the "width" chunk, since this - // property takes the exact same values as width (albeit with - // different semantics on 'auto'). - // XXXdholbert (Maybe these should get separated out into - // a reusable array defined at the top of this file?) - other_values: [ "15px", "3em", "15%", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available", - // valid calc() values - "calc(-2px)", - "calc(2px)", - "calc(50%)", - "calc(50% + 2px)", - "calc( 50% + 2px)", - "calc(50% + 2px )", - "calc( 50% + 2px )", - "calc(50% - -2px)", - "calc(2px - -50%)", - "calc(3*25px)", - "calc(3 *25px)", - "calc(3 * 25px)", - "calc(3* 25px)", - "calc(25px*3)", - "calc(25px *3)", - "calc(25px* 3)", - "calc(25px * 3)", - "calc(3*25px + 50%)", - "calc(50% - 3em + 2px)", - "calc(50% - (3em + 2px))", - "calc((50% - 3em) + 2px)", - "calc(2em)", - "calc(50%)", - "calc(50px/2)", - "calc(50px/(2 - 1))" - ], - invalid_values: [ "none", "-2px", - // invalid calc() values - "calc(50%+ 2px)", - "calc(50% +2px)", - "calc(50%+2px)", - "-moz-min()", - "calc(min())", - "-moz-max()", - "calc(max())", - "-moz-min(5px)", - "calc(min(5px))", - "-moz-max(5px)", - "calc(max(5px))", - "-moz-min(5px,2em)", - "calc(min(5px,2em))", - "-moz-max(5px,2em)", - "calc(max(5px,2em))", - "calc(50px/(2 - 2))", - // If we ever support division by values, which is - // complicated for the reasons described in - // http://lists.w3.org/Archives/Public/www-style/2010Jan/0007.html - // , we should support all 4 of these as described in - // http://lists.w3.org/Archives/Public/www-style/2009Dec/0296.html - "calc((3em / 100%) * 3em)", - "calc(3em / 100% * 3em)", - "calc(3em * (3em / 100%))", - "calc(3em * 3em / 100%)" - ] - }, - "flex-direction": { - domProp: "flexDirection", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "row" ], - other_values: [ "row-reverse", "column", "column-reverse" ], - invalid_values: [ "10px", "30%", "justify", "column wrap" ] - }, - "flex-grow": { - domProp: "flexGrow", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "0" ], - other_values: [ "3", "1", "1.0", "2.5", "123" ], - invalid_values: [ "0px", "-5", "1%", "3em", "stretch", "auto" ] - }, - "flex-shrink": { - domProp: "flexShrink", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "1" ], - other_values: [ "3", "0", "0.0", "2.5", "123" ], - invalid_values: [ "0px", "-5", "1%", "3em", "stretch", "auto" ] - }, - "order": { - domProp: "order", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "0" ], - other_values: [ "1", "99999", "-1", "-50" ], - invalid_values: [ "0px", "1.0", "1.", "1%", "0.2", "3em", "stretch" ] - }, - "justify-content": { - domProp: "justifyContent", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "flex-start" ], - other_values: [ "flex-end", "center", "space-between", "space-around" ], - invalid_values: [ "baseline", "stretch", "30px", "5%" ] - } - }; - for (var prop in flexProperties) { - gCSSProperties[prop] = flexProperties[prop]; - } - gCSSProperties["display"].other_values.push("flex"); - gCSSProperties["display"].other_values.push("inline-flex"); -} - if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { var verticalTextProperties = { "writing-mode": { diff --git a/layout/style/test/test_computed_style_prefs.html b/layout/style/test/test_computed_style_prefs.html index 9adcb4876186..56c0053050cd 100644 --- a/layout/style/test/test_computed_style_prefs.html +++ b/layout/style/test/test_computed_style_prefs.html @@ -69,7 +69,6 @@ function step() { var gProps = { "layout.css.vertical-text.enabled": ["text-combine-horizontal", "text-orientation", "writing-mode"], - "layout.css.flexbox.enabled": ["align-items", "align-self", "flex-basis", "flex-direction", "flex-grow", "flex-shrink", "order", "justify-content"], "layout.css.font-features.enabled": ["font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position"], "layout.css.image-orientation.enabled": ["image-orientation"], "layout.css.mix-blend-mode.enabled": ["mix-blend-mode"], diff --git a/layout/style/test/test_flexbox_align_self_auto.html b/layout/style/test/test_flexbox_align_self_auto.html index 9cdda6ba3551..5a5e37ab95db 100644 --- a/layout/style/test/test_flexbox_align_self_auto.html +++ b/layout/style/test/test_flexbox_align_self_auto.html @@ -12,31 +12,202 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=696253 Mozilla Bug 696253
- +
 
 
diff --git a/layout/style/test/test_flexbox_child_display_values.html b/layout/style/test/test_flexbox_child_display_values.html deleted file mode 100644 index d503d70ffa91..000000000000 --- a/layout/style/test/test_flexbox_child_display_values.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - Test "display" values of content in a flex container (Bug 783415) - - - - -Mozilla Bug 783415 -
- -
-
-
-
- - diff --git a/layout/style/test/file_flexbox_child_display_values.xhtml b/layout/style/test/test_flexbox_child_display_values.xhtml similarity index 93% rename from layout/style/test/file_flexbox_child_display_values.xhtml rename to layout/style/test/test_flexbox_child_display_values.xhtml index 53d646c19287..9a38748df929 100644 --- a/layout/style/test/file_flexbox_child_display_values.xhtml +++ b/layout/style/test/test_flexbox_child_display_values.xhtml @@ -1,6 +1,16 @@ + + + + Test "display" values of content in a flex container (Bug 783415) + + + -
+Mozilla Bug 783415 +
@@ -18,10 +28,6 @@
  * specified display-value.)
  */
 
-// Use "is()" and "ok()" from parent document.
-let is = parent.is;
-let ok = parent.ok;
-
 /*
  * Utility function for getting computed style of "display".
  *
@@ -120,9 +126,6 @@ function testDisplayValue(aSpecifiedDisplay,
  * Main test function
  */
 function main() {
-  ok(SpecialPowers.getBoolPref("layout.css.flexbox.enabled"),
-     "expecting to be run with flexbox support enabled");
-
   testDisplayValue("none");
   testDisplayValue("block");
   testDisplayValue("flex");
@@ -176,8 +179,6 @@ function main() {
     function(aSpecifiedDisplay) {
       testDisplayValue(aSpecifiedDisplay, aSpecifiedDisplay, "block");
   });
-
-  parent.finish();
 }
 
 main();
diff --git a/layout/style/test/test_flexbox_flex_grow_and_shrink.html b/layout/style/test/test_flexbox_flex_grow_and_shrink.html
index 4ac48ada4111..2cfb5c6e9692 100644
--- a/layout/style/test/test_flexbox_flex_grow_and_shrink.html
+++ b/layout/style/test/test_flexbox_flex_grow_and_shrink.html
@@ -7,12 +7,58 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=696253
   
   Test for flex-grow and flex-shrink animation (Bug 696253)
   
+  
   
+  
 
 
 Mozilla Bug 696253
 
- +
 
 
diff --git a/layout/style/test/test_flexbox_flex_shorthand.html b/layout/style/test/test_flexbox_flex_shorthand.html index 5c572f66138a..23d94a250827 100644 --- a/layout/style/test/test_flexbox_flex_shorthand.html +++ b/layout/style/test/test_flexbox_flex_shorthand.html @@ -7,36 +7,265 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=696253 Test for Bug 696253 + Mozilla Bug 696253
- +
+
-
 
diff --git a/layout/style/test/test_flexbox_layout.html b/layout/style/test/test_flexbox_layout.html index e39eacd32b98..5712d4a220db 100644 --- a/layout/style/test/test_flexbox_layout.html +++ b/layout/style/test/test_flexbox_layout.html @@ -7,36 +7,151 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=666041 Test for Bug 666041 + + Mozilla Bug 666041
- +
+
-
 
diff --git a/layout/style/test/test_flexbox_order.html b/layout/style/test/test_flexbox_order.html index 03507d28e0da..4d5a3890abca 100644 --- a/layout/style/test/test_flexbox_order.html +++ b/layout/style/test/test_flexbox_order.html @@ -7,12 +7,69 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=666041 Test for Bug 666041 + + Mozilla Bug 666041
- + + +
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
 
 
diff --git a/layout/style/test/test_flexbox_order_table.html b/layout/style/test/test_flexbox_order_table.html index 1bbd091d485d..e4fad7f40ad6 100644 --- a/layout/style/test/test_flexbox_order_table.html +++ b/layout/style/test/test_flexbox_order_table.html @@ -7,12 +7,73 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=799775 Test for Bug 799775 + + Mozilla Bug 799775
- + + +
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
 
 
diff --git a/layout/style/test/test_transitions_per_property.html b/layout/style/test/test_transitions_per_property.html index a82393e924e5..d772e66402e0 100644 --- a/layout/style/test/test_transitions_per_property.html +++ b/layout/style/test/test_transitions_per_property.html @@ -123,6 +123,12 @@ var supported_properties = { // (not parsing/interpolation) test_float_zeroToOne_clamped ], "filter" : [ test_filter_transition ], + "flex-basis": [ test_length_transition, test_percent_transition, + test_length_clamped, test_percent_clamped ], + "flex-grow": [ test_float_zeroToOne_transition, + test_float_aboveOne_transition ], + "flex-shrink": [ test_float_zeroToOne_transition, + test_float_aboveOne_transition ], "flood-color": [ test_color_transition ], "flood-opacity" : [ test_float_zeroToOne_transition, // opacity is clamped in computed style @@ -179,6 +185,7 @@ var supported_properties = { // opacity is clamped in computed style // (not parsing/interpolation) test_float_zeroToOne_clamped ], + "order": [ test_integer_transition ], "outline-color": [ test_color_transition ], "outline-offset": [ test_length_transition, test_length_unclamped ], "outline-width": [ test_length_transition, test_length_clamped ], @@ -244,23 +251,6 @@ var supported_properties = { "z-index": [ test_integer_transition, test_pos_integer_or_auto_transition ], }; -// Automatically add pref-controlled CSS properties & keywords -// to supported_properties, if the flexbox pref is enabled. -if (SpecialPowers.getBoolPref("layout.css.flexbox.enabled")) { - var flexbox_properties = { - "flex-basis": [ test_length_transition, test_percent_transition, - test_length_clamped, test_percent_clamped ], - "flex-grow": [ test_float_zeroToOne_transition, - test_float_aboveOne_transition ], - "flex-shrink": [ test_float_zeroToOne_transition, - test_float_aboveOne_transition ], - "order": [ test_integer_transition ] - }; - for (var prop in flexbox_properties) { - supported_properties[prop] = flexbox_properties[prop]; - } -} - var div = document.getElementById("display"); var OMTAdiv = document.getElementById("transformTest"); var cs = getComputedStyle(div, ""); diff --git a/layout/svg/nsSVGImageFrame.cpp b/layout/svg/nsSVGImageFrame.cpp index 21c30bf7632d..02687b3fd4fb 100644 --- a/layout/svg/nsSVGImageFrame.cpp +++ b/layout/svg/nsSVGImageFrame.cpp @@ -273,19 +273,19 @@ nsSVGImageFrame::TransformContextForPainting(gfxContext* aGfxContext, imageTransform = GetRasterImageTransform(nativeWidth, nativeHeight, FOR_PAINTING, aTransformRoot); + + // NOTE: We need to cancel out the effects of Full-Page-Zoom, or else + // it'll get applied an extra time by DrawSingleUnscaledImage. + nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel(); + gfxFloat pageZoomFactor = + nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPx); + imageTransform.Scale(pageZoomFactor, pageZoomFactor); } if (imageTransform.IsSingular()) { return false; } - // NOTE: We need to cancel out the effects of Full-Page-Zoom, or else - // it'll get applied an extra time by DrawSingleUnscaledImage. - nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel(); - gfxFloat pageZoomFactor = - nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPx); - imageTransform.Scale(pageZoomFactor, pageZoomFactor); - aGfxContext->Multiply(imageTransform); return true; } diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 2490c47d2c9e..3d2d8e154630 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -178,12 +178,11 @@ android-preqs = \ Makefile.in \ widget/GeckoView.java.frag \ $(SERVICES_MANIFEST_FRAGMENTS) \ - $(call mkdir_deps,$(sort $(dir $(PP_JAVAFILES)))) \ $(NULL) $(android-tgts): % : %.in $(android-preqs) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@ + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< -o $@) res/drawable-mdpi/icon.png: $(ICON_PATH) $(NSINSTALL) -D res/drawable-mdpi diff --git a/mobile/android/base/locales/Makefile.in b/mobile/android/base/locales/Makefile.in index 25d5e75d5103..acbb04cb5268 100644 --- a/mobile/android/base/locales/Makefile.in +++ b/mobile/android/base/locales/Makefile.in @@ -62,9 +62,7 @@ strings-xml-preqs =\ $(if $(MOZ_ANDROID_SHARED_ACCOUNT_TYPE),,$(error Missing MOZ_ANDROID_SHARED_ACCOUNT_TYPE)) $(dir-strings-xml)/strings.xml: $(strings-xml-preqs) - $(NSINSTALL) -D $(dir-strings-xml) - $(TOUCH) $(call mkdir_deps,$(dir-strings-xml)) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ + $(call py_action,preprocessor, \ $(DEFINES) \ -DANDROID_PACKAGE_NAME=$(ANDROID_PACKAGE_NAME) \ -DBOOKMARKSPATH="$(BOOKMARKSPATH)" \ @@ -74,4 +72,4 @@ $(dir-strings-xml)/strings.xml: $(strings-xml-preqs) -DSTRINGSPATH="$(STRINGSPATH)" \ -DSYNCSTRINGSPATH="$(SYNCSTRINGSPATH)" \ $< \ - > $@ + -o $@) diff --git a/mobile/android/installer/Makefile.in b/mobile/android/installer/Makefile.in index a2f3cb8a9d5f..1c982726412e 100644 --- a/mobile/android/installer/Makefile.in +++ b/mobile/android/installer/Makefile.in @@ -47,7 +47,7 @@ endif ifdef MOZ_PKG_MANIFEST_P $(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) $(GLOBAL_DEPS) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $< > $@ + $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $< -o $@) ifdef MOZ_CHROME_MULTILOCALE printf "\n[multilocale]\n" >> $@ for LOCALE in en-US $(MOZ_CHROME_MULTILOCALE) ;\ diff --git a/mobile/locales/Makefile.in b/mobile/locales/Makefile.in index f928917e1d55..44f17538389e 100644 --- a/mobile/locales/Makefile.in +++ b/mobile/locales/Makefile.in @@ -177,21 +177,19 @@ bookmarks-inc = $(firstword $(bookmarks-inc-array)) bookmarks-preqs = \ $(bookmarks-inc) \ - $(call mkdir_deps,$(dir $(bookmarks-ts))) \ $(src-bookmarks) \ generic/profile/$(bookmarks).in \ - $(topsrcdir)/config/Preprocessor.py \ $(if $(IS_LANGUAGE_REPACK),FORCE) \ $(GLOBAL_DEPS) \ $(NULL) $(bookmarks-ts): $(bookmarks-preqs) $(display_deps) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ + $(call py_action,preprocessor, \ -I $< \ -DAB_CD=$(NO_JA_JP_MAC_AB_CD) \ $(src-bookmarks) \ - > $@ + -o $@) .PHONY: bookmarks $(bookmarks) bookmarks: $(bookmarks) diff --git a/modules/libmar/tests/Makefile.in b/modules/libmar/tests/Makefile.in index fbe09d93c6c5..d3779410a559 100644 --- a/modules/libmar/tests/Makefile.in +++ b/modules/libmar/tests/Makefile.in @@ -9,7 +9,7 @@ DEFINES += -DBIN_SUFFIX=$(BIN_SUFFIX) include $(topsrcdir)/config/rules.mk libs:: unit/head_libmar.js.in - $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) $^ > $(TESTROOT)/unit/head_libmar.js + $(call py_action,preprocessor,-Fsubstitution $(DEFINES) $(ACDEFINES) $^ -o $(TESTROOT)/unit/head_libmar.js) ifneq ($(OS_TARGET),Android) ifndef MOZ_PROFILE_GENERATE diff --git a/modules/libpref/src/Makefile.in b/modules/libpref/src/Makefile.in index 31333bce9427..e4ca661d02cb 100644 --- a/modules/libpref/src/Makefile.in +++ b/modules/libpref/src/Makefile.in @@ -40,7 +40,7 @@ endif greprefs.js: $(grepref_files) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $^ > $@ + $(call py_action,preprocessor,$(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $^ -o $@) libs:: greprefs.js $(INSTALL) $^ $(DIST)/bin/ diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 716823270b25..dfa7557d7266 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1606,6 +1606,7 @@ pref("security.notification_enable_delay", 500); pref("security.csp.enable", true); pref("security.csp.debug", false); +pref("security.csp.experimentalEnabled", false); // Mixed content blocking pref("security.mixed_content.block_active_content", false); @@ -1873,9 +1874,6 @@ pref("layout.css.supports-rule.enabled", true); // Is support for CSS Filters enabled? pref("layout.css.filters.enabled", false); -// Is support for CSS Flexbox enabled? -pref("layout.css.flexbox.enabled", true); - // Is support for CSS sticky positioning enabled? #ifdef RELEASE_BUILD pref("layout.css.sticky.enabled", false); diff --git a/mozglue/build/Makefile.in b/mozglue/build/Makefile.in index 0ad69ec9fa94..cd4dae23975a 100644 --- a/mozglue/build/Makefile.in +++ b/mozglue/build/Makefile.in @@ -36,7 +36,7 @@ ifeq (WINNT,$(OS_TARGET)) DEFFILE = mozglue.def mozglue.def: mozglue.def.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(if $(MOZ_REPLACE_MALLOC),-DMOZ_REPLACE_MALLOC) $(ACDEFINES) $< > $@ + $(call py_action,preprocessor,$(if $(MOZ_REPLACE_MALLOC),-DMOZ_REPLACE_MALLOC) $(ACDEFINES) $< -o $@) GARBAGE += mozglue.def diff --git a/netwerk/base/public/security-prefs.js b/netwerk/base/public/security-prefs.js index 16c4d3c6917f..5ab36880e514 100644 --- a/netwerk/base/public/security-prefs.js +++ b/netwerk/base/public/security-prefs.js @@ -16,44 +16,6 @@ pref("security.ssl.enable_false_start", false); pref("security.ssl.false_start.require-npn", true); pref("security.ssl.false_start.require-forward-secrecy", false); -pref("security.ssl3.rsa_rc4_128_md5", true); -pref("security.ssl3.rsa_rc4_128_sha", true); -pref("security.ssl3.rsa_fips_des_ede3_sha", true); -pref("security.ssl3.rsa_des_ede3_sha", true); -pref("security.ssl3.dhe_rsa_camellia_256_sha", true); -pref("security.ssl3.dhe_dss_camellia_256_sha", true); -pref("security.ssl3.rsa_camellia_256_sha", true); -pref("security.ssl3.dhe_rsa_camellia_128_sha", true); -pref("security.ssl3.dhe_dss_camellia_128_sha", true); -pref("security.ssl3.rsa_camellia_128_sha", true); -pref("security.ssl3.dhe_rsa_aes_256_sha", true); -pref("security.ssl3.dhe_dss_aes_256_sha", true); -pref("security.ssl3.rsa_aes_256_sha", true); -pref("security.ssl3.ecdhe_ecdsa_aes_256_sha", true); -pref("security.ssl3.ecdhe_ecdsa_aes_128_sha", true); -pref("security.ssl3.ecdhe_ecdsa_des_ede3_sha", true); -pref("security.ssl3.ecdhe_ecdsa_rc4_128_sha", true); -pref("security.ssl3.ecdhe_rsa_aes_256_sha", true); -pref("security.ssl3.ecdhe_rsa_aes_128_sha", true); -pref("security.ssl3.ecdhe_rsa_des_ede3_sha", true); -pref("security.ssl3.ecdhe_rsa_rc4_128_sha", true); -pref("security.ssl3.ecdh_ecdsa_aes_256_sha", true); -pref("security.ssl3.ecdh_ecdsa_aes_128_sha", true); -pref("security.ssl3.ecdh_ecdsa_des_ede3_sha", true); -pref("security.ssl3.ecdh_ecdsa_rc4_128_sha", true); -pref("security.ssl3.ecdh_rsa_aes_256_sha", true); -pref("security.ssl3.ecdh_rsa_aes_128_sha", true); -pref("security.ssl3.ecdh_rsa_des_ede3_sha", true); -pref("security.ssl3.ecdh_rsa_rc4_128_sha", true); -pref("security.ssl3.dhe_rsa_aes_128_sha", true); -pref("security.ssl3.dhe_dss_aes_128_sha", true); -pref("security.ssl3.rsa_aes_128_sha", true); -pref("security.ssl3.dhe_rsa_des_ede3_sha", true); -pref("security.ssl3.dhe_dss_des_ede3_sha", true); -pref("security.ssl3.rsa_seed_sha", true); -pref("security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", false); -pref("security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", false); - pref("security.default_personal_cert", "Ask Every Time"); pref("security.remember_cert_checkbox_default_setting", true); pref("security.ask_for_password", 0); diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 7e0ba535040c..65c24906b937 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -2838,6 +2838,19 @@ nsHttpConnectionMgr::nsHalfOpenSocket::Abandon() nsRefPtr deleteProtector(this); + // Tell socket (and backup socket) to forget the half open socket. + if (mSocketTransport) { + mSocketTransport->SetEventSink(nullptr, nullptr); + mSocketTransport->SetSecurityCallbacks(nullptr); + mSocketTransport = nullptr; + } + if (mBackupTransport) { + mBackupTransport->SetEventSink(nullptr, nullptr); + mBackupTransport->SetSecurityCallbacks(nullptr); + mBackupTransport = nullptr; + } + + // Tell output stream (and backup) to forget the half open socket. if (mStreamOut) { gHttpHandler->ConnMgr()->RecvdConnect(); mStreamOut->AsyncWait(nullptr, 0, 0, nullptr); @@ -2849,8 +2862,13 @@ nsHttpConnectionMgr::nsHalfOpenSocket::Abandon() mBackupStreamOut = nullptr; } + // Lose references to input stream (and backup). + mStreamIn = mBackupStreamIn = nullptr; + + // Stop the timer - we don't want any new backups. CancelBackupTimer(); + // Remove the half open from the connection entry. if (mEnt) mEnt->RemoveHalfOpen(this); mEnt = nullptr; diff --git a/nsprpub/TAG-INFO b/nsprpub/TAG-INFO index 7924a0f09cd6..4cf11c329c1d 100644 --- a/nsprpub/TAG-INFO +++ b/nsprpub/TAG-INFO @@ -1 +1 @@ -NSPR_4_10_2_BETA1 +NSPR_4_10_2_RTM diff --git a/nsprpub/config/prdepend.h b/nsprpub/config/prdepend.h index e49e92677e3e..6c66b37ca0fc 100644 --- a/nsprpub/config/prdepend.h +++ b/nsprpub/config/prdepend.h @@ -10,3 +10,4 @@ */ #error "Do not include this header file." + diff --git a/nsprpub/lib/ds/plarena.c b/nsprpub/lib/ds/plarena.c index 23610ea88d94..95e1931ee66b 100644 --- a/nsprpub/lib/ds/plarena.c +++ b/nsprpub/lib/ds/plarena.c @@ -153,7 +153,7 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb) { a = pool->current; do { - if ( a->avail +nb <= a->limit ) { + if ( nb <= a->limit - a->avail ) { pool->current = a; rp = (char *)a->avail; a->avail += nb; @@ -171,7 +171,7 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb) return(0); for ( a = arena_freelist, p = NULL; a != NULL ; p = a, a = a->next ) { - if ( a->base +nb <= a->limit ) { + if ( nb <= a->limit - a->base ) { if ( p == NULL ) arena_freelist = a->next; else @@ -196,8 +196,12 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb) /* attempt to allocate from the heap */ { PRUint32 sz = PR_MAX(pool->arenasize, nb); - sz += sizeof *a + pool->mask; /* header and alignment slop */ - a = (PLArena*)PR_MALLOC(sz); + if (PR_UINT32_MAX - sz < sizeof *a + pool->mask) { + a = NULL; + } else { + sz += sizeof *a + pool->mask; /* header and alignment slop */ + a = (PLArena*)PR_MALLOC(sz); + } if ( NULL != a ) { a->limit = (PRUword)a + sz; a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1); diff --git a/nsprpub/pr/include/prinit.h b/nsprpub/pr/include/prinit.h index d2e76bbf2e29..557f2e2202b4 100644 --- a/nsprpub/pr/include/prinit.h +++ b/nsprpub/pr/include/prinit.h @@ -31,11 +31,11 @@ PR_BEGIN_EXTERN_C ** The format of the version string is ** ".[.] []" */ -#define PR_VERSION "4.10.2 Beta" +#define PR_VERSION "4.10.2" #define PR_VMAJOR 4 #define PR_VMINOR 10 #define PR_VPATCH 2 -#define PR_BETA PR_TRUE +#define PR_BETA PR_FALSE /* ** PRVersionCheck diff --git a/nsprpub/pr/src/pthreads/ptio.c b/nsprpub/pr/src/pthreads/ptio.c index abf61d5d2b83..79d58ce8fa05 100644 --- a/nsprpub/pr/src/pthreads/ptio.c +++ b/nsprpub/pr/src/pthreads/ptio.c @@ -4586,7 +4586,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd) if (!_pr_initialized) _PR_ImplicitInitialization(); fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP, PR_FALSE, PR_TRUE); - if (NULL != fd) close(osfd); + if (NULL == fd) close(osfd); return fd; } /* PR_ImportUDPSocket */ diff --git a/python/mozbuild/mozbuild/action/preprocessor.py b/python/mozbuild/mozbuild/action/preprocessor.py new file mode 100644 index 000000000000..d99e1f831a4e --- /dev/null +++ b/python/mozbuild/mozbuild/action/preprocessor.py @@ -0,0 +1,16 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import sys + +from mozbuild.preprocessor import Preprocessor + + +def main(args): + pp = Preprocessor() + pp.handleCommandLine(args, True) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/python/mozbuild/mozbuild/backend/configenvironment.py b/python/mozbuild/mozbuild/backend/configenvironment.py index 7f5e75d2afe0..e2ea97eeea97 100644 --- a/python/mozbuild/mozbuild/backend/configenvironment.py +++ b/python/mozbuild/mozbuild/backend/configenvironment.py @@ -10,7 +10,7 @@ import sys from os.path import relpath -from Preprocessor import Preprocessor +from mozbuild.preprocessor import Preprocessor from ..util import ( ensureParentDir, diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 1ee71ff8ae6f..95e6f24d55fb 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -445,8 +445,12 @@ class RecursiveMakeBackend(CommonBackend): # automated. if isinstance(obj.wrapped, JavaJarData): self._process_java_jar_data(obj.wrapped, backend_file) + else: + return - self._backend_files[obj.srcdir] = backend_file + else: + return + obj.ack() def _fill_root_mk(self): """ diff --git a/python/mozbuild/mozbuild/frontend/data.py b/python/mozbuild/mozbuild/frontend/data.py index d84377b3e0c0..5a57f920b015 100644 --- a/python/mozbuild/mozbuild/frontend/data.py +++ b/python/mozbuild/mozbuild/frontend/data.py @@ -26,11 +26,18 @@ from .sandbox_symbols import compute_final_target class TreeMetadata(object): """Base class for all data being captured.""" + def __init__(self): + self._ack = False + + def ack(self): + self._ack = True + class ReaderSummary(TreeMetadata): """A summary of what the reader did.""" def __init__(self, total_file_count, total_execution_time): + TreeMetadata.__init__(self) self.total_file_count = total_file_count self.total_execution_time = total_execution_time @@ -53,6 +60,8 @@ class SandboxDerived(TreeMetadata): ) def __init__(self, sandbox): + TreeMetadata.__init__(self) + # Capture the files that were evaluated to build this sandbox. self.sandbox_main_path = sandbox.main_path self.sandbox_all_paths = sandbox.all_paths diff --git a/python/mozbuild/mozbuild/frontend/emitter.py b/python/mozbuild/mozbuild/frontend/emitter.py index efcc74165ddd..2b756317af34 100644 --- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -83,6 +83,8 @@ class TreeMetadataEmitter(LoggingMixin): if isinstance(out, MozbuildSandbox): for o in self.emit_from_sandbox(out): yield o + if not o._ack: + raise Exception('Unhandled object of type %s' % type(o)) # Update the stats. file_count += len(out.all_paths) diff --git a/python/mozbuild/mozbuild/jar.py b/python/mozbuild/mozbuild/jar.py index 74b0f4392bcb..7e830b2e0331 100644 --- a/python/mozbuild/mozbuild/jar.py +++ b/python/mozbuild/mozbuild/jar.py @@ -22,7 +22,7 @@ from mozbuild.util import ( PushbackIter, ) -from Preprocessor import Preprocessor +from mozbuild.preprocessor import Preprocessor from mozbuild.action.buildlist import addEntriesToListFile if sys.platform == 'win32': from ctypes import windll, WinError diff --git a/config/Preprocessor.py b/python/mozbuild/mozbuild/preprocessor.py similarity index 65% rename from config/Preprocessor.py rename to python/mozbuild/mozbuild/preprocessor.py index 86891acaf3c6..4d79cf0d73d3 100644 --- a/config/Preprocessor.py +++ b/python/mozbuild/mozbuild/preprocessor.py @@ -1,6 +1,22 @@ """ This is a very primitive line based preprocessor, for times when using a C preprocessor isn't an option. + +It currently supports the following grammar for expressions, whitespace is +ignored: + +expression : + and_cond ( '||' expression ) ? ; +and_cond: + test ( '&&' and_cond ) ? ; +test: + unary ( ( '==' | '!=' ) unary ) ? ; +unary : + '!'? value ; +value : + [0-9]+ # integer + | 'defined(' \w+ ')' + | \w+ # string identifier or value; """ # This Source Code Form is subject to the terms of the Mozilla Public @@ -21,9 +37,231 @@ if sys.platform == "win32": msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) os.linesep = '\n' -import Expression -__all__ = ['Preprocessor', 'preprocess'] +__all__ = [ + 'Context', + 'Expression', + 'Preprocessor', + 'preprocess' +] + + +class Expression: + def __init__(self, expression_string): + """ + Create a new expression with this string. + The expression will already be parsed into an Abstract Syntax Tree. + """ + self.content = expression_string + self.offset = 0 + self.__ignore_whitespace() + self.e = self.__get_logical_or() + if self.content: + raise Expression.ParseError, self + + def __get_logical_or(self): + """ + Production: and_cond ( '||' expression ) ? + """ + if not len(self.content): + return None + rv = Expression.__AST("logical_op") + # test + rv.append(self.__get_logical_and()) + self.__ignore_whitespace() + if self.content[:2] != '||': + # no logical op needed, short cut to our prime element + return rv[0] + # append operator + rv.append(Expression.__ASTLeaf('op', self.content[:2])) + self.__strip(2) + self.__ignore_whitespace() + rv.append(self.__get_logical_or()) + self.__ignore_whitespace() + return rv + + def __get_logical_and(self): + """ + Production: test ( '&&' and_cond ) ? + """ + if not len(self.content): + return None + rv = Expression.__AST("logical_op") + # test + rv.append(self.__get_equality()) + self.__ignore_whitespace() + if self.content[:2] != '&&': + # no logical op needed, short cut to our prime element + return rv[0] + # append operator + rv.append(Expression.__ASTLeaf('op', self.content[:2])) + self.__strip(2) + self.__ignore_whitespace() + rv.append(self.__get_logical_and()) + self.__ignore_whitespace() + return rv + + def __get_equality(self): + """ + Production: unary ( ( '==' | '!=' ) unary ) ? + """ + if not len(self.content): + return None + rv = Expression.__AST("equality") + # unary + rv.append(self.__get_unary()) + self.__ignore_whitespace() + if not re.match('[=!]=', self.content): + # no equality needed, short cut to our prime unary + return rv[0] + # append operator + rv.append(Expression.__ASTLeaf('op', self.content[:2])) + self.__strip(2) + self.__ignore_whitespace() + rv.append(self.__get_unary()) + self.__ignore_whitespace() + return rv + + def __get_unary(self): + """ + Production: '!'? value + """ + # eat whitespace right away, too + not_ws = re.match('!\s*', self.content) + if not not_ws: + return self.__get_value() + rv = Expression.__AST('not') + self.__strip(not_ws.end()) + rv.append(self.__get_value()) + self.__ignore_whitespace() + return rv + + def __get_value(self): + """ + Production: ( [0-9]+ | 'defined(' \w+ ')' | \w+ ) + Note that the order is important, and the expression is kind-of + ambiguous as \w includes 0-9. One could make it unambiguous by + removing 0-9 from the first char of a string literal. + """ + rv = None + m = re.match('defined\s*\(\s*(\w+)\s*\)', self.content) + if m: + word_len = m.end() + rv = Expression.__ASTLeaf('defined', m.group(1)) + else: + word_len = re.match('[0-9]*', self.content).end() + if word_len: + value = int(self.content[:word_len]) + rv = Expression.__ASTLeaf('int', value) + else: + word_len = re.match('\w*', self.content).end() + if word_len: + rv = Expression.__ASTLeaf('string', self.content[:word_len]) + else: + raise Expression.ParseError, self + self.__strip(word_len) + self.__ignore_whitespace() + return rv + + def __ignore_whitespace(self): + ws_len = re.match('\s*', self.content).end() + self.__strip(ws_len) + return + + def __strip(self, length): + """ + Remove a given amount of chars from the input and update + the offset. + """ + self.content = self.content[length:] + self.offset += length + + def evaluate(self, context): + """ + Evaluate the expression with the given context + """ + + # Helper function to evaluate __get_equality results + def eval_equality(tok): + left = opmap[tok[0].type](tok[0]) + right = opmap[tok[2].type](tok[2]) + rv = left == right + if tok[1].value == '!=': + rv = not rv + return rv + # Helper function to evaluate __get_logical_and and __get_logical_or results + def eval_logical_op(tok): + left = opmap[tok[0].type](tok[0]) + right = opmap[tok[2].type](tok[2]) + if tok[1].value == '&&': + return left and right + elif tok[1].value == '||': + return left or right + raise Expression.ParseError, self + + # Mapping from token types to evaluator functions + # Apart from (non-)equality, all these can be simple lambda forms. + opmap = { + 'logical_op': eval_logical_op, + 'equality': eval_equality, + 'not': lambda tok: not opmap[tok[0].type](tok[0]), + 'string': lambda tok: context[tok.value], + 'defined': lambda tok: tok.value in context, + 'int': lambda tok: tok.value} + + return opmap[self.e.type](self.e); + + class __AST(list): + """ + Internal class implementing Abstract Syntax Tree nodes + """ + def __init__(self, type): + self.type = type + super(self.__class__, self).__init__(self) + + class __ASTLeaf: + """ + Internal class implementing Abstract Syntax Tree leafs + """ + def __init__(self, type, value): + self.value = value + self.type = type + def __str__(self): + return self.value.__str__() + def __repr__(self): + return self.value.__repr__() + + class ParseError(StandardError): + """ + Error raised when parsing fails. + It has two members, offset and content, which give the offset of the + error and the offending content. + """ + def __init__(self, expression): + self.offset = expression.offset + self.content = expression.content[:3] + def __str__(self): + return 'Unexpected content at offset {0}, "{1}"'.format(self.offset, + self.content) + +class Context(dict): + """ + This class holds variable values by subclassing dict, and while it + truthfully reports True and False on + + name in context + + it returns the variable name itself on + + context["name"] + + to reflect the ambiguity between string literals and preprocessor + variables. + """ + def __getitem__(self, key): + if key in self: + return super(self.__class__, self).__getitem__(key) + return key class Preprocessor: @@ -37,7 +275,7 @@ class Preprocessor: self.key = MSG RuntimeError.__init__(self, (self.file, self.line, self.key, context)) def __init__(self): - self.context = Expression.Context() + self.context = Context() for k,v in {'FILE': '', 'LINE': 0, 'DIRECTORY': os.path.abspath('.')}.iteritems(): @@ -75,7 +313,9 @@ class Preprocessor: self.setMarker('#') self.LE = '\n' self.varsubst = re.compile('@(?P\w+)@', re.U) - + self.depfile = None + self.includes = set() + def warnUnused(self, file): if self.actionLevel == 0: sys.stderr.write('{0}: WARNING: no preprocessor directives found\n'.format(file)) @@ -88,7 +328,7 @@ class Preprocessor: Set the line endings to be used for output. """ self.LE = {'cr': '\x0D', 'lf': '\x0A', 'crlf': '\x0D\x0A'}[aLE] - + def setMarker(self, aMarker): """ Set the marker to be used for processing directives. @@ -98,7 +338,7 @@ class Preprocessor: self.marker = aMarker if aMarker: self.instruction = re.compile('{0}(?P[a-z]+)(?:\s(?P.*))?$' - .format(aMarker), + .format(aMarker), re.U) self.comment = re.compile(aMarker, re.U) else: @@ -106,7 +346,7 @@ class Preprocessor: def match(self, *args): return False self.instruction = self.comment = NoMatch() - + def clone(self): """ Create a clone of the current processor, including line ending @@ -118,12 +358,12 @@ class Preprocessor: rv.LE = self.LE rv.out = self.out return rv - + def applyFilters(self, aLine): for f in self.filters: aLine = f[1](aLine) return aLine - + def write(self, aLine): """ Internal method for handling output. @@ -143,32 +383,54 @@ class Preprocessor: # with universal line ending support, at least for files. filteredLine = re.sub('\n', self.LE, filteredLine) self.out.write(filteredLine) - + def handleCommandLine(self, args, defaultToStdin = False): """ Parse a commandline into this parser. Uses OptionParser internally, no args mean sys.argv[1:]. """ - p = self.getCommandLineParser() - (options, args) = p.parse_args(args=args) - includes = options.I - if options.output: - dir = os.path.dirname(options.output) + def get_output_file(path): + dir = os.path.dirname(path) if dir and not os.path.exists(dir): try: os.makedirs(dir) except OSError as error: if error.errno != errno.EEXIST: raise - self.out = open(options.output, 'wb') + return open(path, 'wb') + + p = self.getCommandLineParser() + options, args = p.parse_args(args=args) + includes = options.I + if options.output: + self.out = get_output_file(options.output) if defaultToStdin and len(args) == 0: args = [sys.stdin] + if options.depend: + raise Preprocessor.Error(self, "--depend doesn't work with stdin", + None) + if options.depend: + if not options.output: + raise Preprocessor.Error(self, "--depend doesn't work with stdout", + None) + try: + from makeutil import Makefile + except: + raise Preprocessor.Error(self, "--depend requires the " + "mozbuild.makeutil module", None) + self.depfile = get_output_file(options.depend) includes.extend(args) if includes: for f in includes: self.do_include(f, False) self.warnUnused(f) - pass + if self.depfile: + mk = Makefile() + mk.create_rule([options.output]).add_dependencies(self.includes) + mk.dump(self.depfile) + self.depfile.close() + if options.output: + self.out.close() def getCommandLineParser(self, unescapeDefines = False): escapedValue = re.compile('".*"$') @@ -208,6 +470,8 @@ class Preprocessor: p.add_option('-o', '--output', type="string", default=None, metavar="FILENAME", help='Output to the specified file '+ 'instead of stdout') + p.add_option('--depend', type="string", default=None, metavar="FILENAME", + help='Generate dependencies in the given file') p.add_option('--line-endings', action='callback', callback=handleLE, type="string", metavar="[cr|lr|crlf]", help='Use the specified line endings [Default: OS dependent]') @@ -243,7 +507,7 @@ class Preprocessor: # Instruction handlers # These are named do_'instruction name' and take one argument - + # Variables def do_define(self, args): m = re.match('(?P\w+)(?:\s(?P.*))?', args, re.U) @@ -273,7 +537,7 @@ class Preprocessor: return val = None try: - e = Expression.Expression(args) + e = Expression(args) val = e.evaluate(self.context) except Exception: # XXX do real error reporting @@ -453,6 +717,8 @@ class Preprocessor: self.context['DIRECTORY'] = '' else: abspath = os.path.abspath(args.name) + if self.depfile: + self.includes.add(abspath) self.context['FILE'] = abspath self.context['DIRECTORY'] = os.path.dirname(abspath) self.context['LINE'] = 0 @@ -472,10 +738,6 @@ class Preprocessor: def do_error(self, args): raise Preprocessor.Error(self, 'Error: ', str(args)) -def main(): - pp = Preprocessor() - pp.handleCommandLine(None, True) - return def preprocess(includes=[sys.stdin], defines={}, output = sys.stdout, @@ -488,5 +750,8 @@ def preprocess(includes=[sys.stdin], defines={}, for f in includes: pp.do_include(f, False) + +# Keep this module independently executable. if __name__ == "__main__": - main() + pp = Preprocessor() + pp.handleCommandLine(None, True) diff --git a/python/mozbuild/mozbuild/test/frontend/test_emitter.py b/python/mozbuild/mozbuild/test/frontend/test_emitter.py index 8e435ecdb225..79d0556a220b 100644 --- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py +++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py @@ -47,8 +47,11 @@ class TestEmitterBasic(unittest.TestCase): def read_topsrcdir(self, reader): emitter = TreeMetadataEmitter(reader.config) + def ack(obj): + obj.ack() + return obj - objs = list(emitter.emit(reader.read_topsrcdir())) + objs = list(ack(o) for o in emitter.emit(reader.read_topsrcdir())) self.assertGreater(len(objs), 0) self.assertIsInstance(objs[-1], ReaderSummary) diff --git a/config/tests/unit-Expression.py b/python/mozbuild/mozbuild/test/test_expression.py similarity index 97% rename from config/tests/unit-Expression.py rename to python/mozbuild/mozbuild/test/test_expression.py index d153211e9342..fb3c45894c81 100644 --- a/config/tests/unit-Expression.py +++ b/python/mozbuild/mozbuild/test/test_expression.py @@ -4,7 +4,7 @@ import sys import os.path import mozunit -from Expression import Expression, Context +from mozbuild.preprocessor import Expression, Context class TestContext(unittest.TestCase): """ diff --git a/config/tests/unit-LineEndings.py b/python/mozbuild/mozbuild/test/test_line_endings.py similarity index 95% rename from config/tests/unit-LineEndings.py rename to python/mozbuild/mozbuild/test/test_line_endings.py index 56914aae9945..565abc8c93ff 100644 --- a/config/tests/unit-LineEndings.py +++ b/python/mozbuild/mozbuild/test/test_line_endings.py @@ -6,7 +6,7 @@ import sys import os.path import mozunit -from Preprocessor import Preprocessor +from mozbuild.preprocessor import Preprocessor class TestLineEndings(unittest.TestCase): """ diff --git a/config/tests/unit-Preprocessor.py b/python/mozbuild/mozbuild/test/test_preprocessor.py similarity index 99% rename from config/tests/unit-Preprocessor.py rename to python/mozbuild/mozbuild/test/test_preprocessor.py index 9ca640b20977..3039b204827e 100644 --- a/config/tests/unit-Preprocessor.py +++ b/python/mozbuild/mozbuild/test/test_preprocessor.py @@ -6,7 +6,7 @@ import sys import os.path from mozunit import main, MockedOpen -from Preprocessor import Preprocessor +from mozbuild.preprocessor import Preprocessor def NamedIO(name, content): with open(name, 'w') as f: diff --git a/python/mozbuild/mozpack/packager/__init__.py b/python/mozbuild/mozpack/packager/__init__.py index 6ad3ccc9ca15..5e83c1a6f9a5 100644 --- a/python/mozbuild/mozpack/packager/__init__.py +++ b/python/mozbuild/mozpack/packager/__init__.py @@ -2,7 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from Preprocessor import Preprocessor +from mozbuild.preprocessor import Preprocessor import re import os from mozpack.errors import errors diff --git a/python/mozbuild/mozpack/test/test_packager.py b/python/mozbuild/mozpack/test/test_packager.py index 3d84fe950a75..3dd10f0723b8 100644 --- a/python/mozbuild/mozpack/test/test_packager.py +++ b/python/mozbuild/mozpack/test/test_packager.py @@ -18,7 +18,7 @@ from mozpack.chrome.manifest import ( ManifestContent, ) from mozunit import MockedOpen -from Preprocessor import Preprocessor +from mozbuild.preprocessor import Preprocessor from mozpack.errors import ( errors, ErrorMessage, diff --git a/security/build/Makefile.in b/security/build/Makefile.in index dbce3103a5cd..030264c15b46 100644 --- a/security/build/Makefile.in +++ b/security/build/Makefile.in @@ -384,8 +384,6 @@ nss3.def: $(NSS_STATIC_LIBS_DEFS) $(DEPTH)/db/sqlite3/src/sqlite-processed.def mv $@.tmp $@ endif -else -$(NSS_DIST_DLL_FILES) $(NSS_SDK_LIB_FILES): libs-nss/lib endif # MOZ_FOLD_LIBS include $(topsrcdir)/config/rules.mk @@ -446,6 +444,8 @@ libs-nss/lib/freebl: $(DIST)/lib/$(IMPORT_PREFIX)nssutil3$(IMPORT_SUFFIX) $(NSPR # For each directory where we build static libraries, force the NSS build system # to only build static libraries. $(addprefix libs-,$(NSS_STATIC_DIRS)): DEFAULT_GMAKE_FLAGS += SHARED_LIBRARY= IMPORT_LIBRARY= +else +$(NSS_DIST_DLL_FILES) $(NSS_SDK_LIB_FILES): libs-nss/lib endif # MOZ_FOLD_LIBS ifeq ($(NSINSTALL_PY),$(NSINSTALL)) diff --git a/security/manager/ssl/src/nsCrypto.cpp b/security/manager/ssl/src/nsCrypto.cpp index f9d7e29b024b..96f34b66b5ad 100644 --- a/security/manager/ssl/src/nsCrypto.cpp +++ b/security/manager/ssl/src/nsCrypto.cpp @@ -1926,7 +1926,8 @@ nsCrypto::GenerateCRMFRequest(JSContext* aContext, csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL, NS_ConvertASCIItoUTF16(fileName), scriptSample, - lineNum); + lineNum, + EmptyString()); } if (!evalAllowed) { diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 8374f83b605c..621dbe72d67d 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -828,31 +828,70 @@ nsNSSComponent::InitializePIPNSSBundle() typedef struct { const char* pref; long id; + bool enabledByDefault; } CipherPref; -static CipherPref CipherPrefs[] = { - /* SSL3/TLS cipher suites*/ - {"security.ssl3.rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5}, // 128-bit RC4 encryption with RSA and an MD5 MAC - {"security.ssl3.rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA}, // 128-bit RC4 encryption with RSA and a SHA1 MAC - {"security.ssl3.rsa_fips_des_ede3_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with RSA and a SHA1 MAC (FIPS) - {"security.ssl3.rsa_des_ede3_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with RSA and a SHA1 MAC - /* Extra SSL3/TLS cipher suites */ - {"security.ssl3.dhe_rsa_camellia_256_sha", TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA}, // 256-bit Camellia encryption with RSA, DHE, and a SHA1 MAC +static const CipherPref sCipherPrefs[] = { + { "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, true }, + { "security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, true }, + { "security.ssl3.ecdhe_rsa_aes_128_sha", + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, true }, + { "security.ssl3.ecdhe_ecdsa_aes_128_sha", + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, true }, + + { "security.ssl3.ecdhe_rsa_aes_256_sha", + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, true }, + { "security.ssl3.ecdhe_ecdsa_aes_256_sha", + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true }, + + { "security.ssl3.ecdhe_rsa_des_ede3_sha", + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, true }, // deprecated (3DES) + + { "security.ssl3.dhe_rsa_aes_128_sha", + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, true }, + { "security.ssl3.dhe_rsa_camellia_128_sha", + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, true }, + + { "security.ssl3.dhe_rsa_aes_256_sha", + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true }, + { "security.ssl3.dhe_rsa_camellia_256_sha", + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, true }, + + { "security.ssl3.dhe_rsa_des_ede3_sha", + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, true }, // deprecated (3DES) + + { "security.ssl3.dhe_dss_aes_128_sha", + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, true }, // deprecated (DSS) + { "security.ssl3.dhe_dss_aes_256_sha", + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, true }, // deprecated (DSS) + + { "security.ssl3.ecdhe_rsa_rc4_128_sha", + TLS_ECDHE_RSA_WITH_RC4_128_SHA, true }, // deprecated (RC4) + { "security.ssl3.ecdhe_ecdsa_rc4_128_sha", + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, true }, // deprecated (RC4) + + { "security.ssl3.rsa_aes_128_sha", + TLS_RSA_WITH_AES_128_CBC_SHA, true }, // deprecated (RSA key exchange) + { "security.ssl3.rsa_camellia_128_sha", + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, true }, // deprecated (RSA key exchange) + { "security.ssl3.rsa_aes_256_sha", + TLS_RSA_WITH_AES_256_CBC_SHA, true }, // deprecated (RSA key exchange) + { "security.ssl3.rsa_camellia_256_sha", + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, true }, // deprecated (RSA key exchange) + { "security.ssl3.rsa_des_ede3_sha", + SSL_RSA_WITH_3DES_EDE_CBC_SHA, true }, // deprecated (RSA key exchange, 3DES) + + { "security.ssl3.rsa_rc4_128_sha", + SSL_RSA_WITH_RC4_128_SHA, true }, // deprecated (RSA key exchange, RC4) + { "security.ssl3.rsa_rc4_128_md5", + SSL_RSA_WITH_RC4_128_MD5, true }, // deprecated (RSA key exchange, RC4, HMAC-MD5) + + // All the rest are disabled by default + + {"security.ssl3.rsa_fips_des_ede3_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA}, {"security.ssl3.dhe_dss_camellia_256_sha", TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA}, // 256-bit Camellia encryption with DSA, DHE, and a SHA1 MAC - {"security.ssl3.rsa_camellia_256_sha", TLS_RSA_WITH_CAMELLIA_256_CBC_SHA}, // 256-bit Camellia encryption with RSA and a SHA1 MAC - {"security.ssl3.dhe_rsa_aes_256_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA}, // 256-bit AES encryption with RSA, DHE, and a SHA1 MAC - {"security.ssl3.dhe_dss_aes_256_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA}, // 256-bit AES encryption with DSA, DHE, and a SHA1 MAC - {"security.ssl3.rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA}, // 256-bit AES encryption with RSA and a SHA1 MAC - /* TLS_DHE_DSS_WITH_RC4_128_SHA // 128-bit RC4 encryption with DSA, DHE, and a SHA1 MAC - If this cipher gets included at a later time, it should get added at this position */ - {"security.ssl3.ecdhe_ecdsa_aes_256_sha", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, // 256-bit AES encryption with ECDHE-ECDSA and a SHA1 MAC - {"security.ssl3.ecdhe_ecdsa_aes_128_sha", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, // 128-bit AES encryption with ECDHE-ECDSA and a SHA1 MAC - {"security.ssl3.ecdhe_ecdsa_des_ede3_sha", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with ECDHE-ECDSA and a SHA1 MAC - {"security.ssl3.ecdhe_ecdsa_rc4_128_sha", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA}, // 128-bit RC4 encryption with ECDHE-ECDSA and a SHA1 MAC - {"security.ssl3.ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, // 256-bit AES encryption with ECDHE-RSA and a SHA1 MAC - {"security.ssl3.ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, // 128-bit AES encryption with ECDHE-RSA and a SHA1 MAC - {"security.ssl3.ecdhe_rsa_des_ede3_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with ECDHE-RSA and a SHA1 MAC - {"security.ssl3.ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA}, // 128-bit RC4 encryption with ECDHE-RSA and a SHA1 MAC {"security.ssl3.ecdh_ecdsa_aes_256_sha", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA}, // 256-bit AES encryption with ECDH-ECDSA and a SHA1 MAC {"security.ssl3.ecdh_ecdsa_aes_128_sha", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA}, // 128-bit AES encryption with ECDH-ECDSA and a SHA1 MAC {"security.ssl3.ecdh_ecdsa_des_ede3_sha", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with ECDH-ECDSA and a SHA1 MAC @@ -861,17 +900,8 @@ static CipherPref CipherPrefs[] = { {"security.ssl3.ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA}, // 128-bit AES encryption with ECDH-RSA and a SHA1 MAC {"security.ssl3.ecdh_rsa_des_ede3_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with ECDH-RSA and a SHA1 MAC {"security.ssl3.ecdh_rsa_rc4_128_sha", TLS_ECDH_RSA_WITH_RC4_128_SHA}, // 128-bit RC4 encryption with ECDH-RSA and a SHA1 MAC - {"security.ssl3.dhe_rsa_camellia_128_sha", TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA}, // 128-bit Camellia encryption with RSA, DHE, and a SHA1 MAC {"security.ssl3.dhe_dss_camellia_128_sha", TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA}, // 128-bit Camellia encryption with DSA, DHE, and a SHA1 MAC - {"security.ssl3.rsa_camellia_128_sha", TLS_RSA_WITH_CAMELLIA_128_CBC_SHA}, // 128-bit Camellia encryption with RSA and a SHA1 MAC - {"security.ssl3.dhe_rsa_aes_128_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA}, // 128-bit AES encryption with RSA, DHE, and a SHA1 MAC - {"security.ssl3.dhe_dss_aes_128_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA}, // 128-bit AES encryption with DSA, DHE, and a SHA1 MAC - {"security.ssl3.rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA}, // 128-bit AES encryption with RSA and a SHA1 MAC - {"security.ssl3.dhe_rsa_des_ede3_sha", SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with RSA, DHE, and a SHA1 MAC - {"security.ssl3.dhe_dss_des_ede3_sha", SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA}, // 168-bit Triple DES with DSA, DHE, and a SHA1 MAC {"security.ssl3.rsa_seed_sha", TLS_RSA_WITH_SEED_CBC_SHA}, // SEED encryption with RSA and a SHA1 MAC - {"security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, // 128-bit AES-GCM encryption with ECDHE-ECDSA - {"security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, // 128-bit AES-GCM encryption with ECDHE-RSA {nullptr, 0} /* end marker */ }; @@ -968,9 +998,10 @@ CipherSuiteChangeObserver::Observe(nsISupports *aSubject, if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { NS_ConvertUTF16toUTF8 prefName(someData); /* Look through the cipher table and set according to pref setting */ - for (CipherPref* cp = CipherPrefs; cp->pref; ++cp) { + for (const CipherPref* cp = sCipherPrefs; cp->pref; ++cp) { if (prefName.Equals(cp->pref)) { - bool cipherEnabled = Preferences::GetBool(cp->pref, CIPHER_ENABLED_DEFAULT); + bool cipherEnabled = Preferences::GetBool(cp->pref, + cp->enabledByDefault); SSL_CipherPrefSetDefault(cp->id, cipherEnabled); SSL_ClearSessionCache(); break; @@ -2040,8 +2071,8 @@ nsresult InitializeCipherSuite() bool cipherEnabled; // Now only set SSL/TLS ciphers we knew about at compile time - for (CipherPref* cp = CipherPrefs; cp->pref; ++cp) { - cipherEnabled = Preferences::GetBool(cp->pref, CIPHER_ENABLED_DEFAULT); + for (const CipherPref* cp = sCipherPrefs; cp->pref; ++cp) { + bool cipherEnabled = Preferences::GetBool(cp->pref, cp->enabledByDefault); SSL_CipherPrefSetDefault(cp->id, cipherEnabled); } diff --git a/security/manager/ssl/tests/unit/head_psm.js b/security/manager/ssl/tests/unit/head_psm.js index 3b47d4e70265..93a09f0b713b 100644 --- a/security/manager/ssl/tests/unit/head_psm.js +++ b/security/manager/ssl/tests/unit/head_psm.js @@ -15,6 +15,22 @@ let { ctypes } = Cu.import("resource://gre/modules/ctypes.jsm"); let gIsWindows = ("@mozilla.org/windows-registry-key;1" in Cc); +const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE; + +// Sort in numerical order +const SEC_ERROR_REVOKED_CERTIFICATE = SEC_ERROR_BASE + 12; +const SEC_ERROR_BAD_DATABASE = SEC_ERROR_BASE + 18; +const SEC_ERROR_OCSP_MALFORMED_REQUEST = SEC_ERROR_BASE + 120; +const SEC_ERROR_OCSP_SERVER_ERROR = SEC_ERROR_BASE + 121; +const SEC_ERROR_OCSP_TRY_SERVER_LATER = SEC_ERROR_BASE + 122; +const SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = SEC_ERROR_BASE + 123; +const SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = SEC_ERROR_BASE + 124; +const SEC_ERROR_OCSP_UNKNOWN_CERT = SEC_ERROR_BASE + 126; +const SEC_ERROR_OCSP_MALFORMED_RESPONSE = SEC_ERROR_BASE + 129; +const SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE = SEC_ERROR_BASE + 130; +const SEC_ERROR_OCSP_OLD_RESPONSE = SEC_ERROR_BASE + 132; +const SEC_ERROR_OCSP_INVALID_SIGNING_CERT = SEC_ERROR_BASE + 144; + function readFile(file) { let fstream = Cc["@mozilla.org/network/file-input-stream;1"] .createInstance(Ci.nsIFileInputStream); @@ -30,10 +46,9 @@ function addCertFromFile(certdb, filename, trustString) { certdb.addCert(der, trustString, null); } -function getXPCOMStatusFromNSS(offset) { +function getXPCOMStatusFromNSS(statusNSS) { let nssErrorsService = Cc["@mozilla.org/nss_errors_service;1"] .getService(Ci.nsINSSErrorsService); - let statusNSS = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE + offset; return nssErrorsService.getXPCOMFromNSSError(statusNSS); } diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling.js b/security/manager/ssl/tests/unit/test_ocsp_stapling.js index f9a094637893..39490ec3d8af 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_stapling.js +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling.js @@ -42,13 +42,13 @@ function run_test() { add_ocsp_test("ocsp-stapling-good.example.com", Cr.NS_OK, true); - // SEC_ERROR_REVOKED_CERTIFICATE = SEC_ERROR_BASE + 12 - add_ocsp_test("ocsp-stapling-revoked.example.com", getXPCOMStatusFromNSS(12), true); + add_ocsp_test("ocsp-stapling-revoked.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE), true); // This stapled response is from a CA that is untrusted and did not issue // the server's certificate. - // SEC_ERROR_BAD_DATABASE = SEC_ERROR_BASE + 18 - add_ocsp_test("ocsp-stapling-good-other-ca.example.com", getXPCOMStatusFromNSS(18), true); + add_ocsp_test("ocsp-stapling-good-other-ca.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_BAD_DATABASE), true); // SEC_ERROR_BAD_DATABASE vs SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE depends on // whether the CA that signed the response is a trusted CA. @@ -61,28 +61,32 @@ function run_test() { run_next_test(); }); - // SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE = (SEC_ERROR_BASE + 130) - add_ocsp_test("ocsp-stapling-good-other-ca.example.com", getXPCOMStatusFromNSS(130), true); - // SEC_ERROR_OCSP_MALFORMED_REQUEST = (SEC_ERROR_BASE + 120) - add_ocsp_test("ocsp-stapling-malformed.example.com", getXPCOMStatusFromNSS(120), true); - // SEC_ERROR_OCSP_SERVER_ERROR = (SEC_ERROR_BASE + 121) - add_ocsp_test("ocsp-stapling-srverr.example.com", getXPCOMStatusFromNSS(121), true); - // SEC_ERROR_OCSP_TRY_SERVER_LATER = (SEC_ERROR_BASE + 122) - add_ocsp_test("ocsp-stapling-trylater.example.com", getXPCOMStatusFromNSS(122), true); - // SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = (SEC_ERROR_BASE + 123) - add_ocsp_test("ocsp-stapling-needssig.example.com", getXPCOMStatusFromNSS(123), true); - // SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = (SEC_ERROR_BASE + 124) - add_ocsp_test("ocsp-stapling-unauthorized.example.com", getXPCOMStatusFromNSS(124), true); - // SEC_ERROR_OCSP_UNKNOWN_CERT = (SEC_ERROR_BASE + 126) - add_ocsp_test("ocsp-stapling-unknown.example.com", getXPCOMStatusFromNSS(126), true); - add_ocsp_test("ocsp-stapling-good-other.example.com", getXPCOMStatusFromNSS(126), true); + add_ocsp_test("ocsp-stapling-good-other-ca.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE), + true); + add_ocsp_test("ocsp-stapling-malformed.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_REQUEST), true); + add_ocsp_test("ocsp-stapling-srverr.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_SERVER_ERROR), true); + add_ocsp_test("ocsp-stapling-trylater.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_TRY_SERVER_LATER), true); + add_ocsp_test("ocsp-stapling-needssig.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG), true); + add_ocsp_test("ocsp-stapling-unauthorized.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST), + true); + add_ocsp_test("ocsp-stapling-unknown.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), true); + add_ocsp_test("ocsp-stapling-good-other.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), true); // If the server doesn't send an OCSP response, we continue as normal. add_ocsp_test("ocsp-stapling-none.example.com", Cr.NS_OK, true); - // SEC_ERROR_OCSP_MALFORMED_RESPONSE = (SEC_ERROR_BASE + 129) - add_ocsp_test("ocsp-stapling-empty.example.com", getXPCOMStatusFromNSS(129), true); - // SEC_ERROR_OCSP_OLD_RESPONSE = (SEC_ERROR_BASE + 132) - add_ocsp_test("ocsp-stapling-expired.example.com", getXPCOMStatusFromNSS(132), true); - add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com", getXPCOMStatusFromNSS(132), true); + add_ocsp_test("ocsp-stapling-empty.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_RESPONSE), true); + add_ocsp_test("ocsp-stapling-expired.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE), true); + add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE), true); run_next_test(); } diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index ac5b19f2e5a5..6f8bf0a9038d 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_15_4_BETA1 +NSS_3_15_4_BETA2 diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 5182f75552c8..590d1bfaeee3 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,3 +10,4 @@ */ #error "Do not include this header file." + diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index bc4bcfa208bf..9fbc97292435 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -7043,7 +7043,7 @@ ssl3_CheckFalseStart(sslSocket *ss) PRBool ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss) { - PRBool result = PR_FALSE; + PRBool result; PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); @@ -7054,10 +7054,9 @@ ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss) case wait_change_cipher: result = !ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn); break; - case wait_finished: - break; default: - PR_NOT_REACHED("ssl3_WaitingForStartOfServerSecondRound"); + result = PR_FALSE; + break; } return result; @@ -9967,19 +9966,17 @@ ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error) PORT_Assert(!ss->firstHsDone); PORT_Assert(!ss->sec.isServer); PORT_Assert(!ss->ssl3.hs.isResuming); - PORT_Assert(ss->ssl3.hs.ws == wait_new_session_ticket || - ss->ssl3.hs.ws == wait_change_cipher || - ss->ssl3.hs.ws == wait_finished); + PORT_Assert(ss->ssl3.hs.ws != idle_handshake); - /* ssl3_SendClientSecondRound deferred the false start check because - * certificate authentication was pending, so we do it now if we still - * haven't received any of the server's second round yet. - */ if (ss->opt.enableFalseStart && !ss->firstHsDone && !ss->sec.isServer && !ss->ssl3.hs.isResuming && ssl3_WaitingForStartOfServerSecondRound(ss)) { + /* ssl3_SendClientSecondRound deferred the false start check because + * certificate authentication was pending, so we do it now if we still + * haven't received any of the server's second round yet. + */ rv = ssl3_CheckFalseStart(ss); } else { rv = SECSuccess; diff --git a/security/nss/tests/ocsp/ocsp.sh b/security/nss/tests/ocsp/ocsp.sh index 84323c9c8cc3..4e13e0555323 100644 --- a/security/nss/tests/ocsp/ocsp.sh +++ b/security/nss/tests/ocsp/ocsp.sh @@ -60,11 +60,11 @@ ocsp_stapling() ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5143 -d . < ${REQF} html_msg $? 0 "$TESTNAME" - TESTNAME="startssl revoked, supports OCSP stapling" - echo "$SCRIPTNAME: $TESTNAME" - echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5144 -d . < ${REQF}" - ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5144 -d . < ${REQF} - html_msg $? 3 "$TESTNAME" +# TESTNAME="startssl revoked, supports OCSP stapling" +# echo "$SCRIPTNAME: $TESTNAME" +# echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5144 -d . < ${REQF}" +# ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5144 -d . < ${REQF} +# html_msg $? 3 "$TESTNAME" TESTNAME="comodo trial test expired revoked, supports OCSP stapling" echo "$SCRIPTNAME: $TESTNAME" diff --git a/services/sync/Makefile.in b/services/sync/Makefile.in index 494c66de08c5..5cad09b580ea 100644 --- a/services/sync/Makefile.in +++ b/services/sync/Makefile.in @@ -10,7 +10,7 @@ weave_id := {340c2bbc-ce74-4362-90b5-7c26312808ef} SYNC_PP := modules/constants.js SYNC_PP_FLAGS := \ -Dweave_version=$(weave_version) \ - -Dweave_id=$(weave_id) + -Dweave_id="$(weave_id)" SYNC_PP_PATH = $(FINAL_TARGET)/modules/services-sync PP_TARGETS += SYNC_PP diff --git a/testing/mochitest/b2g-debug.json b/testing/mochitest/b2g-debug.json index 2a848013966d..5f033776abe3 100644 --- a/testing/mochitest/b2g-debug.json +++ b/testing/mochitest/b2g-debug.json @@ -254,6 +254,7 @@ "content/base/test/test_bug424359-2.html":"", "content/base/test/test_mixed_content_blocker_bug803225.html":"", "content/html/document/test/test_non-ascii-cookie.html":"", + "content/html/document/test/test_document.watch.html":"expects document.cookie setting to work", "docshell/test/navigation/test_bug13871.html":"", "docshell/test/navigation/test_bug270414.html":"", diff --git a/testing/mochitest/b2g-desktop.json b/testing/mochitest/b2g-desktop.json index f9a3bca24c6d..e35b43faa6de 100644 --- a/testing/mochitest/b2g-desktop.json +++ b/testing/mochitest/b2g-desktop.json @@ -253,6 +253,7 @@ "content/base/test/test_bug426308.html":"", "content/base/test/test_mixed_content_blocker_bug803225.html":"", "content/html/document/test/test_non-ascii-cookie.html":"", + "content/html/document/test/test_document.watch.html":"expects document.cookie setting to work", "docshell/test/navigation/test_bug13871.html":"", "docshell/test/navigation/test_bug270414.html":"", diff --git a/testing/mochitest/b2g.json b/testing/mochitest/b2g.json index 970c5617e48a..2dccceacf0b1 100644 --- a/testing/mochitest/b2g.json +++ b/testing/mochitest/b2g.json @@ -212,6 +212,7 @@ "content/base/test/csp/test_CSP_bug916446.html":"observer not working", "content/base/test/csp/test_CSP_bug909029.html":"observer not working", "content/base/test/csp/test_policyuri_regression_from_multipolicy.html":"observer not working", + "content/base/test/csp/test_nonce_source.html":"observer not working", "content/base/test/test_CrossSiteXHR_origin.html":"https not working, bug 907770", "content/base/test/test_plugin_freezing.html":"", @@ -258,6 +259,7 @@ "content/base/test/test_bug424359-2.html":"", "content/base/test/test_mixed_content_blocker_bug803225.html":"", "content/html/document/test/test_non-ascii-cookie.html":"", + "content/html/document/test/test_document.watch.html":"expects document.cookie setting to work", "docshell/test/navigation/test_bug13871.html":"", "docshell/test/navigation/test_bug270414.html":"", diff --git a/toolkit/components/osfile/modules/osfile_unix_back.jsm b/toolkit/components/osfile/modules/osfile_unix_back.jsm index 5acd4a9b2aa4..a3aedd3b63b2 100644 --- a/toolkit/components/osfile/modules/osfile_unix_back.jsm +++ b/toolkit/components/osfile/modules/osfile_unix_back.jsm @@ -92,6 +92,15 @@ Type.gid_t = Type.intn_t(Const.OSFILE_SIZEOF_GID_T).withName("gid_t"); + /** + * A file size (st_size in struct stat) + */ + if (OS.Constants.Sys.Name == "NetBSD") { + Type.stat_size_t = Type.off_t.withName("stat_size_t"); + } else { + Type.stat_size_t = Type.size_t.withName("stat_size_t"); + } + /** * Type |time_t| */ @@ -165,7 +174,7 @@ } stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_SIZE, - "st_size", Type.size_t.implementation); + "st_size", Type.stat_size_t.implementation); Type.stat = stat.getType(); } @@ -398,9 +407,15 @@ /*oflags*/Type.int, /*mode*/ Type.int); - declareLazyFFI(SysFile, "opendir", libc, "opendir", ctypes.default_abi, + if (OS.Constants.Sys.Name == "NetBSD") { + declareLazyFFI(SysFile, "opendir", libc, "__opendir30", ctypes.default_abi, + /*return*/ Type.null_or_DIR_ptr, + /*path*/ Type.path); + } else { + declareLazyFFI(SysFile, "opendir", libc, "opendir", ctypes.default_abi, /*return*/ Type.null_or_DIR_ptr, /*path*/ Type.path); + } declareLazyFFI(SysFile, "pread", libc, "pread", ctypes.default_abi, /*return*/ Type.negativeone_or_ssize_t, @@ -437,6 +452,10 @@ declareLazyFFI(SysFile, "readdir", libc, "readdir$INODE64", ctypes.default_abi, /*return*/Type.null_or_dirent_ptr, /*dir*/ Type.DIR.in_ptr); // For MacOS X + } else if (OS.Constants.Sys.Name == "NetBSD") { + declareLazyFFI(SysFile, "readdir", libc, "__readdir30", ctypes.default_abi, + /*return*/Type.null_or_dirent_ptr, + /*dir*/ Type.DIR.in_ptr); // Other Unices } else { declareLazyFFI(SysFile, "readdir", libc, "readdir", ctypes.default_abi, /*return*/Type.null_or_dirent_ptr, @@ -547,6 +566,23 @@ SysFile.fstat = function fstat(fd, buf) { return Stat.fxstat(ver, fd, buf); }; + } else if (OS.Constants.Sys.Name == "NetBSD") { + // NetBSD 5.0 and newer + declareLazyFFI(SysFile, "stat", libc, "__stat50", ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*path*/ Type.path, + /*buf*/ Type.stat.out_ptr + ); + declareLazyFFI(SysFile, "lstat", libc, "__lstat50", ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*path*/ Type.path, + /*buf*/ Type.stat.out_ptr + ); + declareLazyFFI(SysFile, "fstat", libc, "__fstat50", ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*fd*/ Type.fd, + /*buf*/ Type.stat.out_ptr + ); } else { // Mac OS X 32-bits, other Unix declareLazyFFI(SysFile, "stat", libc, "stat", ctypes.default_abi, @@ -589,16 +625,32 @@ return result; }; - declareLazyFFI(SysFile, "utimes", libc, "utimes", ctypes.default_abi, + if (OS.Constants.Sys.Name == "NetBSD") { + declareLazyFFI(SysFile, "utimes", libc, "__utimes50", ctypes.default_abi, /*return*/ Type.negativeone_or_nothing, /*path*/ Type.path, /*timeval[2]*/ Type.timevals.out_ptr ); - declareLazyFFI(SysFile, "futimes", libc, "futimes", ctypes.default_abi, + } else { + declareLazyFFI(SysFile, "utimes", libc, "utimes", ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*path*/ Type.path, + /*timeval[2]*/ Type.timevals.out_ptr + ); + } + if (OS.Constants.Sys.Name == "NetBSD") { + declareLazyFFI(SysFile, "futimes", libc, "__futimes50", ctypes.default_abi, /*return*/ Type.negativeone_or_nothing, /*fd*/ Type.fd, /*timeval[2]*/ Type.timevals.out_ptr ); + } else { + declareLazyFFI(SysFile, "futimes", libc, "futimes", ctypes.default_abi, + /*return*/ Type.negativeone_or_nothing, + /*fd*/ Type.fd, + /*timeval[2]*/ Type.timevals.out_ptr + ); + } }; exports.OS.Unix = { diff --git a/toolkit/components/osfile/modules/osfile_unix_front.jsm b/toolkit/components/osfile/modules/osfile_unix_front.jsm index acec273169ad..7bb87903909a 100644 --- a/toolkit/components/osfile/modules/osfile_unix_front.jsm +++ b/toolkit/components/osfile/modules/osfile_unix_front.jsm @@ -789,7 +789,7 @@ File.Info = function Info(stat) { let isDir = (stat.st_mode & Const.S_IFMT) == Const.S_IFDIR; let isSymLink = (stat.st_mode & Const.S_IFMT) == Const.S_IFLNK; - let size = Type.size_t.importFromC(stat.st_size); + let size = Type.stat_size_t.importFromC(stat.st_size); let lastAccessDate = new Date(stat.st_atime * 1000); let lastModificationDate = new Date(stat.st_mtime * 1000); diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in index ee4fc27fb188..cf85d77b4e1d 100644 --- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -127,8 +127,8 @@ OS_LIBS += -lrt EXTRA_DSO_LDOPTS += -Wl,-version-script,symverscript symverscript: symverscript.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - -DVERSION="$(LIBRARY_NAME)$(MOZILLA_SYMBOLVERSION)" $< > $@ + $(call py_action,preprocessor, \ + -DVERSION="$(LIBRARY_NAME)$(MOZILLA_SYMBOLVERSION)" $< -o $@) EXTRA_DEPS += symverscript endif @@ -136,7 +136,6 @@ endif STATIC_LIBS += \ xpcom_core \ - ucvutil_s \ chromium_s \ snappy_s \ $(NULL) diff --git a/toolkit/locales/l10n.mk b/toolkit/locales/l10n.mk index 9b38addd05c7..b5bb4c78fc82 100644 --- a/toolkit/locales/l10n.mk +++ b/toolkit/locales/l10n.mk @@ -158,8 +158,8 @@ langpack-%: XPI_NAME=locale-$* langpack-%: libs-% @echo "Making langpack $(LANGPACK_FILE)" $(NSINSTALL) -D $(DIST)/$(PKG_LANGPACK_PATH) - $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \ - -I$(TK_DEFINES) -I$(APP_DEFINES) $(srcdir)/generic/install.rdf > $(DIST)/xpi-stage/$(XPI_NAME)/install.rdf + $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) \ + -I$(TK_DEFINES) -I$(APP_DEFINES) $(srcdir)/generic/install.rdf -o $(DIST)/xpi-stage/$(XPI_NAME)/install.rdf) cd $(DIST)/xpi-stage/locale-$(AB_CD) && \ $(ZIP) -r9D $(LANGPACK_FILE) install.rdf $(PKG_ZIP_DIRS) chrome.manifest diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk index 262882e7ef85..16bc3a7de7fc 100644 --- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -178,12 +178,11 @@ RPM_INCIDENTALS=$(topsrcdir)/toolkit/mozapps/installer/linux/rpm RPM_CMD = \ echo Creating RPM && \ - mkdir -p $(RPMBUILD_SOURCEDIR) && \ - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ + $(PYTHON) -m mozbuild.action.preprocessor \ -DMOZ_APP_NAME=$(MOZ_APP_NAME) \ -DMOZ_APP_DISPLAYNAME="$(MOZ_APP_DISPLAYNAME)" \ - < $(RPM_INCIDENTALS)/mozilla.desktop \ - > $(RPMBUILD_SOURCEDIR)/$(MOZ_APP_NAME).desktop && \ + $(RPM_INCIDENTALS)/mozilla.desktop \ + -o $(RPMBUILD_SOURCEDIR)/$(MOZ_APP_NAME).desktop && \ rm -rf $(_ABS_DIST)/$(TARGET_CPU) && \ $(RPMBUILD) -bb \ $(SPEC_FILE) \ diff --git a/webapprt/Makefile.in b/webapprt/Makefile.in index 388f8d7d4abc..0f5710f92d0e 100644 --- a/webapprt/Makefile.in +++ b/webapprt/Makefile.in @@ -28,7 +28,7 @@ DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) \ $(NULL) webapprt.ini: application.ini.in $(DEPTH)/config/buildid $(topsrcdir)/config/milestone.txt - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@ + $(call py_action,preprocessor,$(DEFINES) $< -o $@) libs:: webapprt.ini $(INSTALL) webapprt.ini $(FINAL_TARGET) diff --git a/webapprt/win/Makefile.in b/webapprt/win/Makefile.in index d86b5f110b4e..365ea0afd247 100644 --- a/webapprt/win/Makefile.in +++ b/webapprt/win/Makefile.in @@ -68,9 +68,9 @@ endif libs:: $(RM) -r $(CONFIG_DIR) $(MKDIR) $(CONFIG_DIR) - $(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution \ + $(call py_action,preprocessor,-Fsubstitution \ $(DEFINES) $(ACDEFINES) \ - $(srcdir)/webapp-uninstaller.nsi.in > $(CONFIG_DIR)/webapp-uninstaller.nsi + $(srcdir)/webapp-uninstaller.nsi.in -o $(CONFIG_DIR)/webapp-uninstaller.nsi) $(PYTHON) \ $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \ --create-nlf-file $(topsrcdir) $(AB_CD) $(CONFIG_DIR) diff --git a/widget/android/AndroidJNI.cpp b/widget/android/AndroidJNI.cpp index 8ff59bd9cbb7..81b27fcdc4a8 100644 --- a/widget/android/AndroidJNI.cpp +++ b/widget/android/AndroidJNI.cpp @@ -877,7 +877,7 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, const MultiTouchInput& input = wrapper->MakeMultiTouchInput(nsWindow::TopWindow()); delete wrapper; if (input.mType >= 0) { - controller->ReceiveInputEvent(input); + controller->ReceiveInputEvent(input, nullptr); } } } diff --git a/widget/windows/winrt/APZController.cpp b/widget/windows/winrt/APZController.cpp index 60a6f0eb2493..0795e4baa826 100644 --- a/widget/windows/winrt/APZController.cpp +++ b/widget/windows/winrt/APZController.cpp @@ -17,6 +17,7 @@ #include "nsIDOMWindowUtils.h" #include "nsIInterfaceRequestorUtils.h" #include "nsLayoutUtils.h" +#include "mozilla/TouchEvents.h" //#define DEBUG_CONTROLLER 1 @@ -163,6 +164,62 @@ APZController::SetWidgetListener(nsIWidgetListener* aWidgetListener) mWidgetListener = aWidgetListener; } +void +APZController::ContentReceivedTouch(const ScrollableLayerGuid& aGuid, bool aPreventDefault) +{ + if (!sAPZC) { + return; + } + sAPZC->ContentReceivedTouch(aGuid, aPreventDefault); +} + +bool +APZController::HitTestAPZC(ScreenIntPoint& aPoint) +{ + if (!sAPZC) { + return false; + } + return sAPZC->HitTestAPZC(aPoint); +} + +void +APZController::TransformCoordinateToGecko(const ScreenIntPoint& aPoint, + LayoutDeviceIntPoint* aRefPointOut) +{ + if (!sAPZC || !aRefPointOut) { + return; + } + sAPZC->TransformCoordinateToGecko(aPoint, aRefPointOut); +} + +nsEventStatus +APZController::ReceiveInputEvent(WidgetInputEvent* aEvent, + ScrollableLayerGuid* aOutTargetGuid) +{ + MOZ_ASSERT(aEvent); + + if (!sAPZC) { + return nsEventStatus_eIgnore; + } + return sAPZC->ReceiveInputEvent(*aEvent->AsInputEvent(), aOutTargetGuid); +} + +nsEventStatus +APZController::ReceiveInputEvent(WidgetInputEvent* aInEvent, + ScrollableLayerGuid* aOutTargetGuid, + WidgetInputEvent* aOutEvent) +{ + MOZ_ASSERT(aInEvent); + MOZ_ASSERT(aOutEvent); + + if (!sAPZC) { + return nsEventStatus_eIgnore; + } + return sAPZC->ReceiveInputEvent(*aInEvent->AsInputEvent(), + aOutTargetGuid, + aOutEvent); +} + // APZC sends us this request when we need to update the display port on // the scrollable frame the apzc is managing. void diff --git a/widget/windows/winrt/APZController.h b/widget/windows/winrt/APZController.h index fbfd733710b6..f5ca5eade7b5 100644 --- a/widget/windows/winrt/APZController.h +++ b/widget/windows/winrt/APZController.h @@ -8,6 +8,7 @@ #include "mozilla/layers/GeckoContentController.h" #include "mozilla/layers/APZCTreeManager.h" +#include "mozilla/EventForwards.h" #include "FrameMetrics.h" #include "Units.h" @@ -21,6 +22,7 @@ class APZController : public mozilla::layers::GeckoContentController { typedef mozilla::layers::FrameMetrics FrameMetrics; + typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid; public: // GeckoContentController interface @@ -36,7 +38,18 @@ public: void SetWidgetListener(nsIWidgetListener* aWidgetListener); void UpdateScrollOffset(const mozilla::layers::ScrollableLayerGuid& aScrollLayerId, CSSIntPoint& aScrollOffset); + bool HitTestAPZC(mozilla::ScreenIntPoint& aPoint); + void TransformCoordinateToGecko(const mozilla::ScreenIntPoint& aPoint, + LayoutDeviceIntPoint* aRefPointOut); + void ContentReceivedTouch(const ScrollableLayerGuid& aGuid, bool aPreventDefault); + nsEventStatus ReceiveInputEvent(mozilla::WidgetInputEvent* aEvent, + ScrollableLayerGuid* aOutTargetGuid); + nsEventStatus ReceiveInputEvent(mozilla::WidgetInputEvent* aInEvent, + ScrollableLayerGuid* aOutTargetGuid, + mozilla::WidgetInputEvent* aOutEvent); + public: + // todo: make this a member variable as prep for multiple views static nsRefPtr sAPZC; private: diff --git a/widget/windows/winrt/MetroInput.cpp b/widget/windows/winrt/MetroInput.cpp index 2164fb3846cc..ac180f9f34f6 100644 --- a/widget/windows/winrt/MetroInput.cpp +++ b/widget/windows/winrt/MetroInput.cpp @@ -668,19 +668,35 @@ MetroInput::TransformRefPoint(const Foundation::Point& aPosition, LayoutDeviceIn { // If this event is destined for content we need to transform our ref point through // the apz so that zoom can be accounted for. - LayoutDeviceIntPoint pt = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(aPosition)); - aRefPointOut = pt; + aRefPointOut = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(aPosition)); + ScreenIntPoint spt; + spt.x = aRefPointOut.x; + spt.y = aRefPointOut.y; // This is currently a general contained rect hit test, it may produce a false positive for // overlay chrome elements. - bool apzIntersect = mWidget->HitTestAPZC(mozilla::ScreenPoint(pt.x, pt.y)); - if (apzIntersect && HitTestChrome(pt)) { + bool apzIntersect = mWidget->ApzHitTest(spt); + if (apzIntersect && HitTestChrome(aRefPointOut)) { return; } - WidgetMouseEvent event(true, NS_MOUSE_MOVE, mWidget.Get(), - WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); - event.refPoint = aRefPointOut; - mWidget->ApzReceiveInputEvent(&event); - aRefPointOut = event.refPoint; + mWidget->ApzTransformGeckoCoordinate(spt, &aRefPointOut); +} + +void +MetroInput::TransformTouchEvent(WidgetTouchEvent* aEvent) +{ + nsTArray< nsRefPtr >& touches = aEvent->touches; + for (uint32_t i = 0; i < touches.Length(); ++i) { + dom::Touch* touch = touches[i]; + if (touch) { + LayoutDeviceIntPoint lpt; + ScreenIntPoint spt; + spt.x = touch->mRefPoint.x; + spt.y = touch->mRefPoint.y; + mWidget->ApzTransformGeckoCoordinate(spt, &lpt); + touch->mRefPoint.x = lpt.x; + touch->mRefPoint.y = lpt.y; + } + } } void @@ -1115,7 +1131,7 @@ MetroInput::DeliverNextQueuedTouchEvent() if (mCancelable && event->message == NS_TOUCH_START) { nsRefPtr touch = event->touches[0]; LayoutDeviceIntPoint pt = LayoutDeviceIntPoint::FromUntyped(touch->mRefPoint); - bool apzIntersect = mWidget->HitTestAPZC(mozilla::ScreenPoint(pt.x, pt.y)); + bool apzIntersect = mWidget->ApzHitTest(mozilla::ScreenIntPoint(pt.x, pt.y)); mChromeHitTestCacheForTouch = (apzIntersect && HitTestChrome(pt)); } @@ -1133,11 +1149,19 @@ MetroInput::DeliverNextQueuedTouchEvent() if (mCancelable) { WidgetTouchEvent transformedEvent(*event); DUMP_TOUCH_IDS("APZC(1)", event); - mWidget->ApzReceiveInputEvent(event, &transformedEvent); + mWidget->ApzReceiveInputEvent(event, &mTargetAPZCGuid, &transformedEvent); DUMP_TOUCH_IDS("DOM(2)", event); mWidget->DispatchEvent(mChromeHitTestCacheForTouch ? event : &transformedEvent, status); if (event->message == NS_TOUCH_START) { mContentConsumingTouch = (nsEventStatus_eConsumeNoDefault == status); + // If we know content wants touch here, we can bail early on mCancelable + // processing. This insures the apz gets an update when the user touches + // the screen, but doesn't move soon after. + if (mContentConsumingTouch) { + mCancelable = false; + mWidget->ApzContentConsumingTouch(mTargetAPZCGuid); + DispatchTouchCancel(event); + } // Disable gesture based events (taps, swipes, rotation) if // preventDefault is called on touchstart. mRecognizerWantsEvents = !(nsEventStatus_eConsumeNoDefault == status); @@ -1150,10 +1174,10 @@ MetroInput::DeliverNextQueuedTouchEvent() // Let the apz know if content wants to consume touch events, or cancel // the touch block for content. if (mContentConsumingTouch) { - mWidget->ApzContentConsumingTouch(); + mWidget->ApzContentConsumingTouch(mTargetAPZCGuid); DispatchTouchCancel(event); } else { - mWidget->ApzContentIgnoringTouch(); + mWidget->ApzContentIgnoringTouch(mTargetAPZCGuid); } } // If content is consuming touch don't generate any gesture based @@ -1164,11 +1188,14 @@ MetroInput::DeliverNextQueuedTouchEvent() return; } - // Forward event data to apz. Even if content is consuming input, we still - // need APZC to transform the coordinates. It won't actually react to the - // event if ContentReceivedTouch was called previously. - DUMP_TOUCH_IDS("APZC(2)", event); - status = mWidget->ApzReceiveInputEvent(event); + // If content is consuming touch, we need to transform event coords + // through the apzc before sending. Otherwise send the event to apzc. + if (mContentConsumingTouch) { + TransformTouchEvent(event); + } else { + DUMP_TOUCH_IDS("APZC(2)", event); + status = mWidget->ApzReceiveInputEvent(event, nullptr); + } // If content called preventDefault on touchstart or first touchmove send // the event to content only. @@ -1216,7 +1243,7 @@ MetroInput::DispatchTouchCancel(WidgetTouchEvent* aEvent) } if (mContentConsumingTouch) { DUMP_TOUCH_IDS("APZC(3)", &touchEvent); - mWidget->ApzReceiveInputEvent(&touchEvent); + mWidget->ApzReceiveInputEvent(&touchEvent, nullptr); } else { DUMP_TOUCH_IDS("DOM(5)", &touchEvent); mWidget->DispatchEvent(&touchEvent, sThrowawayStatus); diff --git a/widget/windows/winrt/MetroInput.h b/widget/windows/winrt/MetroInput.h index e7383ba47a43..137fe957fafb 100644 --- a/widget/windows/winrt/MetroInput.h +++ b/widget/windows/winrt/MetroInput.h @@ -12,6 +12,7 @@ #include "mozwrlbase.h" #include "nsDeque.h" #include "mozilla/EventForwards.h" +#include "mozilla/layers/APZCTreeManager.h" // System headers (alphabetical) #include // EventRegistrationToken @@ -100,6 +101,8 @@ private: typedef ABI::Windows::UI::Input::ITappedEventArgs ITappedEventArgs; typedef ABI::Windows::UI::Input::ManipulationDelta ManipulationDelta; + typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid; + public: MetroInput(MetroWidget* aWidget, ICoreWindow* aWindow); @@ -168,6 +171,7 @@ private: // Event processing helpers. See function definitions for more info. void TransformRefPoint(const Point& aPosition, LayoutDeviceIntPoint& aRefPointOut); + void TransformTouchEvent(WidgetTouchEvent* aEvent); void OnPointerNonTouch(IPointerPoint* aPoint); void AddPointerMoveDataToRecognizer(IPointerEventArgs* aArgs); void InitGeckoMouseEventFromPointerPoint(WidgetMouseEvent* aEvent, @@ -277,6 +281,7 @@ private: void DispatchTouchCancel(WidgetTouchEvent* aEvent); nsDeque mInputEventQueue; + mozilla::layers::ScrollableLayerGuid mTargetAPZCGuid; static nsEventStatus sThrowawayStatus; }; diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index ba210ff39ad4..8ae0726156ae 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -973,57 +973,70 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa } void -MetroWidget::ApzContentConsumingTouch() +MetroWidget::ApzContentConsumingTouch(const ScrollableLayerGuid& aGuid) { LogFunction(); - if (!APZController::sAPZC) { + if (!mController) { return; } - APZController::sAPZC->ContentReceivedTouch(mRootLayerTreeId, true); + mController->ContentReceivedTouch(aGuid, true); } void -MetroWidget::ApzContentIgnoringTouch() +MetroWidget::ApzContentIgnoringTouch(const ScrollableLayerGuid& aGuid) { LogFunction(); - if (!APZController::sAPZC) { + if (!mController) { return; } - APZController::sAPZC->ContentReceivedTouch(mRootLayerTreeId, false); + mController->ContentReceivedTouch(aGuid, false); } bool -MetroWidget::HitTestAPZC(ScreenPoint& pt) +MetroWidget::ApzHitTest(ScreenIntPoint& pt) { - if (!APZController::sAPZC) { + if (!mController) { return false; } - return APZController::sAPZC->HitTestAPZC(pt); + return mController->HitTestAPZC(pt); +} + +void +MetroWidget::ApzTransformGeckoCoordinate(const ScreenIntPoint& aPoint, + LayoutDeviceIntPoint* aRefPointOut) +{ + if (!mController) { + return; + } + mController->TransformCoordinateToGecko(aPoint, aRefPointOut); } nsEventStatus -MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aEvent) +MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aEvent, + ScrollableLayerGuid* aOutTargetGuid) { MOZ_ASSERT(aEvent); - if (!APZController::sAPZC) { + if (!mController) { return nsEventStatus_eIgnore; } - return APZController::sAPZC->ReceiveInputEvent(*aEvent->AsInputEvent()); + return mController->ReceiveInputEvent(aEvent, aOutTargetGuid); } nsEventStatus MetroWidget::ApzReceiveInputEvent(WidgetInputEvent* aInEvent, + ScrollableLayerGuid* aOutTargetGuid, WidgetInputEvent* aOutEvent) { MOZ_ASSERT(aInEvent); MOZ_ASSERT(aOutEvent); - if (!APZController::sAPZC) { + if (!mController) { return nsEventStatus_eIgnore; } - return APZController::sAPZC->ReceiveInputEvent(*aInEvent->AsInputEvent(), - aOutEvent); + return mController->ReceiveInputEvent(aInEvent, + aOutTargetGuid, + aOutEvent); } LayerManager* diff --git a/widget/windows/winrt/MetroWidget.h b/widget/windows/winrt/MetroWidget.h index 15b2da9121a7..43d161ce3d1e 100644 --- a/widget/windows/winrt/MetroWidget.h +++ b/widget/windows/winrt/MetroWidget.h @@ -56,6 +56,7 @@ class MetroWidget : public nsWindowBase, typedef ABI::Windows::UI::Core::ICharacterReceivedEventArgs ICharacterReceivedEventArgs; typedef mozilla::widget::winrt::FrameworkView FrameworkView; typedef mozilla::widget::winrt::APZController APZController; + typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid; static LRESULT CALLBACK StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParan, LPARAM aLParam); @@ -198,15 +199,23 @@ public: virtual void SetTransparencyMode(nsTransparencyMode aMode); virtual nsTransparencyMode GetTransparencyMode(); - // APZ related apis - void ApzContentConsumingTouch(); - void ApzContentIgnoringTouch(); - nsEventStatus ApzReceiveInputEvent(mozilla::WidgetInputEvent* aEvent); + // apzc controller related api + + // Hit test a point to see if an apzc would consume input there + bool ApzHitTest(mozilla::ScreenIntPoint& pt); + // Transforms a coord so that it properly targets gecko content based + // on apzc transforms currently applied. + void ApzTransformGeckoCoordinate(const mozilla::ScreenIntPoint& pt, + mozilla::LayoutDeviceIntPoint* aRefPointOut); + // send ContentRecievedTouch calls to the apz with appropriate preventDefault params + void ApzContentConsumingTouch(const ScrollableLayerGuid& aGuid); + void ApzContentIgnoringTouch(const ScrollableLayerGuid& aGuid); + // Input handling + nsEventStatus ApzReceiveInputEvent(mozilla::WidgetInputEvent* aEvent, + ScrollableLayerGuid* aOutTargetGuid); nsEventStatus ApzReceiveInputEvent(mozilla::WidgetInputEvent* aInEvent, + ScrollableLayerGuid* aOutTargetGuid, mozilla::WidgetInputEvent* aOutEvent); - bool HitTestAPZC(mozilla::ScreenPoint& pt); - nsresult RequestContentScroll(); - void RequestContentRepaintImplMainThread(); protected: friend class FrameworkView; diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index da0bd54e13cc..16073d487bc9 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -101,6 +101,7 @@ /* This must occur *after* base/process_util.h to avoid typedefs conflicts. */ #include "mozilla/MemoryReporting.h" #include "mozilla/Util.h" +#include "mozilla/LinkedList.h" #include "mozilla/CycleCollectedJSRuntime.h" #include "nsCycleCollectionParticipant.h" @@ -1111,7 +1112,7 @@ GraphWalker::DoWalk(nsDeque &aQueue) } } -struct CCGraphDescriber +struct CCGraphDescriber : public LinkedListElement { CCGraphDescriber() : mAddress("0x"), mToAddress("0x"), mCnt(0), mType(eUnknown) {} @@ -1139,12 +1140,12 @@ class nsCycleCollectorLogger MOZ_FINAL : public nsICycleCollectorListener public: nsCycleCollectorLogger() : mStream(nullptr), mWantAllTraces(false), - mDisableLog(false), mWantAfterProcessing(false), - mNextIndex(0) + mDisableLog(false), mWantAfterProcessing(false) { } ~nsCycleCollectorLogger() { + ClearDescribers(); if (mStream) { MozillaUnRegisterDebugFILE(mStream); fclose(mStream); @@ -1209,8 +1210,7 @@ public: NS_IMETHOD Begin() { mCurrentAddress.AssignLiteral("0x"); - mDescribers.Clear(); - mNextIndex = 0; + ClearDescribers(); if (mDisableLog) { return NS_OK; } @@ -1278,7 +1278,8 @@ public: aObjectDescription); } if (mWantAfterProcessing) { - CCGraphDescriber* d = mDescribers.AppendElement(); + CCGraphDescriber* d = new CCGraphDescriber(); + mDescribers.insertBack(d); mCurrentAddress.AssignLiteral("0x"); mCurrentAddress.AppendInt(aAddress, 16); d->mType = CCGraphDescriber::eRefCountedObject; @@ -1296,7 +1297,8 @@ public: aMarked ? ".marked" : "", aObjectDescription); } if (mWantAfterProcessing) { - CCGraphDescriber* d = mDescribers.AppendElement(); + CCGraphDescriber* d = new CCGraphDescriber(); + mDescribers.insertBack(d); mCurrentAddress.AssignLiteral("0x"); mCurrentAddress.AppendInt(aAddress, 16); d->mType = aMarked ? CCGraphDescriber::eGCMarkedObject : @@ -1312,7 +1314,8 @@ public: fprintf(mStream, "> %p %s\n", (void*)aToAddress, aEdgeName); } if (mWantAfterProcessing) { - CCGraphDescriber* d = mDescribers.AppendElement(); + CCGraphDescriber* d = new CCGraphDescriber(); + mDescribers.insertBack(d); d->mType = CCGraphDescriber::eEdge; d->mAddress = mCurrentAddress; d->mToAddress.AppendInt(aToAddress, 16); @@ -1343,7 +1346,8 @@ public: fprintf(mStream, "%p [known=%u]\n", (void*)aAddress, aKnownEdges); } if (mWantAfterProcessing) { - CCGraphDescriber* d = mDescribers.AppendElement(); + CCGraphDescriber* d = new CCGraphDescriber(); + mDescribers.insertBack(d); d->mType = CCGraphDescriber::eRoot; d->mAddress.AppendInt(aAddress, 16); d->mCnt = aKnownEdges; @@ -1356,7 +1360,8 @@ public: fprintf(mStream, "%p [garbage]\n", (void*)aAddress); } if (mWantAfterProcessing) { - CCGraphDescriber* d = mDescribers.AppendElement(); + CCGraphDescriber* d = new CCGraphDescriber(); + mDescribers.insertBack(d); d->mType = CCGraphDescriber::eGarbage; d->mAddress.AppendInt(aAddress, 16); } @@ -1403,42 +1408,41 @@ public: bool* aCanContinue) { NS_ENSURE_STATE(aHandler && mWantAfterProcessing); - if (mNextIndex < mDescribers.Length()) { - CCGraphDescriber& d = mDescribers[mNextIndex++]; - switch (d.mType) { + CCGraphDescriber* d = mDescribers.popFirst(); + if (d) { + switch (d->mType) { case CCGraphDescriber::eRefCountedObject: - aHandler->NoteRefCountedObject(d.mAddress, - d.mCnt, - d.mName); + aHandler->NoteRefCountedObject(d->mAddress, + d->mCnt, + d->mName); break; case CCGraphDescriber::eGCedObject: case CCGraphDescriber::eGCMarkedObject: - aHandler->NoteGCedObject(d.mAddress, - d.mType == + aHandler->NoteGCedObject(d->mAddress, + d->mType == CCGraphDescriber::eGCMarkedObject, - d.mName); + d->mName); break; case CCGraphDescriber::eEdge: - aHandler->NoteEdge(d.mAddress, - d.mToAddress, - d.mName); + aHandler->NoteEdge(d->mAddress, + d->mToAddress, + d->mName); break; case CCGraphDescriber::eRoot: - aHandler->DescribeRoot(d.mAddress, - d.mCnt); + aHandler->DescribeRoot(d->mAddress, + d->mCnt); break; case CCGraphDescriber::eGarbage: - aHandler->DescribeGarbage(d.mAddress); + aHandler->DescribeGarbage(d->mAddress); break; case CCGraphDescriber::eUnknown: NS_NOTREACHED("CCGraphDescriber::eUnknown"); break; } + delete d; } - if (!(*aCanContinue = mNextIndex < mDescribers.Length())) { + if (!(*aCanContinue = !mDescribers.isEmpty())) { mCurrentAddress.AssignLiteral("0x"); - mDescribers.Clear(); - mNextIndex = 0; } return NS_OK; } @@ -1477,6 +1481,14 @@ private: return dont_AddRef(logFile); } + void ClearDescribers() + { + CCGraphDescriber* d; + while((d = mDescribers.popFirst())) { + delete d; + } + } + FILE *mStream; nsCOMPtr mOutFile; bool mWantAllTraces; @@ -1484,8 +1496,7 @@ private: bool mWantAfterProcessing; nsString mFilenameIdentifier; nsCString mCurrentAddress; - nsTArray mDescribers; - uint32_t mNextIndex; + mozilla::LinkedList mDescribers; }; NS_IMPL_ISUPPORTS1(nsCycleCollectorLogger, nsICycleCollectorListener) diff --git a/xpcom/build/PoisonIOInterposerMac.cpp b/xpcom/build/PoisonIOInterposerMac.cpp index 0cb030c7c694..094decc0c129 100644 --- a/xpcom/build/PoisonIOInterposerMac.cpp +++ b/xpcom/build/PoisonIOInterposerMac.cpp @@ -56,8 +56,7 @@ class MacIOAutoObservation : public IOInterposeObserver::Observation public: MacIOAutoObservation(IOInterposeObserver::Operation aOp, const char* aReference, int aFd) - : mFd(aFd), - mShouldObserve(sIsEnabled && IOInterposer::IsObservedOperation(aOp) && + : mShouldObserve(sIsEnabled && IOInterposer::IsObservedOperation(aOp) && !IsDebugFile(aFd)) { if (mShouldObserve) { @@ -70,8 +69,7 @@ public: MacIOAutoObservation(IOInterposeObserver::Operation aOp, const char* aReference, int aFd, const void *aBuf, size_t aCount) - : mFd(aFd), - mShouldObserve(sIsEnabled && IOInterposer::IsObservedOperation(aOp) && + : mShouldObserve(sIsEnabled && IOInterposer::IsObservedOperation(aOp) && !IsDebugFile(aFd)) { if (mShouldObserve) { @@ -95,7 +93,6 @@ public: } private: - int mFd; bool mShouldObserve; }; @@ -337,4 +334,4 @@ void ClearPoisonIOInterposer() { sIsEnabled = false; } -} // namespace mozilla \ No newline at end of file +} // namespace mozilla diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 1035afbaceac..e33066fa0dfa 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -8,6 +8,7 @@ #include "mozilla/Attributes.h" #include "mozilla/HashFunctions.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/DebugOnly.h" #include "nsAtomTable.h" #include "nsStaticAtom.h" @@ -54,11 +55,11 @@ static bool gStaticAtomTableSealed = false; class AtomImpl : public nsIAtom { public: - AtomImpl(const nsAString& aString, PLDHashNumber aKeyHash); + AtomImpl(const nsAString& aString, uint32_t aHash); // This is currently only used during startup when creating a permanent atom // from NS_RegisterStaticAtoms - AtomImpl(nsStringBuffer* aData, uint32_t aLength, PLDHashNumber aKeyHash); + AtomImpl(nsStringBuffer* aData, uint32_t aLength, uint32_t aHash); protected: // This is only intended to be used when a normal atom is turned into a @@ -135,43 +136,63 @@ struct AtomTableEntry : public PLDHashEntryHdr { struct AtomTableKey { - AtomTableKey(const PRUnichar* aUTF16String, uint32_t aLength) + AtomTableKey(const PRUnichar* aUTF16String, uint32_t aLength, + /*inout*/ uint32_t& aHash) : mUTF16String(aUTF16String), mUTF8String(nullptr), mLength(aLength) { + if (aHash) { + MOZ_ASSERT(aHash == HashString(mUTF16String, mLength)); + mHash = aHash; + } else { + UpdateHashKey(); + aHash = mHash; + } } - AtomTableKey(const char* aUTF8String, uint32_t aLength) + AtomTableKey(const char* aUTF8String, uint32_t aLength, + /*inout*/ uint32_t& aHash) : mUTF16String(nullptr), mUTF8String(aUTF8String), mLength(aLength) { + if (aHash) { + mozilla::DebugOnly err; + MOZ_ASSERT(aHash == HashUTF8AsUTF16(mUTF8String, mLength, &err)); + mHash = aHash; + } else { + UpdateHashKey(); + aHash = mHash; + } } const PRUnichar* mUTF16String; const char* mUTF8String; uint32_t mLength; + uint32_t mHash; + + void UpdateHashKey() + { + if (mUTF8String) { + bool err; + mHash = HashUTF8AsUTF16(mUTF8String, mLength, &err); + if (err) { + mUTF8String = nullptr; + mLength = 0; + mHash = 0; + } + } else { + mHash = HashString(mUTF16String, mLength); + } + } }; static PLDHashNumber AtomTableGetHash(PLDHashTable *table, const void *key) { const AtomTableKey *k = static_cast(key); - - if (k->mUTF8String) { - bool err; - uint32_t hash = HashUTF8AsUTF16(k->mUTF8String, k->mLength, &err); - if (err) { - AtomTableKey* mutableKey = const_cast(k); - mutableKey->mUTF8String = nullptr; - mutableKey->mLength = 0; - hash = 0; - } - return hash; - } - - return HashString(k->mUTF16String, k->mLength); + return k->mHash; } static bool @@ -292,7 +313,7 @@ NS_PurgeAtomTable() } } -AtomImpl::AtomImpl(const nsAString& aString, PLDHashNumber aKeyHash) +AtomImpl::AtomImpl(const nsAString& aString, uint32_t aHash) { mLength = aString.Length(); nsRefPtr buf = nsStringBuffer::FromString(aString); @@ -305,9 +326,8 @@ AtomImpl::AtomImpl(const nsAString& aString, PLDHashNumber aKeyHash) mString[mLength] = PRUnichar(0); } - // The low bit of aKeyHash is generally useless, so shift it out - MOZ_ASSERT(sizeof(mHash) == sizeof(PLDHashNumber)); - mHash = aKeyHash >> 1; + mHash = aHash; + MOZ_ASSERT(mHash == HashString(mString, mLength)); NS_ASSERTION(mString[mLength] == PRUnichar(0), "null terminated"); NS_ASSERTION(buf && buf->StorageSize() >= (mLength+1) * sizeof(PRUnichar), @@ -319,7 +339,7 @@ AtomImpl::AtomImpl(const nsAString& aString, PLDHashNumber aKeyHash) } AtomImpl::AtomImpl(nsStringBuffer* aStringBuffer, uint32_t aLength, - PLDHashNumber aKeyHash) + uint32_t aHash) { mLength = aLength; mString = static_cast(aStringBuffer->Data()); @@ -327,9 +347,8 @@ AtomImpl::AtomImpl(nsStringBuffer* aStringBuffer, uint32_t aLength, // the static atom buffers have an initial refcount of 2. aStringBuffer->AddRef(); - // The low bit of aKeyHash is generally useless, so shift it out - MOZ_ASSERT(sizeof(mHash) == sizeof(PLDHashNumber)); - mHash = aKeyHash >> 1; + mHash = aHash; + MOZ_ASSERT(mHash == HashString(mString, mLength)); NS_ASSERTION(mString[mLength] == PRUnichar(0), "null terminated"); NS_ASSERTION(aStringBuffer && @@ -344,7 +363,7 @@ AtomImpl::~AtomImpl() // don't want to remove them twice. See comment above in // |AtomTableClearEntry|. if (!IsPermanentInDestructor()) { - AtomTableKey key(mString, mLength); + AtomTableKey key(mString, mLength, mHash); PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_REMOVE); if (gAtomTable.entryCount == 0) { PL_DHashTableFinish(&gAtomTable); @@ -493,11 +512,11 @@ EnsureTableExists() } static inline AtomTableEntry* -GetAtomHashEntry(const char* aString, uint32_t aLength) +GetAtomHashEntry(const char* aString, uint32_t aLength, uint32_t& aHash) { MOZ_ASSERT(NS_IsMainThread(), "wrong thread"); EnsureTableExists(); - AtomTableKey key(aString, aLength); + AtomTableKey key(aString, aLength, aHash); AtomTableEntry* e = static_cast (PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD)); @@ -508,11 +527,11 @@ GetAtomHashEntry(const char* aString, uint32_t aLength) } static inline AtomTableEntry* -GetAtomHashEntry(const PRUnichar* aString, uint32_t aLength) +GetAtomHashEntry(const PRUnichar* aString, uint32_t aLength, uint32_t& aHash) { MOZ_ASSERT(NS_IsMainThread(), "wrong thread"); EnsureTableExists(); - AtomTableKey key(aString, aLength); + AtomTableKey key(aString, aLength, aHash); AtomTableEntry* e = static_cast (PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD)); @@ -558,9 +577,10 @@ RegisterStaticAtoms(const nsStaticAtom* aAtoms, uint32_t aAtomCount) uint32_t stringLen = aAtoms[i].mStringBuffer->StorageSize() / sizeof(PRUnichar) - 1; + uint32_t hash = 0; AtomTableEntry *he = GetAtomHashEntry((PRUnichar*)aAtoms[i].mStringBuffer->Data(), - stringLen); + stringLen, hash); if (he->mAtom) { // there already is an atom with this name in the table.. but we @@ -577,7 +597,7 @@ RegisterStaticAtoms(const nsStaticAtom* aAtoms, uint32_t aAtomCount) else { AtomImpl* atom = new PermanentAtomImpl(aAtoms[i].mStringBuffer, stringLen, - he->keyHash); + hash); he->mAtom = atom; *aAtoms[i].mAtom = atom; @@ -598,8 +618,10 @@ NS_NewAtom(const char* aUTF8String) already_AddRefed NS_NewAtom(const nsACString& aUTF8String) { + uint32_t hash = 0; AtomTableEntry *he = GetAtomHashEntry(aUTF8String.Data(), - aUTF8String.Length()); + aUTF8String.Length(), + hash); if (he->mAtom) { nsCOMPtr atom = he->mAtom; @@ -612,7 +634,7 @@ NS_NewAtom(const nsACString& aUTF8String) // Actually, now there is, sort of: ForgetSharedBuffer. nsString str; CopyUTF8toUTF16(aUTF8String, str); - nsRefPtr atom = new AtomImpl(str, he->keyHash); + nsRefPtr atom = new AtomImpl(str, hash); he->mAtom = atom; @@ -628,8 +650,10 @@ NS_NewAtom(const PRUnichar* aUTF16String) already_AddRefed NS_NewAtom(const nsAString& aUTF16String) { + uint32_t hash = 0; AtomTableEntry *he = GetAtomHashEntry(aUTF16String.Data(), - aUTF16String.Length()); + aUTF16String.Length(), + hash); if (he->mAtom) { nsCOMPtr atom = he->mAtom; @@ -637,7 +661,7 @@ NS_NewAtom(const nsAString& aUTF16String) return atom.forget(); } - nsRefPtr atom = new AtomImpl(aUTF16String, he->keyHash); + nsRefPtr atom = new AtomImpl(aUTF16String, hash); he->mAtom = atom; return atom.forget(); @@ -646,8 +670,10 @@ NS_NewAtom(const nsAString& aUTF16String) nsIAtom* NS_NewPermanentAtom(const nsAString& aUTF16String) { + uint32_t hash = 0; AtomTableEntry *he = GetAtomHashEntry(aUTF16String.Data(), - aUTF16String.Length()); + aUTF16String.Length(), + hash); AtomImpl* atom = he->mAtom; if (atom) { @@ -656,7 +682,7 @@ NS_NewPermanentAtom(const nsAString& aUTF16String) } } else { - atom = new PermanentAtomImpl(aUTF16String, he->keyHash); + atom = new PermanentAtomImpl(aUTF16String, hash); he->mAtom = atom; } diff --git a/xulrunner/app/Makefile.in b/xulrunner/app/Makefile.in index 59b37cca96df..62dbe48d4372 100644 --- a/xulrunner/app/Makefile.in +++ b/xulrunner/app/Makefile.in @@ -103,7 +103,7 @@ endif # XXX applications would need to supply this file #export:: brand.dtd.in -# $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > brand.dtd +# $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $^ -o brand.dtd) export:: $(NSINSTALL) -D $(DIST)/branding diff --git a/xulrunner/installer/Makefile.in b/xulrunner/installer/Makefile.in index 52ecf057e8e5..27206463ba72 100644 --- a/xulrunner/installer/Makefile.in +++ b/xulrunner/installer/Makefile.in @@ -107,25 +107,24 @@ DEFINES += \ ifeq ($(OS_TARGET),Linux) debian/changelog: $(srcdir)/debian/changelog.in $(LIBXUL_DIST)/bin/platform.ini - mkdir -p debian - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@ + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) debian/xulrunner.links: $(srcdir)/debian/xulrunner.links.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@ + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) debian/xulrunner.service: $(srcdir)/debian/xulrunner.service.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@ + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) debian/prerm: $(srcdir)/debian/prerm.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@ + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) debian/postinst: $(srcdir)/debian/postinst.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@ + $(call py_action,preprocessor, \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ -o $@) package: $(MAKE) package -C $(DEPTH)