Merge remote-tracking branch 'origin/master' into kmeleon76

This commit is contained in:
2023-09-28 15:22:50 +08:00
211 changed files with 9155 additions and 2415 deletions
+3 -6
View File
@@ -124,16 +124,13 @@ ifdef JS_STANDALONE
NO_REMOVE=1
endif
.PHONY: $(addprefix install-,$(install_manifests))
$(addprefix install-,$(filter dist/%,$(install_manifests))): install-dist/%: $(install_manifest_depends)
$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )$(DIST)/$* _build_manifests/install/dist_$*)
.PHONY: $(addprefix install-,$(subst /,_,$(install_manifests)))
$(addprefix install-,$(install_manifests)): install-%: $(install_manifest_depends)
$(addprefix $(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )$*) ,$(wildcard _build_manifests/install/$(subst /,_,$*)))
# Dummy wrapper rule to allow the faster backend to piggy back
install-dist_%: install-dist/% ;
install-_tests: $(install_manifest_depends)
$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )_tests _build_manifests/install/tests)
# For compatibility
.PHONY: install-tests
install-tests: install-_tests
+11 -3
View File
@@ -2,7 +2,15 @@
# 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/.
GAIA_PATH := gaia/profile
# For b2gdroid, gaia ends up in the assets/gaia folder in the APK.
GAIA_PATH := $(if MOZ_B2GDROID,gaia/assets/gaia,gaia/profile)
# For b2gdroid, we disable the screen timeout since this is managed by android.
# We also limit the app set to the production ones.
GAIA_OPTIONS := $(if MOZ_B2GDROID, \
GAIA_DISTRIBUTION_DIR=distros/b2gdroid \
NO_LOCK_SCREEN=1 \
)
GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
@@ -10,5 +18,5 @@ include $(topsrcdir)/config/rules.mk
libs::
+$(MAKE) -j1 -C $(GAIADIR) clean
+$(MAKE) -j1 -C $(GAIADIR) profile
(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
+$(GAIA_OPTIONS) $(MAKE) -j1 -C $(GAIADIR) profile
(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(ABS_DIST)/bin/$(GAIA_PATH) && tar -xf -)
+15 -13
View File
@@ -4,17 +4,19 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Program(CONFIG['MOZ_APP_NAME'])
if not CONFIG['MOZ_B2GDROID']:
# b2gdroid does not build a runner executable, but it does build gaia; see Makefile.in.
Program(CONFIG['MOZ_APP_NAME'])
if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'run-b2g.cpp',
]
DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
else:
SOURCES += [
'run-b2g.c',
]
DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = '"gaia/profile"'
if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'run-b2g.cpp',
]
DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
else:
SOURCES += [
'run-b2g.c',
]
DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = '"gaia/profile"'
-6
View File
@@ -25,12 +25,6 @@ ifdef MOZ_NO_DEBUG_RTL
DEFINES += -DMOZ_PACKAGE_MSVC_DLLS=1
DEFINES += -DMSVC_C_RUNTIME_DLL=$(MSVC_C_RUNTIME_DLL)
DEFINES += -DMSVC_CXX_RUNTIME_DLL=$(MSVC_CXX_RUNTIME_DLL)
ifdef MSVC_APPCRT_DLL
DEFINES += -DMSVC_APPCRT_DLL=$(MSVC_APPCRT_DLL)
endif
ifdef MSVC_DESKTOPCRT_DLL
DEFINES += -DMSVC_DESKTOPCRT_DLL=$(MSVC_DESKTOPCRT_DLL)
endif
endif
endif
-6
View File
@@ -87,12 +87,6 @@
#if MOZ_PACKAGE_MSVC_DLLS
@BINPATH@/@MSVC_C_RUNTIME_DLL@
@BINPATH@/@MSVC_CXX_RUNTIME_DLL@
#ifdef MSVC_APPCRT_DLL
@BINPATH@/@MSVC_APPCRT_DLL@
#endif
#ifdef MSVC_DESKTOPCRT_DLL
@BINPATH@/@MSVC_DESKTOPCRT_DLL@
#endif
#endif
#endif
#ifndef MOZ_NATIVE_ICU
+8 -8
View File
@@ -19,8 +19,8 @@ PWD := $(CURDIR)
# pulls. You may override them if you provide your own files. You _must_
# override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not
# work in that case.
ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE)
WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
ZIP_IN ?= $(ABS_DIST)/$(PACKAGE)
WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
RETRIEVE_WINDOWS_INSTALLER = 1
MOZ_LANGPACK_EID=langpack-$(AB_CD)@b2g.mozilla.org
@@ -31,9 +31,9 @@ L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warning
PP_TARGETS += L10N_PREF_JS_EXPORTS
ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore
MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png
MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns
MOZ_PKG_MAC_DSSTORE=$(ABS_DIST)/branding/dsstore
MOZ_PKG_MAC_BACKGROUND=$(ABS_DIST)/branding/background.png
MOZ_PKG_MAC_ICON=$(ABS_DIST)/branding/disk.icns
MOZ_PKG_MAC_EXTRA=--symlink '/Applications:/ '
endif
@@ -41,8 +41,8 @@ ifeq (WINNT,$(OS_ARCH))
UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \
$(NSINSTALL) -D $(STAGEDIST)/uninstall; \
cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \
$(RM) $(_ABS_DIST)/l10n-stage/setup.exe; \
cp ../installer/windows/l10ngen/setup.exe $(_ABS_DIST)/l10n-stage; \
$(RM) $(ABS_DIST)/l10n-stage/setup.exe; \
cp ../installer/windows/l10ngen/setup.exe $(ABS_DIST)/l10n-stage; \
$(NULL)
endif
@@ -75,7 +75,7 @@ chrome-%:
@$(MAKE) chrome AB_CD=$*
@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$*
repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
repackage-win32-installer: WIN32_INSTALLER_OUT=$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
repackage-win32-installer: $(call ESCAPE_SPACE,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD)
@echo 'Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT).'
$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export
@@ -276,7 +276,7 @@ this.MigratorPrototype = {
doMigrate();
};
BookmarkHTMLUtils.importFromURL(
"resource:///defaults/profile/bookmarks.html", true).then(
"chrome://browser/locale/bookmarks.html", true).then(
onImportComplete, onImportComplete);
return;
}
+1 -1
View File
@@ -1096,7 +1096,7 @@ BrowserGlue.prototype = {
var bookmarksUrl = null;
if (restoreDefaultBookmarks) {
// User wants to restore bookmarks.html file from default profile folder
bookmarksUrl = "resource:///defaults/profile/bookmarks.html";
bookmarksUrl = "chrome://browser/locale/bookmarks.html";
}
else if (yield OS.File.exists(BookmarkHTMLUtils.defaultPath)) {
bookmarksUrl = OS.Path.toFileURI(BookmarkHTMLUtils.defaultPath);
-6
View File
@@ -66,12 +66,6 @@ DEFINES += -DMOZ_PACKAGE_MSVC_DLLS=1
DEFINES += -DMSVC_C_RUNTIME_DLL=$(MSVC_C_RUNTIME_DLL)
DEFINES += -DMSVC_CXX_RUNTIME_DLL=$(MSVC_CXX_RUNTIME_DLL)
DEFINES += -DMSVC_OPENMP_DLL=$(MSVC_OPENMP_DLL)
ifdef MSVC_APPCRT_DLL
DEFINES += -DMSVC_APPCRT_DLL=$(MSVC_APPCRT_DLL)
endif
ifdef MSVC_DESKTOPCRT_DLL
DEFINES += -DMSVC_DESKTOPCRT_DLL=$(MSVC_DESKTOPCRT_DLL)
endif
endif
endif
-7
View File
@@ -46,7 +46,6 @@
@RESPATH@/browser/chrome/@AB_CD@.manifest
@RESPATH@/chrome/@AB_CD@@JAREXT@
@RESPATH@/chrome/@AB_CD@.manifest
@RESPATH@/browser/defaults/profile/bookmarks.html
@RESPATH@/browser/defaults/profile/chrome/*
@RESPATH@/browser/defaults/profile/localstore.rdf
@RESPATH@/browser/defaults/profile/mimeTypes.rdf
@@ -103,12 +102,6 @@
@BINPATH@/@MSVC_C_RUNTIME_DLL@
@BINPATH@/@MSVC_CXX_RUNTIME_DLL@
@BINPATH@/@MSVC_OPENMP_DLL@
#ifdef MSVC_APPCRT_DLL
@BINPATH@/@MSVC_APPCRT_DLL@
#endif
#ifdef MSVC_DESKTOPCRT_DLL
@BINPATH@/@MSVC_DESKTOPCRT_DLL@
#endif
#endif
#endif
#ifndef MOZ_NATIVE_ICU
+30 -28
View File
@@ -6,11 +6,11 @@
include $(topsrcdir)/config/config.mk
ifdef LOCALE_MERGEDIR
vpath book%.inc $(LOCALE_MERGEDIR)/browser/profile
vpath crashreporter%.ini $(LOCALE_MERGEDIR)/browser/crashreporter
endif
vpath book%.inc $(LOCALE_SRCDIR)/profile
vpath crashreporter%.ini $(LOCALE_SRCDIR)/crashreporter
ifdef LOCALE_MERGEDIR
vpath book%.inc @srcdir@/en-US/profile
vpath crashreporter%.ini @srcdir@/en-US/crashreporter
endif
@@ -28,8 +28,8 @@ PWD := $(CURDIR)
# pulls. You may override them if you provide your own files. You _must_
# override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not
# work in that case.
ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE)
WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
ZIP_IN ?= $(ABS_DIST)/$(PACKAGE)
WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
RETRIEVE_WINDOWS_INSTALLER = 1
MOZ_LANGPACK_EID=langpack-$(AB_CD)@palemoon.org
@@ -40,9 +40,9 @@ L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warning
PP_TARGETS += L10N_PREF_JS_EXPORTS
ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore
MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png
MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns
MOZ_PKG_MAC_DSSTORE=$(ABS_DIST)/branding/dsstore
MOZ_PKG_MAC_BACKGROUND=$(ABS_DIST)/branding/background.png
MOZ_PKG_MAC_ICON=$(ABS_DIST)/branding/disk.icns
MOZ_PKG_MAC_EXTRA=--symlink '/Applications:/ '
endif
@@ -50,21 +50,22 @@ ifeq (WINNT,$(OS_ARCH))
UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \
$(NSINSTALL) -D $(STAGEDIST)/uninstall; \
cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \
$(RM) $(_ABS_DIST)/l10n-stage/setup.exe; \
cp ../installer/windows/l10ngen/setup.exe $(_ABS_DIST)/l10n-stage; \
$(RM) $(ABS_DIST)/l10n-stage/setup.exe; \
cp ../installer/windows/l10ngen/setup.exe $(ABS_DIST)/l10n-stage; \
$(NULL)
STUB_HOOK = $(NSINSTALL) -D '$(_ABS_DIST)/$(PKG_INST_PATH)'; \
$(RM) '$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \
cp ../installer/windows/l10ngen/stub.exe '$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \
chmod 0755 '$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \
STUB_HOOK = $(NSINSTALL) -D '$(ABS_DIST)/$(PKG_INST_PATH)'; \
$(RM) '$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \
cp ../installer/windows/l10ngen/stub.exe '$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \
chmod 0755 '$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \
$(NULL)
endif
SEARCHPLUGINS_NAMES = $(shell cat $(call MERGE_FILE,/searchplugins/list.txt))
SEARCHPLUGINS_FILENAMES = $(subst :hidden,,$(SEARCHPLUGINS_NAMES))
SEARCHPLUGINS_PATH := .deps/generated_$(AB_CD)
SEARCHPLUGINS_TARGET := libs searchplugins
SEARCHPLUGINS := $(foreach plugin,$(addsuffix .xml,$(SEARCHPLUGINS_NAMES)),$(or $(wildcard $(call EN_US_OR_L10N_FILE,searchplugins/$(plugin))),$(info Missing searchplugin: $(plugin))))
SEARCHPLUGINS := $(foreach plugin,$(addsuffix .xml,$(SEARCHPLUGINS_FILENAMES)),$(or $(wildcard $(call EN_US_OR_L10N_FILE,searchplugins/$(plugin))),$(warning Missing searchplugin: $(plugin))))
# Some locale-specific search plugins may have preprocessor directives, but the
# default en-US ones do not.
SEARCHPLUGINS_FLAGS := --silence-missing-directive-warnings
@@ -100,17 +101,7 @@ PROFILE_FILES = \
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 $@)
$(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 ;
DEFINES += -DBOOKMARKS_INCLUDE_DIR=$(dir $(call MERGE_FILE,profile/bookmarks.inc))
libs:: $(addprefix generic/profile/,$(PROFILE_FILES))
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile
@@ -130,13 +121,16 @@ libs-%:
$(NSINSTALL) -D $(DIST)/install
@$(MAKE) -C ../../toolkit/locales libs-$*
@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$*
ifdef MOZ_WEBAPP_RUNTIME
@$(MAKE) -C ../../webapprt/locales AB_CD=$* XPI_NAME=locale-$*
endif
@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../intl/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -B searchplugins AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$*
repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
repackage-win32-installer: WIN32_INSTALLER_OUT=$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
repackage-win32-installer: $(call ESCAPE_WILDCARD,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD)
@echo 'Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT).'
$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export
@@ -198,6 +192,11 @@ else
endif
endif
ifdef MOZ_CRASHREPORTER
libs:: crashreporter-override.ini
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
endif
ident:
@printf 'fx_revision '
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
@@ -220,6 +219,9 @@ l10n-check::
$(RM) -rf x-test
$(NSINSTALL) -D x-test/toolkit
echo '#define MOZ_LANG_TITLE Just testing' > x-test/toolkit/defines.inc
$(MAKE) installers-x-test L10NBASEDIR='$(PWD)' LOCALE_MERGEDIR='$(PWD)/mergedir'
@# ZIP_IN='$(ZIP_IN)' will pass down the *current* value of ZIP_IN, based
@# on MOZ_SIMPLE_PACKAGE_NAME not being reset, overwriting the value it
@# would get with MOZ_SIMPLE_PACKAGE_NAME reset.
$(MAKE) installers-x-test L10NBASEDIR='$(PWD)' LOCALE_MERGEDIR='$(PWD)/mergedir' ZIP_IN='$(ZIP_IN)' MOZ_SIMPLE_PACKAGE_NAME=
$(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/unpack.py $(DIST)/l10n-stage/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)
cd $(DIST)/l10n-stage && test $$(cat $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/update.locale) = x-test
@@ -1,4 +1,12 @@
#filter substitution
#include @BOOKMARKS_INCLUDE_DIR@/bookmarks.inc
#define ja_jp_mac ja-JP-mac
#if AB_CD == ja_jp_mac
#define AB_CD ja
#endif
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
+6
View File
@@ -6,6 +6,7 @@
@AB_CD@.jar:
% locale browser @AB_CD@ %locale/browser/
* locale/browser/bookmarks.html (generic/profile/bookmarks.html.in)
locale/browser/aboutCertError.dtd (%chrome/browser/aboutCertError.dtd)
locale/browser/aboutDialog.dtd (%chrome/browser/aboutDialog.dtd)
locale/browser/aboutPrivateBrowsing.dtd (%chrome/browser/aboutPrivateBrowsing.dtd)
@@ -89,8 +90,13 @@
locale/browser/syncQuota.dtd (%chrome/browser/syncQuota.dtd)
locale/browser/syncQuota.properties (%chrome/browser/syncQuota.properties)
#endif
#if BUILD_FASTER
locale/browser/searchplugins/list.txt (%searchplugins/list.txt)
locale/browser/searchplugins/ (%searchplugins/*.xml)
#else
locale/browser/searchplugins/list.txt (.deps/generated_@AB_CD@/list.txt)
locale/browser/searchplugins/ (.deps/generated_@AB_CD@/*.xml)
#endif
% locale browser-region @AB_CD@ %locale/browser-region/
locale/browser-region/region.properties (%chrome/browser-region/region.properties)
# the following files are browser-specific overrides
+2 -2
View File
@@ -33,7 +33,7 @@ endif
# NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir.
# needs to be absolute to be distinct from $(topsrcdir)/.gdbinit
GDBINIT_OBJDIR_FILES = $(topsrcdir)/.gdbinit
GDBINIT_OBJDIR_DEST = $(abspath $(DEPTH))
GDBINIT_OBJDIR_DEST = $(topobjdir)
INSTALL_TARGETS += GDBINIT_OBJDIR
# Put a .lldbinit in the bin directory and the objdir, to be picked up
@@ -52,7 +52,7 @@ INSTALL_TARGETS += LLDBINIT_FINAL_TARGET
# Put the .ycm_extra_conf.py file at the root of the objdir. It is used by
# the vim plugin YouCompleteMe.
YCM_FILES := $(topsrcdir)/.ycm_extra_conf.py
YCM_DEST := $(abspath $(DEPTH))
YCM_DEST := $(topobjdir)
YCM_TARGET := export
INSTALL_TARGETS += YCM
+10 -4
View File
@@ -396,7 +396,7 @@ class Automation(object):
self.log.info("Can't trigger Breakpad, just killing process")
self.killPid(processPID)
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath):
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath, outputHandler=None):
""" Look for timeout or crashes and return the status after the process terminates """
stackFixerFunction = None
didTimeout = False
@@ -437,7 +437,12 @@ class Automation(object):
while line != "" and not didTimeout:
if stackFixerFunction:
line = stackFixerFunction(line)
self.log.info(line.rstrip().decode("UTF-8", "ignore"))
if outputHandler is None:
self.log.info(line.rstrip().decode("UTF-8", "ignore"))
else:
outputHandler(line)
if "TEST-START" in line and "|" in line:
self.lastTestSeen = line.split("|")[1].strip()
if not debuggerInfo and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
@@ -531,7 +536,7 @@ class Automation(object):
debuggerInfo = None, symbolsPath = None,
timeout = -1, maxTime = None, onLaunch = None,
detectShutdownLeaks = False, screenshotOnFail=False, testPath=None, bisectChunk=None,
valgrindPath=None, valgrindArgs=None, valgrindSuppFiles=None):
valgrindPath=None, valgrindArgs=None, valgrindSuppFiles=None, outputHandler=None):
"""
Run the app, log the duration it took to execute, return the status code.
Kills the app if it runs for longer than |maxTime| seconds, or outputs nothing for |timeout| seconds.
@@ -580,7 +585,8 @@ class Automation(object):
# app is launched.
onLaunch()
status = self.waitForFinish(proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath)
status = self.waitForFinish(proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath,
outputHandler=outputHandler)
self.log.info("INFO | automation.py | Application ran for: %s", str(datetime.now() - startTime))
# Do a final check for zombie child processes.
+15 -2
View File
@@ -18,6 +18,7 @@ ALL_HARNESSES = [
'jittest',
'mozbase',
'web-platform',
'gtest',
]
PACKAGE_SPECIFIED_HARNESSES = [
@@ -28,6 +29,11 @@ PACKAGE_SPECIFIED_HARNESSES = [
'web-platform',
]
# These packages are not present for every build configuration.
OPTIONAL_PACKAGES = [
'gtest',
]
def parse_args():
parser = ArgumentParser(description='Generate a test_packages.json file to tell automation which harnesses require which test packages.')
@@ -41,6 +47,10 @@ def parse_args():
parser.add_argument("--%s" % harness, required=True,
action="store", dest=harness,
help="Name of the %s zip." % harness)
for harness in OPTIONAL_PACKAGES:
parser.add_argument("--%s" % harness, required=False,
action="store", dest=harness,
help="Name of the %s zip." % harness)
parser.add_argument("--dest-file", required=True,
action="store", dest="destfile",
help="Path to the output file to be written.")
@@ -58,8 +68,11 @@ def generate_package_data(args):
harness_requirements = dict([(k, [tests_common]) for k in ALL_HARNESSES])
harness_requirements['jittest'].append(jsshell)
for harness in PACKAGE_SPECIFIED_HARNESSES:
harness_requirements[harness].append(getattr(args, harness))
for harness in PACKAGE_SPECIFIED_HARNESSES + OPTIONAL_PACKAGES:
pkg_name = getattr(args, harness, None)
if pkg_name is None:
continue
harness_requirements[harness].append(pkg_name)
return harness_requirements
if __name__ == '__main__':
-26
View File
@@ -29,29 +29,3 @@ postflight_all:
# actually does a universal staging with both OBJDIR_ARCH_1 and OBJDIR_ARCH_2.
$(MAKE) -C $(OBJDIR_ARCH_1)/$(MOZ_BUILD_APP)/installer \
PKG_SKIP_STRIP=1 stage-package
ifdef ENABLE_TESTS
# Now, repeat the process for the test package.
$(MAKE) -C $(OBJDIR_ARCH_1) UNIVERSAL_BINARY= CHROME_JAR= package-tests
$(MAKE) -C $(OBJDIR_ARCH_2) UNIVERSAL_BINARY= CHROME_JAR= package-tests
rm -rf $(DIST_UNI)/test-stage
# automation.py differs because it hardcodes a path to
# dist/bin. It doesn't matter which one we use.
if test -d $(DIST_ARCH_1)/test-stage -a \
-d $(DIST_ARCH_2)/test-stage; then \
cp $(DIST_ARCH_1)/test-stage/mochitest/automation.py \
$(DIST_ARCH_2)/test-stage/mochitest/; \
cp -RL $(DIST_ARCH_1)/test-stage/mochitest/extensions/specialpowers \
$(DIST_ARCH_2)/test-stage/mochitest/extensions/; \
cp $(DIST_ARCH_1)/test-stage/xpcshell/automation.py \
$(DIST_ARCH_2)/test-stage/xpcshell/; \
cp $(DIST_ARCH_1)/test-stage/reftest/automation.py \
$(DIST_ARCH_2)/test-stage/reftest/; \
cp -RL $(DIST_ARCH_1)/test-stage/reftest/specialpowers \
$(DIST_ARCH_2)/test-stage/reftest/; \
$(TOPSRCDIR)/build/macosx/universal/unify \
--unify-with-sort "\.manifest$$" \
--unify-with-sort "all-test-dirs\.list$$" \
$(DIST_ARCH_1)/test-stage \
$(DIST_ARCH_2)/test-stage \
$(DIST_UNI)/test-stage; fi
endif
+1 -1
View File
@@ -6,6 +6,6 @@
# As used here, arguments in $MOZ_BUILD_PROJECTS are suitable as arguments
# to gcc's -arch parameter.
mk_add_options MOZ_BUILD_PROJECTS="i386 x86_64"
mk_add_options MOZ_BUILD_PROJECTS="x86_64 i386"
. $topsrcdir/build/macosx/universal/mozconfig.common
+19 -10
View File
@@ -205,23 +205,31 @@ class B2GRemoteAutomation(Automation):
return app, args
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime,
debuggerInfo, symbolsPath):
debuggerInfo, symbolsPath, outputHandler=None):
""" Wait for tests to finish (as evidenced by a signature string
in logcat), or for a given amount of time to elapse with no
output.
"""
timeout = timeout or 120
while True:
currentlog = proc.getStdoutLines(timeout)
if currentlog:
print currentlog
lines = proc.getStdoutLines(timeout)
if lines:
currentlog = '\n'.join(lines)
if outputHandler:
for line in lines:
outputHandler(line)
else:
print(currentlog)
# Match the test filepath from the last TEST-START line found in the new
# log content. These lines are in the form:
# ... INFO TEST-START | /filepath/we/wish/to/capture.html\n
testStartFilenames = re.findall(r"TEST-START \| ([^\s]*)", currentlog)
if testStartFilenames:
self.lastTestSeen = testStartFilenames[-1]
if hasattr(self, 'logFinish') and self.logFinish in currentlog:
if (outputHandler and outputHandler.suite_finished) or (
hasattr(self, 'logFinish') and self.logFinish in currentlog):
return 0
else:
self.log.info("TEST-UNEXPECTED-FAIL | %s | application timed "
@@ -431,11 +439,12 @@ class B2GRemoteAutomation(Automation):
break
# wait 'timeout' for any additional lines
try:
lines.append(self.queue.get(True, timeout))
except Queue.Empty:
pass
return '\n'.join(lines)
if not lines:
try:
lines.append(self.queue.get(True, timeout))
except Queue.Empty:
pass
return lines
def wait(self, timeout=None):
# this should never happen
+20 -18
View File
@@ -80,7 +80,7 @@ class RemoteAutomation(Automation):
return env
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath):
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath, outputHandler=None):
""" Wait for tests to finish.
If maxTime seconds elapse or no output is detected for timeout
seconds, kill the process and fail the test.
@@ -264,20 +264,21 @@ class RemoteAutomation(Automation):
return pid
def read_stdout(self):
""" Fetch the full remote log file using devicemanager and return just
the new log entries since the last call (as a list of messages or lines).
"""
Fetch the full remote log file using devicemanager, process them and
return whether there were any new log entries since the last call.
"""
if not self.dm.fileExists(self.proc):
return []
return False
try:
newLogContent = self.dm.pullFile(self.proc, self.stdoutlen)
except DMError:
# we currently don't retry properly in the pullFile
# function in dmSUT, so an error here is not necessarily
# the end of the world
return []
return False
if not newLogContent:
return []
return False
self.stdoutlen += len(newLogContent)
@@ -286,26 +287,27 @@ class RemoteAutomation(Automation):
if testStartFilenames:
self.lastTestSeen = testStartFilenames[-1]
print newLogContent
return [newLogContent]
return True
self.logBuffer += newLogContent
lines = self.logBuffer.split('\n')
if not lines:
return
# We only keep the last (unfinished) line in the buffer
self.logBuffer = lines[-1]
del lines[-1]
messages = []
if lines:
# We only keep the last (unfinished) line in the buffer
self.logBuffer = lines[-1]
del lines[-1]
if not lines:
return False
for line in lines:
# This passes the line to the logger (to be logged or buffered)
# and returns a list of structured messages (dict)
parsed_messages = self.messageLogger.write(line)
for message in parsed_messages:
if message['action'] == 'test_start':
if isinstance(message, dict) and message.get('action') == 'test_start':
self.lastTestSeen = message['test']
messages += parsed_messages
return messages
return True
@property
def getLastTestSeen(self):
@@ -331,10 +333,10 @@ class RemoteAutomation(Automation):
# too long, only do it every 60 seconds
if (not slowLog) or (timer % 60 == 0):
startRead = datetime.datetime.now()
messages = self.read_stdout()
hasOutput = self.read_stdout()
if (datetime.datetime.now() - startRead) > datetime.timedelta(seconds=5):
slowLog = True
if messages:
if hasOutput:
noOutputTimer = 0
time.sleep(interval)
timer += interval
-20
View File
@@ -1,20 +0,0 @@
#!/bin/sh
# 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/.
args=""
for i in "${@}"
do
case "$i" in
-I?:/*)
i="$(echo "${i}" | sed -e 's|^-I\(.\):/|-I/\1/|')"
;;
esac
args="${args} '${i}'"
done
eval "exec perl $args"
+4
View File
@@ -112,6 +112,10 @@ def GetRemotePath(path, local_file, base_path):
full remote path to place the file in. If base_path is not None, include
the relative path from base_path to file."""
if base_path is None or not local_file.startswith(base_path):
# Hack to work around OSX uploading the i386 SDK from i386/dist. Both
# the i386 SDK and x86-64 SDK end up in the same directory this way.
if base_path.endswith('/x86_64/dist'):
return GetBaseRelativePath(path, local_file, base_path.replace('/x86_64/', '/i386/'))
return path
dir = os.path.dirname(local_file)
# strip base_path + extra slash and make it unixy
-2
View File
@@ -10,8 +10,6 @@ REDIST_FILES = \
$(MSVC_REDIST_CRT_DIR)/$(MSVC_C_RUNTIME_DLL) \
$(MSVC_REDIST_CRT_DIR)/$(MSVC_CXX_RUNTIME_DLL) \
$(MSVC_REDIST_OPENMP_DIR)/$(MSVC_OPENMP_DLL) \
$(MSVC_APPCRT_DLL) \
$(MSVC_DESKTOPCRT_DLL) \
$(NULL)
libs-preqs = \
+1
View File
@@ -18,6 +18,7 @@ else
DIST = $(DEPTH)/$(TOP_DIST)
endif
endif
ABS_DIST = $(topobjdir)/dist
# We do magic with OBJ_SUFFIX in config.mk, the following ensures we don't
# manually use it before config.mk inclusion
+1 -6
View File
@@ -205,12 +205,7 @@ OS_LDFLAGS += $(_DEBUG_LDFLAGS)
# XXX: What does this? Bug 482434 filed for better explanation.
ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_)
ifdef MOZ_DEBUG
ifneq (,$(MOZ_BROWSE_INFO)$(MOZ_BSCFILE))
OS_CFLAGS += -FR
OS_CXXFLAGS += -FR
endif
else # ! MOZ_DEBUG
ifndef MOZ_DEBUG
# MOZ_DEBUG_SYMBOLS generates debug symbols in separate PDB files.
# Used for generating an optimized build with debugging symbols.
-1
View File
@@ -8,7 +8,6 @@ include $(topsrcdir)/config/rules.mk
ifdef MOZ_BUILD_NSPR
# Copy NSPR to the SDK
ABS_DIST = $(abspath $(DIST))
ifdef MOZ_FOLD_LIBS
# Trick the nspr build system into not building shared libraries.
-9
View File
@@ -94,15 +94,6 @@ NSS_EXTRA_DLLS += freebl_64int_3
NSS_EXTRA_DLLS += freebl_64fpu_3
endif
ABS_DIST := $(abspath $(DIST))
ifeq ($(HOST_OS_ARCH),WINNT)
ifdef CYGDRIVE_MOUNT
ABS_DIST := $(shell cygpath -w $(ABS_DIST) | sed -e 's|\\|/|g')
endif
ifneq (,$(filter mingw%,$(host_os)))
ABS_DIST := $(shell cd $(DIST) && pwd -W)
endif
endif
# For all variables such as DLLFLAGS, that may contain $(DIST)
DIST := $(ABS_DIST)
NSPR_INCLUDE_DIR = $(firstword $(filter -I%,$(NSPR_CFLAGS)))
+1
View File
@@ -676,6 +676,7 @@ SSL_SetStapledOCSPResponses
SSL_SetURL
SSL_SNISocketConfigHook
SSL_VersionRangeGet
SSL_VersionRangeGetDefault
SSL_VersionRangeGetSupported
SSL_VersionRangeSet
SSL_VersionRangeSetDefault
+9 -4
View File
@@ -58,10 +58,6 @@ endif
# toolkit/content/buildconfig.html and browser/locales/jar.mn.
ACDEFINES += -DBUILD_FASTER
# Generic rule to fall back to the recursive make backend
$(TOPOBJDIR)/%: FORCE
$(MAKE) -C $(dir $@) $(notdir $@)
# Files under the faster/ sub-directory, however, are not meant to use the
# fallback
$(TOPOBJDIR)/faster/%: ;
@@ -76,6 +72,13 @@ $(TOPOBJDIR)/dist/%:
rm -f $@
cp $< $@
# Generic rule to fall back to the recursive make backend.
# This needs to stay after other $(TOPOBJDIR)/* rules because GNU Make
# <3.82 apply pattern rules in definition order, not stem length like
# modern GNU Make.
$(TOPOBJDIR)/%: FORCE
$(MAKE) -C $(dir $@) $(notdir $@)
# Refresh backend
$(BACKEND):
cd $(TOPOBJDIR) && $(PYTHON) config.status --backend FasterMake
@@ -93,11 +96,13 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(TOPOBJDIR)/config/build
@# The overhead is not that big, and this avoids waiting for proper
@# support for defines tracking in process_install_manifest.
@touch install_$(subst /,_,$*)
@# BOOKMARKS_INCLUDE_DIR is for bookmarks.html only.
$(PYTHON) -m mozbuild.action.process_install_manifest \
--no-remove \
--no-remove-empty-directories \
$(TOPOBJDIR)/$* \
-DAB_CD=en-US \
-DBOOKMARKS_INCLUDE_DIR=$(TOPSRCDIR)/browser/locales/en-US/profile \
-DMOZ_APP_BUILDID=$(shell cat $(TOPOBJDIR)/config/buildid) \
$(ACDEFINES) \
$(MOZ_DEBUG_DEFINES) \
+136 -153
View File
@@ -76,6 +76,7 @@ GCONF_VERSION=1.2.1
STARTUP_NOTIFICATION_VERSION=0.8
DBUS_VERSION=0.60
SQLITE_VERSION=3.21.0
FONTCONFIG_VERSION=2.7.0
MSMANIFEST_TOOL=
@@ -538,8 +539,6 @@ case "$target" in
MSVS_VERSION=2015
MSVC_C_RUNTIME_DLL=vcruntime140.dll
MSVC_CXX_RUNTIME_DLL=msvcp140.dll
MSVC_APPCRT_DLL=appcrt140.dll
MSVC_DESKTOPCRT_DLL=desktopcrt140.dll
# -Wv:18 disables all warnings introduced after VS2013
# See http://blogs.msdn.com/b/vcblog/archive/2014/11/12/improvements-to-warnings-in-the-c-compiler.aspx
@@ -569,8 +568,6 @@ See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
AC_SUBST(MSVC_CXX_RUNTIME_DLL)
AC_SUBST(MSVC_REDIST_OPENMP_DIR)
AC_SUBST(MSVC_OPENMP_DLL)
AC_SUBST(MSVC_APPCRT_DLL)
AC_SUBST(MSVC_DESKTOPCRT_DLL)
# Disable SEH on clang-cl because it doesn't implement them yet.
if test -z "$CLANG_CL"; then
@@ -793,7 +790,7 @@ else
fi
if test -z "$COMPILE_ENVIRONMENT"; then
NSINSTALL_BIN='$(PYTHON) $(topsrcdir)/config/nsinstall.py'
NSINSTALL_BIN='$(PYTHON) $(MOZILLA_DIR)/config/nsinstall.py'
fi
AC_SUBST(NSINSTALL_BIN)
@@ -1459,65 +1456,40 @@ if test "$GNU_CC"; then
fi
# Turn on gcc/clang warnings:
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
#
# -Wall - turn on a lot of warnings
# -Wchar-subscripts - catches array index using signed char
# -Wcomment - catches nested comments
# https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Warning-Options.html
# -Wall - lots of useful warnings
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
# -Wenum-compare - catches comparison of different enum types
# -Wignored-qualifiers - catches returns types with qualifiers like const
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmultichar - catches multicharacter integer constants like 'THIS'
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wnonnull - catches NULL used with functions arguments marked as non-null
# -Wignored-qualifiers - catches return types with qualifiers like const
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
# -Wpointer-sign - catches mixing pointers to signed and unsigned types
# -Wpointer-to-int-cast - catches casts from pointer to different sized int
# -Wreturn-type - catches missing returns, zero false positives
# -Wsequence-point - catches undefined order behavior like `a = a++`
# -Wsign-compare - catches comparison of signed and unsigned types
# -Wtrigraphs - catches unlikely use of trigraphs
# -Wtype-limits - catches overflow bugs, few false positives
# -Wunknown-pragmas - catches unexpected #pragma directives
#
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wempty-body"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wpointer-to-int-cast"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wsign-compare"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wignored-qualifiers"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wpointer-arith"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits"
# Treat some warnings as errors if --enable-warnings-as-errors:
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=char-subscripts"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=comment"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=endif-labels"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=enum-compare"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=ignored-qualifiers"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=multichar"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=nonnull"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-arith"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-sign"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=return-type"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=uninitialized"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas"
MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_werror_non_literal_null_conversion)
MOZ_C_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_c_has_sometimes_uninitialized)
fi
# Turn off the following warnings that -Wall turns on:
# -Wno-unused - lots of violations in third-party code
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
# -Wclass-varargs - catches objects passed by value to variadic functions.
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wsometimes-initialized - catches some uninitialized values
# -Wunreachable-code-aggressive - catches lots of dead code
#
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wno-unused"
# XXX: at the time of writing, the version of clang used on the OS X test
# machines has a bug that causes it to reject some valid files if both
# -Wnon-literal-null-conversion and -Wsometimes-uninitialized are
# specified. We work around this by instead using
# -Werror=non-literal-null-conversion, but we only do that when
# --enable-warnings-as-errors is specified so that no unexpected fatal
# warnings are produced.
MOZ_C_SUPPORTS_WARNING(-W, class-varargs, ac_c_has_wclass_varargs)
MOZ_CXX_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_cxx_has_wno_unused_local_typedef)
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_non_literal_null_conversion)
fi
MOZ_C_SUPPORTS_WARNING(-W, sometimes-uninitialized, ac_c_has_sometimes_uninitialized)
MOZ_C_SUPPORTS_WARNING(-W, unreachable-code-aggressive, ac_c_has_wunreachable_code_aggressive)
# -Wcast-align - catches problems with cast alignment
if test -z "$INTEL_CC" -a -z "$CLANG_CC"; then
# Don't use -Wcast-align with ICC or clang
case "$CPU_ARCH" in
@@ -1530,8 +1502,14 @@ if test "$GNU_CC"; then
esac
fi
# Turn off some non-useful warnings that -Wall turns on.
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
MOZ_C_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_c_has_wno_unused_local_typedef)
_DEFINES_CFLAGS='-include $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
_USE_CPP_INCLUDE_FLAG=1
ASFLAGS="$ASFLAGS $_DEFINES_CFLAGS"
elif test "$SOLARIS_SUNPRO_CC"; then
@@ -1563,65 +1541,46 @@ if test "$GNU_CXX"; then
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing"
# Turn on gcc/clang warnings:
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
#
# -Wall - turn on a lot of warnings
# https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Warning-Options.html
# -Wall - lots of useful warnings
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmissing-braces - catches aggregate initializers missing nested braces
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wignored-qualifiers - catches return types with qualifiers like const
# -Woverloaded-virtual - function declaration hides virtual function from base class
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
# -Wrange-loop-analysis - catches copies during range-based for loops.
# -Wreturn-type - catches missing returns, zero false positives
# -Wsequence-point - catches undefined order behavior like `a = a++`
# -Wsign-compare - catches comparison of signed and unsigned types
# -Wswitch - catches switches without all enum cases or default case
# -Wtrigraphs - catches unlikely use of trigraphs
# -Wtype-limits - catches overflow bugs, few false positives
# -Wunused-label - catches unused goto labels
# -Wwrite-strings - catches non-const char* pointers to string literals
#
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wempty-body"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wignored-qualifiers"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Woverloaded-virtual"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wwrite-strings"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wpointer-arith"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
# Treat some warnings as errors if --enable-warnings-as-errors:
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=parentheses"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=pointer-arith"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=switch"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=uninitialized"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
MOZ_CXX_SUPPORTS_WARNING(-Werror=, range-loop-analysis, ac_cxx_has_range_loop_analysis)
MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
fi
# Turn off the following warnings that -Wall turns on:
# -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
# -Wno-inline-new-delete - we inline 'new' and 'delete' in mozalloc
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
# for performance reasons, and because GCC and clang accept it (though
# clang warns about it).
# -Wclass-varargs - catches objects passed by value to variadic functions.
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wrange-loop-analysis - catches copies during range-based for loops.
# -Wsometimes-initialized - catches some uninitialized values
# -Wunreachable-code - catches some dead code
# -Wunreachable-code-return - catches dead code after return call
#
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
# XXX: at the time of writing, the version of clang used on the OS X test
# machines has a bug that causes it to reject some valid files if both
# -Wnon-literal-null-conversion and -Wsometimes-uninitialized are
# specified. We work around this by instead using
# -Werror=non-literal-null-conversion, but we only do that when
# --enable-warnings-as-errors is specified so that no unexpected fatal
# warnings are produced.
MOZ_CXX_SUPPORTS_WARNING(-W, class-varargs, ac_cxx_has_wclass_varargs)
MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete)
MOZ_CXX_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_cxx_has_wno_unused_local_typedef)
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_non_literal_null_conversion)
fi
MOZ_CXX_SUPPORTS_WARNING(-W, range-loop-analysis, ac_cxx_has_range_loop_analysis)
MOZ_CXX_SUPPORTS_WARNING(-W, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
MOZ_CXX_SUPPORTS_WARNING(-W, unreachable-code, ac_cxx_has_wunreachable_code)
MOZ_CXX_SUPPORTS_WARNING(-W, unreachable-code-return, ac_cxx_has_wunreachable_code_return)
# -Wcast-align - catches problems with cast alignment
if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
# Don't use -Wcast-align with ICC or clang
case "$CPU_ARCH" in
@@ -1634,8 +1593,15 @@ if test "$GNU_CXX"; then
esac
fi
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/mozilla-config.h'
_USE_CPP_INCLUDE_FLAG=1
# Turn off some non-useful warnings that -Wall turns on.
# -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
# -Wno-inline-new-delete - we inline 'new' and 'delete' in mozalloc
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete)
MOZ_CXX_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_cxx_has_wno_unused_local_typedef)
# Recent clang and gcc support C++11 deleted functions without warnings if
# compiling with -std=c++0x or -std=gnu++0x (or c++11 or gnu++11 in very new
@@ -1648,6 +1614,9 @@ if test "$GNU_CXX"; then
MOZ_CXX_SUPPORTS_WARNING(-Wno-, extended-offsetof, ac_cxx_has_wno_extended_offsetof)
fi
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(topobjdir)/mozilla-config.h'
_USE_CPP_INCLUDE_FLAG=1
else
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_MOZILLA_CONFIG_H_ $(ACDEFINES)'
fi
@@ -1696,15 +1665,6 @@ if test -n "$MOZ_USE_SYSTRACE"; then
AC_DEFINE(MOZ_USE_SYSTRACE)
fi
# For profiling builds keep the symbol information
if test "$MOZ_PROFILING" -a -z "$STRIP_FLAGS"; then
case "$OS_TARGET" in
Linux|DragonFly|FreeBSD|NetBSD|OpenBSD)
STRIP_FLAGS="--strip-debug"
;;
esac
fi
dnl ========================================================
dnl = Use Valgrind
dnl ========================================================
@@ -1768,6 +1728,38 @@ if test -n "$MOZ_VTUNE"; then
AC_DEFINE(MOZ_VTUNE)
fi
# For profiling builds keep the symbol information
if test "$MOZ_PROFILING" -a -z "$STRIP_FLAGS"; then
case "$OS_TARGET" in
Linux|DragonFly|FreeBSD|NetBSD|OpenBSD)
STRIP_FLAGS="--strip-debug"
;;
esac
fi
dnl ========================================================
dnl = Enable DMD
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(dmd,
[ --enable-dmd Enable DMD; also enables jemalloc, replace-malloc and profiling],
MOZ_DMD=1,
MOZ_DMD= )
if test "$MOZ_DMD"; then
AC_DEFINE(MOZ_DMD)
if test "${CPU_ARCH}" = "arm"; then
CFLAGS="$CFLAGS -funwind-tables"
CXXFLAGS="$CXXFLAGS -funwind-tables"
fi
MOZ_MEMORY=1 # DMD enables jemalloc
MOZ_REPLACE_MALLOC=1 # DMD enables replace-malloc
MOZ_PROFILING=1 # DMD enables profiling
fi
AC_SUBST(MOZ_DMD)
dnl ========================================================
dnl Profiling
dnl ========================================================
@@ -1792,11 +1784,6 @@ case "$host" in
HOST_NSPR_MDCPUCFG='"md/_winnt.cfg"'
HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O2}"
HOST_BIN_SUFFIX=.exe
case "$host" in
*mingw*)
PERL="/bin/sh ${_topsrcdir}/build/msys-perl-wrapper"
;;
esac
case "${host_cpu}" in
i*86)
@@ -3455,12 +3442,14 @@ AC_MSG_CHECKING([for YASM assembler])
AC_CHECK_PROGS(YASM, yasm, "")
if test -n "$YASM"; then
AC_MSG_CHECKING([yasm version])
dnl Pull out yasm's version string
YASM_VERSION=`yasm --version | $AWK '/^yasm/ { print $2 }'`
_YASM_MAJOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $1 }'`
_YASM_MINOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $2 }'`
_YASM_RELEASE=` echo ${YASM_VERSION} | $AWK -F\. '{ print $3 }'`
_YASM_BUILD=` echo ${YASM_VERSION} | $AWK -F\. '{ print $4 }'`
AC_MSG_RESULT([$YASM_VERSION (v$_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.$_YASM_RELEASE)])
fi
if test -z "$SKIP_LIBRARY_CHECKS"; then
@@ -4912,7 +4901,7 @@ AC_SUBST(MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI)
# target_arch is from {ia32|x64|arm|ppc}
case "$CPU_ARCH" in
x86_64 | arm | x86 | ppc* | ia64)
x86_64 | arm | aarch64 | x86 | ppc* | ia64)
:
;;
*)
@@ -5368,6 +5357,23 @@ if test -z "$MOZ_NATIVE_LIBVPX"; then
VPX_AS_CONVERSION='$(PERL) $(topsrcdir)/media/libvpx/build/make/ads2gas.pl'
VPX_ASM_SUFFIX="$ASM_SUFFIX"
VPX_ARM_ASM=1
dnl Building with -mfpu=neon requires either the "softfp" or the
dnl "hardfp" ABI. Depending on the compiler's default target, and the
dnl CFLAGS, the default ABI might be neither, in which case it is the
dnl "softfloat" ABI.
dnl The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
dnl we can safely mix code built with both ABIs. So, if we detect
dnl that compiling uses the "softfloat" ABI, force the use of the
dnl "softfp" ABI instead.
dnl Confusingly, the __SOFTFP__ preprocessor variable indicates the
dnl "softfloat" ABI, not the "softfp" ABI.
dnl Note: VPX_ASFLAGS is also used in CFLAGS.
AC_TRY_COMPILE([],
[#ifndef __SOFTFP__
#error "compiler target supports -mfpu=neon, so we don't have to add extra flags"
#endif],
VPX_ASFLAGS="$VPX_ASFLAGS -mfloat-abi=softfp"
)
fi
;;
*:x86)
@@ -5729,9 +5735,9 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
# Find a D3D compiler DLL in a Windows SDK.
MOZ_D3DCOMPILER_VISTA_DLL=
case "$MOZ_WINSDK_MAXVER" in
0x0603*)
0x0603*|0x0A00*)
MOZ_D3DCOMPILER_VISTA_DLL=d3dcompiler_47.dll
AC_MSG_RESULT([Found D3D compiler in Windows SDK 8.1.])
AC_MSG_RESULT([Found D3D compiler in Windows SDK.])
;;
esac
@@ -5750,6 +5756,8 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
else
AC_MSG_RESULT([Windows SDK not found.])
fi
else
AC_MSG_ERROR([Couldn't find Windows SDK 8.1 or higher needed for ANGLE.])
fi
if test -z "$MOZ_D3DCOMPILER_VISTA_DLL_PATH"; then
@@ -6900,28 +6908,6 @@ if test -n "$MOZ_DEBUG"; then
AC_DEFINE(MOZ_DUMP_PAINTING)
fi
dnl ========================================================
dnl = Enable DMD
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(dmd,
[ --enable-dmd Enable DMD; also enables jemalloc and replace-malloc],
MOZ_DMD=1,
MOZ_DMD= )
if test "$MOZ_DMD"; then
AC_DEFINE(MOZ_DMD)
if test "${CPU_ARCH}" = "arm"; then
CFLAGS="$CFLAGS -funwind-tables"
CXXFLAGS="$CXXFLAGS -funwind-tables"
fi
MOZ_MEMORY=1 # DMD enables jemalloc
MOZ_REPLACE_MALLOC=1 # DMD enables replace-malloc
fi
AC_SUBST(MOZ_DMD)
dnl ========================================================
dnl = Enable jemalloc
dnl ========================================================
@@ -7267,7 +7253,7 @@ MOZ_ARG_ENABLE_BOOL(tasktracer,
[ --enable-tasktracer Set compile flags necessary for using TaskTracer],
MOZ_TASK_TRACER=1,
MOZ_TASK_TRACER= )
if test "$MOZ_WIDGET_TOOLKIT" = "gonk" -a -n "$MOZ_TASK_TRACER"; then
if test -n "$MOZ_TASK_TRACER"; then
AC_DEFINE(MOZ_TASK_TRACER)
AC_SUBST(MOZ_TASK_TRACER)
fi
@@ -7914,7 +7900,7 @@ if test "$USE_FC_FREETYPE"; then
AC_DEFINE(HAVE_FONTCONFIG_FCFREETYPE_H)
fi
PKG_CHECK_MODULES(_FONTCONFIG, fontconfig,
PKG_CHECK_MODULES(_FONTCONFIG, fontconfig >= $FONTCONFIG_VERSION,
[
if test "$MOZ_PANGO"; then
MOZ_PANGO_CFLAGS="$MOZ_PANGO_CFLAGS $_FONTCONFIG_CFLAGS"
@@ -8531,6 +8517,7 @@ AC_SUBST(MOZ_UA_BUILDID)
AC_SUBST(MOZ_APP_STATIC_INI)
AC_SUBST(MOZ_PKG_SPECIAL)
AC_SUBST(MOZ_SIMPLE_PACKAGE_NAME)
AC_SUBST(MOZILLA_OFFICIAL)
if test "$MOZILLA_OFFICIAL"; then
@@ -8563,7 +8550,6 @@ if test -n "$MOZ_TELEMETRY_REPORTING" || test -n "$MOZ_SERVICES_HEALTHREPORT"; t
fi
dnl win32 options
AC_SUBST(MOZ_BROWSE_INFO)
AC_SUBST(WIN32_REDIST_DIR)
AC_SUBST(MAKENSISU)
@@ -8899,12 +8885,10 @@ dnl ========================================================
dnl ICU Support
dnl ========================================================
# Internationalization isn't built or exposed by default in non-desktop
# builds. Bugs to enable:
#
# Android: bug 864843
# Internationalization is not built or exposed on Fennec.
# See Bug 1215256
if test "$MOZ_WIDGET_TOOLKIT" = "android"; then
if test "$MOZ_BUILD_APP" = "mobile/android"; then
_INTL_API=no
else
_INTL_API=yes
@@ -8929,10 +8913,9 @@ MOZ_CREATE_CONFIG_STATUS()
if test "$COMPILE_ENVIRONMENT"; then
MOZ_SUBCONFIGURE_ICU()
MOZ_SUBCONFIGURE_FFI()
MOZ_SUBCONFIGURE_JEMALLOC()
fi
MOZ_SUBCONFIGURE_JEMALLOC()
# Run freetype configure script
if test "$MOZ_TREE_FREETYPE"; then
+43 -119
View File
@@ -179,72 +179,6 @@ static void AddLoadFlags(nsIRequest *request, nsLoadFlags newFlags)
request->SetLoadFlags(flags);
}
//-----------------------------------------------------------------------------
// XMLHttpRequestAuthPrompt
//-----------------------------------------------------------------------------
class XMLHttpRequestAuthPrompt : public nsIAuthPrompt
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHPROMPT
XMLHttpRequestAuthPrompt();
protected:
virtual ~XMLHttpRequestAuthPrompt();
};
NS_IMPL_ISUPPORTS(XMLHttpRequestAuthPrompt, nsIAuthPrompt)
XMLHttpRequestAuthPrompt::XMLHttpRequestAuthPrompt()
{
MOZ_COUNT_CTOR(XMLHttpRequestAuthPrompt);
}
XMLHttpRequestAuthPrompt::~XMLHttpRequestAuthPrompt()
{
MOZ_COUNT_DTOR(XMLHttpRequestAuthPrompt);
}
NS_IMETHODIMP
XMLHttpRequestAuthPrompt::Prompt(const char16_t* aDialogTitle,
const char16_t* aText,
const char16_t* aPasswordRealm,
uint32_t aSavePassword,
const char16_t* aDefaultText,
char16_t** aResult,
bool* aRetval)
{
*aRetval = false;
return NS_OK;
}
NS_IMETHODIMP
XMLHttpRequestAuthPrompt::PromptUsernameAndPassword(const char16_t* aDialogTitle,
const char16_t* aDialogText,
const char16_t* aPasswordRealm,
uint32_t aSavePassword,
char16_t** aUser,
char16_t** aPwd,
bool* aRetval)
{
*aRetval = false;
return NS_OK;
}
NS_IMETHODIMP
XMLHttpRequestAuthPrompt::PromptPassword(const char16_t* aDialogTitle,
const char16_t* aText,
const char16_t* aPasswordRealm,
uint32_t aSavePassword,
char16_t** aPwd,
bool* aRetval)
{
*aRetval = false;
return NS_OK;
}
/////////////////////////////////////////////
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
@@ -2930,6 +2864,10 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
mChannel->SetNotificationCallbacks(this);
if (internalHttpChannel) {
internalHttpChannel->SetBlockAuthPrompt(ShouldBlockAuthPrompt());
}
// Start reading from the channel
// Because of bug 682305, we can't let listener be the XHR object itself
// because JS wouldn't be able to use it. So create a listener around 'this'.
@@ -3543,59 +3481,6 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
}
else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
nsCOMPtr<nsIURI> uri;
rv = mChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// Verify that it's ok to prompt for credentials here, per spec
// http://xhr.spec.whatwg.org/#the-send%28%29-method
bool showPrompt = true;
// If authentication fails, XMLHttpRequest origin and
// the request URL are same origin, ...
/* Disabled - bug: 799540
if (IsCrossSiteCORSRequest()) {
showPrompt = false;
}
*/
// ... Authorization is not in the list of author request headers, ...
if (showPrompt) {
for (uint32_t i = 0, len = mModifiedRequestHeaders.Length(); i < len; ++i) {
if (mModifiedRequestHeaders[i].header.
LowerCaseEqualsLiteral("authorization")) {
showPrompt = false;
break;
}
}
}
// ... request username is null, and request password is null,
if (showPrompt) {
nsCString username;
rv = uri->GetUsername(username);
NS_ENSURE_SUCCESS(rv, rv);
nsCString password;
rv = uri->GetPassword(password);
NS_ENSURE_SUCCESS(rv, rv);
if (!username.IsEmpty() || !password.IsEmpty()) {
showPrompt = false;
}
}
// ... user agents should prompt the end user for their username and password.
if (!showPrompt) {
RefPtr<XMLHttpRequestAuthPrompt> prompt = new XMLHttpRequestAuthPrompt();
if (!prompt)
return NS_ERROR_OUT_OF_MEMORY;
return prompt->QueryInterface(aIID, aResult);
}
nsCOMPtr<nsIPromptFactory> wwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
@@ -3743,6 +3628,45 @@ nsXMLHttpRequest::EnsureXPCOMifier()
return newRef.forget();
}
bool
nsXMLHttpRequest::ShouldBlockAuthPrompt()
{
// Verify that it's ok to prompt for credentials here, per spec
// http://xhr.spec.whatwg.org/#the-send%28%29-method
for (uint32_t i = 0, len = mModifiedRequestHeaders.Length(); i < len; ++i) {
if (mModifiedRequestHeaders[i].header.
LowerCaseEqualsLiteral("authorization")) {
return true;
}
}
nsCOMPtr<nsIURI> uri;
nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
// Also skip if a username and/or password is provided in the URI.
nsCString username;
rv = uri->GetUsername(username);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
nsCString password;
rv = uri->GetPassword(password);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!username.IsEmpty() || !password.IsEmpty()) {
return true;
}
return false;
}
NS_IMPL_ISUPPORTS(nsXMLHttpRequest::nsHeaderVisitor, nsIHttpHeaderVisitor)
NS_IMETHODIMP nsXMLHttpRequest::
+2
View File
@@ -799,6 +799,8 @@ protected:
void ResetResponse();
bool ShouldBlockAuthPrompt();
struct RequestHeader
{
nsCString header;
-1
View File
@@ -400,7 +400,6 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g(clipboard unde
[test_bug276037-1.html]
[test_bug276037-2.xhtml]
[test_bug282547.html]
skip-if = e10s
[test_bug28293.html]
[test_bug28293.xhtml]
[test_bug298064.html]
+5
View File
@@ -1405,6 +1405,11 @@ DOMInterfaces = {
'headerFile': 'WebGLExtensions.h'
},
'WEBGL_compressed_texture_es3': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureES3',
'headerFile': 'WebGLExtensions.h'
},
'WEBGL_compressed_texture_pvrtc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTexturePVRTC',
'headerFile': 'WebGLExtensions.h'
-1
View File
@@ -2,7 +2,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/.
abs_dist := $(abspath $(DIST))
webidl_base := $(topsrcdir)/dom/webidl
# Generated by moz.build
+1
View File
@@ -189,6 +189,7 @@ class WebGLContext
friend class WebGL2Context;
friend class WebGLContextUserData;
friend class WebGLExtensionCompressedTextureATC;
friend class WebGLExtensionCompressedTextureES3;
friend class WebGLExtensionCompressedTextureETC1;
friend class WebGLExtensionCompressedTexturePVRTC;
friend class WebGLExtensionCompressedTextureS3TC;
+6
View File
@@ -47,6 +47,7 @@ WebGLContext::GetExtensionString(WebGLExtensionID ext)
WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_atc)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_es3)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc1)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_pvrtc)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc)
@@ -199,6 +200,8 @@ WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
switch (ext) {
case WebGLExtensionID::EXT_disjoint_timer_query:
return WebGLExtensionDisjointTimerQuery::IsSupported(this);
case WebGLExtensionID::WEBGL_compressed_texture_es3:
return gl->IsExtensionSupported(gl::GLContext::ARB_ES3_compatibility);
default:
// For warnings-as-errors.
@@ -377,6 +380,9 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
case WebGLExtensionID::WEBGL_compressed_texture_atc:
obj = new WebGLExtensionCompressedTextureATC(this);
break;
case WebGLExtensionID::WEBGL_compressed_texture_es3:
obj = new WebGLExtensionCompressedTextureES3(this);
break;
case WebGLExtensionID::WEBGL_compressed_texture_etc1:
obj = new WebGLExtensionCompressedTextureETC1(this);
break;
@@ -0,0 +1,55 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLExtensions.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
#ifdef FOO
#error FOO is already defined! We use FOO() macros to keep things succinct in this file.
#endif
namespace mozilla {
WebGLExtensionCompressedTextureES3::WebGLExtensionCompressedTextureES3(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275
const auto fnAdd = [&webgl_](GLenum sizedFormat, webgl::EffectiveFormat effFormat) {
auto& fua = webgl_->mFormatUsage;
auto usage = fua->EditUsage(effFormat);
usage->isFilterable = true;
fua->AllowSizedTexFormat(sizedFormat, usage);
webgl_->mCompressedTextureFormats.AppendElement(sizedFormat);
};
#define FOO(x) LOCAL_GL_ ## x, webgl::EffectiveFormat::x
fnAdd(FOO(COMPRESSED_R11_EAC));
fnAdd(FOO(COMPRESSED_SIGNED_R11_EAC));
fnAdd(FOO(COMPRESSED_RG11_EAC));
fnAdd(FOO(COMPRESSED_SIGNED_RG11_EAC));
fnAdd(FOO(COMPRESSED_RGB8_ETC2));
fnAdd(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2));
fnAdd(FOO(COMPRESSED_RGBA8_ETC2_EAC));
// sRGB support is manadatory in GL 4.3 and GL ES 3.0, which are the only
// versions to support ETC2.
fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC));
fnAdd(FOO(COMPRESSED_SRGB8_ETC2));
fnAdd(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2));
#undef FOO
}
WebGLExtensionCompressedTextureES3::~WebGLExtensionCompressedTextureES3()
{
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureES3, WEBGL_compressed_texture_es3)
} // namespace mozilla
+10
View File
@@ -71,6 +71,16 @@ public:
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureES3
: public WebGLExtensionBase
{
public:
explicit WebGLExtensionCompressedTextureES3(WebGLContext*);
virtual ~WebGLExtensionCompressedTextureES3();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureETC1
: public WebGLExtensionBase
{
+1
View File
@@ -8,6 +8,7 @@
#include <map>
#include <set>
#include <string>
#include <vector>
#include "mozilla/LinkedList.h"
+1
View File
@@ -149,6 +149,7 @@ enum class WebGLExtensionID : uint8_t {
OES_vertex_array_object,
WEBGL_color_buffer_float,
WEBGL_compressed_texture_atc,
WEBGL_compressed_texture_es3,
WEBGL_compressed_texture_etc1,
WEBGL_compressed_texture_pvrtc,
WEBGL_compressed_texture_s3tc,
+1
View File
@@ -101,6 +101,7 @@ UNIFIED_SOURCES += [
'WebGLExtensionColorBufferFloat.cpp',
'WebGLExtensionColorBufferHalfFloat.cpp',
'WebGLExtensionCompressedTextureATC.cpp',
'WebGLExtensionCompressedTextureES3.cpp',
'WebGLExtensionCompressedTextureETC1.cpp',
'WebGLExtensionCompressedTexturePVRTC.cpp',
'WebGLExtensionCompressedTextureS3TC.cpp',
+2
View File
@@ -4,6 +4,7 @@ skip-if = ((os == 'linux') && (buildapp == 'b2g'))
support-files =
webgl-mochitest/driver-info.js
webgl-mochitest/es3-data.js
webgl-mochitest/webgl-util.js
[webgl-mochitest/test_backbuffer_channels.html]
@@ -33,6 +34,7 @@ skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests
# We haven't cleaned up the Try results yet, but let's get this on the books first.
[webgl-mochitest/test_webgl_conformance.html]
skip-if = buildapp == 'mulet' || toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
[webgl-mochitest/test_webgl_compressed_texture_es3.html]
[webgl-mochitest/test_webgl_disjoint_timer_query.html]
[webgl-mochitest/test_webgl_request_context.html]
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,753 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<script src="webgl-util.js"></script>
<script src="es3-data.js"></script>
<title>WebGL test: test WEBGL_compressed_texture_es3 extension</title>
<style>
img {
border: 1px solid black;
margin-right: 1em;
}
.testimages {
}
.testimages br {
clear: both;
}
.testimages > div {
float: left;
margin: 1em;
}
</style>
</head>
<body>
<div id="description"></div>
<canvas id="canvas" width="8" height="8"></canvas>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
varying vec2 texCoord;
void main() {
gl_Position = vPosition;
texCoord = texCoord0;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
gl_FragData[0] = texture2D(tex, texCoord);
}
</script>
<script id="fshader-r" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
vec4 pixel = (texture2D(tex, texCoord));
pixel.r = (pixel.r + 1.0) / 2.0;
gl_FragData[0] = pixel;
}
</script>
<script id="fshader-rg" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
vec4 pixel = (texture2D(tex, texCoord));
pixel.rg = (pixel.rg + 1.0) / 2.0;
gl_FragData[0] = pixel;
}
</script>
<script>
"use strict";
var ext = null;
var vao = null;
var gl = null;
var validFormats = {
COMPRESSED_R11_EAC : 0x9270,
COMPRESSED_SIGNED_R11_EAC : 0x9271,
COMPRESSED_RG11_EAC : 0x9272,
COMPRESSED_SIGNED_RG11_EAC : 0x9273,
COMPRESSED_RGB8_ETC2 : 0x9274,
COMPRESSED_SRGB8_ETC2 : 0x9275,
COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9276,
COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9277,
COMPRESSED_RGBA8_ETC2_EAC : 0x9278,
COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : 0x9279,
};
var name;
var supportedFormats;
function setupUnitQuad() {
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
}
function runTest() {
gl = WebGLUtil.getWebGL("canvas", false, {antialias: false});
if (!gl) {
ok(false, "WebGL context does not exist");
} else {
ok(true, "WebGL context exists");
setupUnitQuad();
// Run tests with extension disabled
runTestDisabled();
// Query the extension and store globally so shouldBe can access it
ext = gl.getExtension("WEBGL_compressed_texture_es3");
if (!ext) {
ok(true, "No WEBGL_compressed_texture_es3 support -- this is legal");
runSupportedTest(false);
} else {
ok(true, "Successfully enabled WEBGL_compressed_texture_es3 extension");
runSupportedTest(true);
runTestExtension();
}
}
SimpleTest.finish();
}
function runSupportedTest(extensionEnabled) {
var supported = gl.getSupportedExtensions();
if (supported.indexOf("WEBGL_compressed_texture_es3") >= 0) {
if (extensionEnabled) {
ok(true, "WEBGL_compressed_texture_es3 listed as supported and getExtension succeeded");
} else {
ok(false, "WEBGL_compressed_texture_es3 listed as supported but getExtension failed");
}
} else {
if (extensionEnabled) {
ok(false, "WEBGL_compressed_texture_es3 not listed as supported but getExtension succeeded");
} else {
ok(true, "WEBGL_compressed_texture_es3 not listed as supported and getExtension failed -- this is legal");
}
}
}
function runTestDisabled() {
is(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS).length, 0,
"Should be no compressed texture formats");
}
function formatExists(format, supportedFormats) {
for (var ii = 0; ii < supportedFormats.length; ++ii) {
if (format == supportedFormats[ii]) {
ok(true, "supported format " + formatToString(format) + " is exists");
return;
}
}
ok(false, "supported format " + formatToString(format) + " does not exist");
}
function formatToString(format) {
for (var p in ext) {
if (ext[p] == format) {
return p;
}
}
return "0x" + format.toString(16);
}
function runTestExtension() {
// check that all format enums exist.
for (name in validFormats) {
is(ext[name], validFormats[name], "format is match");
}
supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
// There should be exactly 10 formats
is(supportedFormats.length, 10, "Should be exactly 10 formats");
// check that all 10 formats exist
for (var name in validFormats.length) {
formatExists(validFormats[name], supportedFormats);
}
// Test each format
testETC2_RGB();
}
function testETC2_RGB() {
var tests = [
{
width: 4,
height: 4,
channels: 1,
data: img_4x4_r11_eac,
format: ext.COMPRESSED_R11_EAC
},
{
width: 4,
height: 4,
channels: 1,
data: img_4x4_signed_r11_eac,
format: ext.COMPRESSED_SIGNED_R11_EAC
},
{
width: 4,
height: 4,
channels: 2,
data: img_4x4_rg11_eac,
format: ext.COMPRESSED_RG11_EAC
},
{
width: 4,
height: 4,
channels: 2,
data: img_4x4_signed_rg11_eac,
format: ext.COMPRESSED_SIGNED_RG11_EAC
},
{
width: 4,
height: 4,
channels: 3,
data: img_4x4_rgb_etc2,
format: ext.COMPRESSED_RGB8_ETC2
},
{
width: 4,
height: 4,
channels: 3,
data: img_4x4_rgb_etc2,
format: ext.COMPRESSED_SRGB8_ETC2
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgb_punchthrough_etc2,
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgb_punchthrough_etc2,
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgba_etc2,
format: ext.COMPRESSED_RGBA8_ETC2_EAC
},
{
width: 4,
height: 4,
channels: 4,
data: img_4x4_rgba_etc2,
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
},
{
width: 8,
height: 8,
channels: 1,
data: img_8x8_r11_eac,
format: ext.COMPRESSED_R11_EAC
},
{
width: 8,
height: 8,
channels: 1,
data: img_8x8_signed_r11_eac,
format: ext.COMPRESSED_SIGNED_R11_EAC
},
{
width: 8,
height: 8,
channels: 2,
data: img_8x8_rg11_eac,
format: ext.COMPRESSED_RG11_EAC
},
{
width: 8,
height: 8,
channels: 2,
data: img_8x8_signed_rg11_eac,
format: ext.COMPRESSED_SIGNED_RG11_EAC
},
{
width: 8,
height: 8,
channels: 3,
data: img_8x8_rgb_etc2,
format: ext.COMPRESSED_RGB8_ETC2
},
{
width: 8,
height: 8,
channels: 3,
data: img_8x8_rgb_etc2,
format: ext.COMPRESSED_SRGB8_ETC2
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgb_punchthrough_etc2,
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgb_punchthrough_etc2,
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgba_etc2,
format: ext.COMPRESSED_RGBA8_ETC2_EAC
},
{
width: 8,
height: 8,
channels: 4,
data: img_8x8_rgba_etc2,
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
},
{
width: 32,
height: 32,
channels: 1,
data: img_32x32_r11_eac,
format: ext.COMPRESSED_R11_EAC
},
{
width: 32,
height: 32,
channels: 1,
data: img_32x32_signed_r11_eac,
format: ext.COMPRESSED_SIGNED_R11_EAC
},
{
width: 32,
height: 32,
channels: 2,
data: img_32x32_rg11_eac,
format: ext.COMPRESSED_RG11_EAC
},
{
width: 32,
height: 32,
channels: 2,
data: img_32x32_signed_rg11_eac,
format: ext.COMPRESSED_SIGNED_RG11_EAC
},
{
width: 32,
height: 32,
channels: 3,
data: img_32x32_rgb_etc2,
format: ext.COMPRESSED_RGB8_ETC2
},
{
width: 32,
height: 32,
channels: 3,
data: img_32x32_rgb_etc2,
format: ext.COMPRESSED_SRGB8_ETC2
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgb_punchthrough_etc2,
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgb_punchthrough_etc2,
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgba_etc2,
format: ext.COMPRESSED_RGBA8_ETC2_EAC
},
{
width: 32,
height: 32,
channels: 4,
data: img_32x32_rgba_etc2,
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
},
];
testETCTextures(tests);
}
function testETCTextures(tests) {
for (var ii = 0; ii < tests.length; ++ii) {
testETCTexture(tests[ii]);
}
}
/* Return the size of block in bytes */
function getBlockSize(format) {
switch (format) {
case ext.COMPRESSED_R11_EAC:
case ext.COMPRESSED_SIGNED_R11_EAC:
case ext.COMPRESSED_RGB8_ETC2:
case ext.COMPRESSED_SRGB8_ETC2:
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
return 8;
case ext.COMPRESSED_RG11_EAC:
case ext.COMPRESSED_SIGNED_RG11_EAC:
case ext.COMPRESSED_RGBA8_ETC2_EAC:
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
return 16
}
}
function copyRect(data, srcX, srcY, dstX, dstY, width, height, stride) {
var bytesPerLine = width * 4;
var srcOffset = srcX * 4 + srcY * stride;
var dstOffset = dstX * 4 + dstY * stride;
for (var jj = height; jj > 0; --jj) {
for (var ii = 0; ii < bytesPerLine; ++ii) {
data[dstOffset + ii] = data[srcOffset + ii];
}
srcOffset += stride;
dstOffset += stride;
}
}
function testETCTexture(test) {
var data = new Uint8Array(test.data.compressed);
var width = test.width;
var height = test.height;
var format = test.format;
var uncompressedData = new Uint8Array(test.data.decompressed);
var glErrorShouldBe = (gl, glError, msg) => {
msg = msg || "";
var err = gl.getError();
var getGLErrorAsString = err => {
if (err === gl.NO_ERROR) {
return "NO_ERROR";
}
for (var name in gl) {
if (gl[name] === err) {
return name;
}
}
return err.toString();
}
if (err != glError) {
ok(false, "getError expected: " + getGLErrorAsString(glError) +
". Was " + getGLErrorAsString(err) + " : " + msg);
} else {
ok(true, "getError was expected value: " +
getGLErrorAsString(glError) + " : " + msg);
}
};
canvas.width = width;
canvas.height = height;
gl.viewport(0, 0, width, height);
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.generateMipmap(gl.TEXTURE_2D);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
if (format == ext.COMPRESSED_SIGNED_R11_EAC) {
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-r');
} else if (format == ext.COMPRESSED_SIGNED_RG11_EAC) {
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-rg');
} else {
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader');
}
gl.bindAttribLocation(program, 0, 'vPosition');
gl.bindAttribLocation(program, 1, 'texCoord0');
gl.useProgram(program);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width + 4, height, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height + 4, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 4, height, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 4, 0, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
if (width == 4) {
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
}
if (height == 4) {
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
}
// pick a wrong format that uses the same amount of data.
var wrongFormat;
switch (format) {
case ext.COMPRESSED_R11_EAC:
wrongFormat = ext.COMPRESSED_SIGNED_R11_EAC;
break;
case ext.COMPRESSED_SIGNED_R11_EAC:
wrongFormat = ext.COMPRESSED_R11_EAC;
break;
case ext.COMPRESSED_RG11_EAC:
wrongFormat = ext.COMPRESSED_SIGNED_RG11_EAC;
break;
case ext.COMPRESSED_SIGNED_RG11_EAC:
wrongFormat = ext.COMPRESSED_RG11_EAC;
break;
case ext.COMPRESSED_RGB8_ETC2:
wrongFormat = ext.COMPRESSED_SRGB8_ETC2;
break;
case ext.COMPRESSED_SRGB8_ETC2:
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
break;
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
break;
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
break;
case ext.COMPRESSED_RGBA8_ETC2_EAC:
wrongFormat = ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
break;
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
wrongFormat = ext.COMPRESSED_RGBA8_ETC2_EAC;
break;
}
// Restore original texture.
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "format does not match");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width + 4, height, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height + 4, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 4, height, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 4, format, data);
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 1, height, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 2, height, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 1, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 2, format, data);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
var subData = new Uint8Array(data.buffer, 0, getBlockSize(format));
if (width == 8 && height == 8) {
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 0, 4, 4, format, subData);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 4, 4, format, subData);
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
}
if (width < 32 && height < 32) {
var stride = width * 4;
for (var yoff = 0; yoff < height; yoff += 4) {
for (var xoff = 0; xoff < width; xoff += 4) {
copyRect(uncompressedData, 0, 0, xoff, yoff, 4, 4, stride);
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, xoff, yoff, 4, 4, format, subData);
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
}
}
}
}
function insertImg(element, caption, img) {
var div = document.createElement("div");
div.appendChild(img);
var label = document.createElement("div");
label.appendChild(document.createTextNode(caption));
div.appendChild(label);
element.appendChild(div);
}
function convertToSRGB(val) {
var norm = val / 255.0;
var res = 0;
if (norm <= 0.04045) {
res = norm / 12.92;
} else {
res = Math.pow(((norm + 0.055)/1.055), 2.4);
}
return res * 255.0;
}
function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) {
var scale = 8;
var c = document.createElement("canvas");
c.width = imageWidth * scale;
c.height = imageHeight * scale;
var ctx = c.getContext("2d");
for (var yy = 0; yy < imageHeight; ++yy) {
for (var xx = 0; xx < imageWidth; ++xx) {
var offset = (yy * dataWidth + xx) * 4;
ctx.fillStyle = "rgba(" +
data[offset + 0] + "," +
data[offset + 1] + "," +
data[offset + 2] + "," +
(alpha ? data[offset + 3] / 255 : 1) + ")";
ctx.fillRect(xx * scale, yy * scale, scale, scale);
}
}
var img = document.createElement("img");
img.src = c.toDataURL();
return img;
}
function compareRect(actualWidth, actualHeight, actualChannels,
dataWidth, dataHeight, expectedData,
testData, testFormat)
{
var actual = new Uint8Array(actualWidth * actualHeight * 4);
gl.readPixels(
0, 0, actualWidth, actualHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
var div = document.createElement("div");
div.className = "testimages";
var hasAlpha = actualChannels == 4;
var imgExpected = makeImage(actualWidth, actualHeight, dataWidth, expectedData, hasAlpha);
var imgActual = makeImage(actualWidth, actualHeight, actualWidth, actual, hasAlpha);
insertImg(div, "expected", imgExpected);
insertImg(div, "actual", imgActual);
div.appendChild(document.createElement('br'));
document.getElementById("console").appendChild(div);
var failed = false;
for (var yy = 0; yy < actualHeight; ++yy) {
for (var xx = 0; xx < actualWidth; ++xx) {
var actualOffset = (yy * actualWidth + xx) * 4;
var expectedOffset = (yy * dataWidth + xx) * 4;
var expected = expectedData.slice(expectedOffset, expectedOffset + 4);
var maxDiffPixel = 0;
switch (testFormat) {
case ext.COMPRESSED_SRGB8_ETC2:
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
// Alpha shouldn't do conversion.
for (var i = 0; i < 3; ++i) {
expected[i] = convertToSRGB(expected[i]);
}
//fallthrough
case ext.COMPRESSED_R11_EAC:
case ext.COMPRESSED_RG11_EAC:
case ext.COMPRESSED_SIGNED_R11_EAC:
case ext.COMPRESSED_SIGNED_RG11_EAC:
// Due to floating round error, we need fuzzy test here.
var maxDiffPixel = 1;
break;
default:
var maxDiffPixel = 0;
break;
}
for (var channel = 0; channel < actualChannels; ++channel) {
var diff = Math.abs(expected[channel] - actual[actualOffset + channel]);
if (diff > maxDiffPixel) {
failed = true;
var was = actual.slice(actualOffset, actualOffset + 4).join();
ok(false, 'at (' + xx + ', ' + yy +
') expected: ' + expected.join() + ' was ' + was);
break;
}
}
}
}
if (!failed) {
ok(true, "texture rendered correctly");
}
}
var prefArrArr = [
['webgl.enable-draft-extensions', true],
];
var prefEnv = {'set': prefArrArr};
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(prefEnv, runTest);
</script>
</body>
</html>
+1 -1
View File
@@ -13,7 +13,7 @@ addon_file_name = testaddon.xpi
endif
# This is so hacky. Waiting on bug 988938.
testdir = $(abspath $(DEPTH)/_tests/xpcshell/dom/plugins/test/unit/)
testdir = $(topobjdir)/_tests/xpcshell/dom/plugins/test/unit/
addonpath = $(testdir)/$(addon_file_name)
ifdef COMPILE_ENVIRONMENT
+15
View File
@@ -827,6 +827,21 @@ interface WEBGL_compressed_texture_atc
const GLenum COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE;
};
[NoInterfaceObject]
interface WEBGL_compressed_texture_es3
{
const GLenum COMPRESSED_R11_EAC = 0x9270;
const GLenum COMPRESSED_SIGNED_R11_EAC = 0x9271;
const GLenum COMPRESSED_RG11_EAC = 0x9272;
const GLenum COMPRESSED_SIGNED_RG11_EAC = 0x9273;
const GLenum COMPRESSED_RGB8_ETC2 = 0x9274;
const GLenum COMPRESSED_SRGB8_ETC2 = 0x9275;
const GLenum COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
const GLenum COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
const GLenum COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
const GLenum COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
};
[NoInterfaceObject]
interface WEBGL_compressed_texture_etc1
{
+1 -1
View File
@@ -154,8 +154,8 @@ if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
CFLAGS += [
'-Wno-address',
'-Wno-missing-field-initializers',
'-Wno-sign-compare',
'-Wno-incompatible-pointer-types',
'-Wno-sign-compare',
'-Wno-unused', # too many unused warnings; ignore
]
if CONFIG['CLANG_CXX'] or CONFIG['CLANG_CL']:
+22 -1
View File
@@ -12,6 +12,7 @@
#include "mozilla/gfx/2D.h"
#include "ScopedGLHelpers.h"
#include "GLUploadHelpers.h"
#include "GfxTexturesReporter.h"
#include "TextureImageEGL.h"
#ifdef XP_MACOSX
@@ -95,6 +96,16 @@ gfx::IntRect TextureImage::GetSrcTileRect() {
return GetTileRect();
}
void
TextureImage::UpdateUploadSize(size_t amount)
{
if (mUploadSize > 0) {
GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryFreed, mUploadSize);
}
mUploadSize = amount;
GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryAllocated, mUploadSize);
}
BasicTextureImage::~BasicTextureImage()
{
GLContext *ctx = mGLContext;
@@ -162,16 +173,20 @@ BasicTextureImage::EndUpdate()
RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface();
bool relative = FinishedSurfaceUpdate();
size_t uploadSize;
mTextureFormat =
UploadSurfaceToTexture(mGLContext,
updateData,
mUpdateRegion,
mTexture,
&uploadSize,
mTextureState == Created,
mUpdateOffset,
relative);
FinishedSurfaceUpload();
if (uploadSize > 0) {
UpdateUploadSize(uploadSize);
}
mUpdateDrawTarget = nullptr;
mTextureState = Valid;
@@ -214,14 +229,19 @@ BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion
region = aRegion;
}
size_t uploadSize;
mTextureFormat =
UploadSurfaceToTexture(mGLContext,
aSurf,
region,
mTexture,
&uploadSize,
mTextureState == Created,
bounds.TopLeft() + IntPoint(aFrom.x, aFrom.y),
false);
if (uploadSize > 0) {
UpdateUploadSize(uploadSize);
}
mTextureState = Valid;
return true;
}
@@ -273,6 +293,7 @@ TextureImage::TextureImage(const gfx::IntSize& aSize,
, mTextureFormat(gfx::SurfaceFormat::UNKNOWN)
, mFilter(Filter::GOOD)
, mFlags(aFlags)
, mUploadSize(0)
{}
BasicTextureImage::BasicTextureImage(GLuint aTexture,
+6 -1
View File
@@ -203,6 +203,8 @@ public:
protected:
friend class GLContext;
void UpdateUploadSize(size_t amount);
/**
* After the ctor, the TextureImage is invalid. Implementations
* must allocate resources successfully before returning the new
@@ -214,7 +216,9 @@ protected:
Flags aFlags = NoFlags);
// Protected destructor, to discourage deletion outside of Release():
virtual ~TextureImage() {}
virtual ~TextureImage() {
UpdateUploadSize(0);
}
virtual gfx::IntRect GetSrcTileRect();
@@ -224,6 +228,7 @@ protected:
gfx::SurfaceFormat mTextureFormat;
gfx::Filter mFilter;
Flags mFlags;
size_t mUploadSize;
};
/**
+61 -3
View File
@@ -9,6 +9,8 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Tools.h" // For BytesPerPixel
#include "nsRegion.h"
#include "GfxTexturesReporter.h"
#include "mozilla/gfx/Logging.h"
namespace mozilla {
@@ -379,6 +381,51 @@ TexImage2DHelper(GLContext *gl,
}
}
static uint32_t
GetBytesPerTexel(GLenum format, GLenum type)
{
// If there is no defined format or type, we're not taking up any memory
if (!format || !type) {
return 0;
}
if (format == LOCAL_GL_DEPTH_COMPONENT) {
if (type == LOCAL_GL_UNSIGNED_SHORT)
return 2;
else if (type == LOCAL_GL_UNSIGNED_INT)
return 4;
} else if (format == LOCAL_GL_DEPTH_STENCIL) {
if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
return 4;
}
if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT || type == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV) {
uint32_t multiplier = type == LOCAL_GL_UNSIGNED_BYTE ? 1 : 4;
switch (format) {
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
return 1 * multiplier;
case LOCAL_GL_LUMINANCE_ALPHA:
return 2 * multiplier;
case LOCAL_GL_RGB:
return 3 * multiplier;
case LOCAL_GL_RGBA:
return 4 * multiplier;
default:
break;
}
} else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
{
return 2;
}
gfxCriticalError() << "Unknown texture type " << type << " or format " << format;
MOZ_CRASH();
return 0;
}
SurfaceFormat
UploadImageDataToTexture(GLContext* gl,
unsigned char* aData,
@@ -386,6 +433,7 @@ UploadImageDataToTexture(GLContext* gl,
SurfaceFormat aFormat,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
size_t* aOutUploadSize,
bool aOverwrite,
bool aPixelBuffer,
GLenum aTextureUnit,
@@ -505,6 +553,10 @@ UploadImageDataToTexture(GLContext* gl,
// Top left point of the region's bounding rectangle.
IntPoint topLeft = paintRegion.GetBounds().TopLeft();
if (aOutUploadSize) {
*aOutUploadSize = 0;
}
for (auto iter = paintRegion.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
// The inital data pointer is at the top left point of the region's
@@ -544,6 +596,11 @@ UploadImageDataToTexture(GLContext* gl,
rectData);
}
if (aOutUploadSize && !textureInited) {
uint32_t texelSize = GetBytesPerTexel(internalFormat, type);
size_t numTexels = size_t(rect.width) * size_t(rect.height);
*aOutUploadSize += texelSize * numTexels;
}
}
return surfaceFormat;
@@ -551,9 +608,10 @@ UploadImageDataToTexture(GLContext* gl,
SurfaceFormat
UploadSurfaceToTexture(GLContext* gl,
DataSourceSurface *aSurface,
DataSourceSurface* aSurface,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
size_t* aOutUploadSize,
bool aOverwrite,
const gfx::IntPoint& aSrcPoint,
bool aPixelBuffer,
@@ -565,8 +623,8 @@ UploadSurfaceToTexture(GLContext* gl,
SurfaceFormat format = aSurface->GetFormat();
data += DataOffset(aSrcPoint, stride, format);
return UploadImageDataToTexture(gl, data, stride, format,
aDstRegion, aTexture, aOverwrite,
aPixelBuffer, aTextureUnit,
aDstRegion, aTexture, aOutUploadSize,
aOverwrite, aPixelBuffer, aTextureUnit,
aTextureTarget);
}
+3
View File
@@ -40,6 +40,7 @@ class GLContext;
* \param aData Image data to upload.
* \param aDstRegion Region of texture to upload to.
* \param aTexture Texture to use, or 0 to have one created for you.
* \param aOutUploadSize if set, the number of bytes the texture requires will be returned here
* \param aOverwrite Over an existing texture with a new one.
* \param aSrcPoint Offset into aSrc where the region's bound's
* TopLeft() sits.
@@ -59,6 +60,7 @@ UploadImageDataToTexture(GLContext* gl,
gfx::SurfaceFormat aFormat,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
size_t* aOutUploadSize = nullptr,
bool aOverwrite = false,
bool aPixelBuffer = false,
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
@@ -72,6 +74,7 @@ UploadSurfaceToTexture(GLContext* gl,
gfx::DataSourceSurface *aSurface,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
size_t* aOutUploadSize = nullptr,
bool aOverwrite = false,
const gfx::IntPoint& aSrcPoint = gfx::IntPoint(0, 0),
bool aPixelBuffer = false,
+6 -69
View File
@@ -5,85 +5,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GfxTexturesReporter.h"
#include "GLDefs.h"
using namespace mozilla;
using namespace mozilla::gl;
NS_IMPL_ISUPPORTS(GfxTexturesReporter, nsIMemoryReporter)
Atomic<int32_t> GfxTexturesReporter::sAmount(0);
Atomic<int32_t> GfxTexturesReporter::sTileWasteAmount(0);
static uint32_t
GetBitsPerTexel(GLenum format, GLenum type)
{
// If there is no defined format or type, we're not taking up any memory
if (!format || !type) {
return 0;
}
if (format == LOCAL_GL_DEPTH_COMPONENT) {
if (type == LOCAL_GL_UNSIGNED_SHORT)
return 2*8;
else if (type == LOCAL_GL_UNSIGNED_INT)
return 4*8;
} else if (format == LOCAL_GL_DEPTH_STENCIL) {
if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
return 4*8;
}
if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
uint32_t multiplier = type == LOCAL_GL_FLOAT ? 32 : 8;
switch (format) {
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
return 1 * multiplier;
case LOCAL_GL_LUMINANCE_ALPHA:
return 2 * multiplier;
case LOCAL_GL_RGB:
return 3 * multiplier;
case LOCAL_GL_RGBA:
return 4 * multiplier;
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
return 2;
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case LOCAL_GL_ATC_RGB:
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
case LOCAL_GL_ETC1_RGB8_OES:
return 4;
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
return 8;
default:
break;
}
} else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
{
return 2*8;
}
MOZ_ASSERT(false);
return 0;
}
Atomic<size_t> GfxTexturesReporter::sAmount(0);
Atomic<size_t> GfxTexturesReporter::sTileWasteAmount(0);
/* static */ void
GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format,
GLenum type, int32_t tileWidth,
int32_t tileHeight)
GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount)
{
int64_t bitsPerTexel = GetBitsPerTexel(format, type);
int64_t bytes = int64_t(tileWidth) * int64_t(tileHeight) * bitsPerTexel/8;
if (action == MemoryFreed) {
sAmount -= bytes;
MOZ_RELEASE_ASSERT(amount <= sAmount);
sAmount -= amount;
} else {
sAmount += bytes;
sAmount += amount;
}
}
+6 -7
View File
@@ -41,10 +41,9 @@ public:
// When memory is used/freed for tile textures, call this method to update
// the value reported by this memory reporter.
static void UpdateAmount(MemoryUse action, GLenum format, GLenum type,
int32_t tileWidth, int32_t tileHeight);
static void UpdateAmount(MemoryUse action, size_t amount);
static void UpdateWasteAmount(int32_t delta) {
static void UpdateWasteAmount(size_t delta) {
sTileWasteAmount += delta;
}
@@ -52,17 +51,17 @@ public:
nsISupports* aData, bool aAnonymize) override
{
MOZ_COLLECT_REPORT("gfx-tiles-waste", KIND_OTHER, UNITS_BYTES,
sTileWasteAmount,
int64_t(sTileWasteAmount),
"Memory lost due to tiles extending past content boundaries");
return MOZ_COLLECT_REPORT(
"gfx-textures", KIND_OTHER, UNITS_BYTES, sAmount,
"gfx-textures", KIND_OTHER, UNITS_BYTES, int64_t(sAmount),
"Memory used for storing GL textures.");
}
private:
static Atomic<int32_t> sAmount;
static Atomic<size_t> sAmount;
// Count the amount of memory lost to tile waste
static Atomic<int32_t> sTileWasteAmount;
static Atomic<size_t> sTileWasteAmount;
};
class GfxTextureWasteTracker {
+5
View File
@@ -207,14 +207,19 @@ TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion&
region = aRegion;
}
size_t uploadSize = 0;
mTextureFormat =
UploadSurfaceToTexture(mGLContext,
aSurf,
region,
mTexture,
&uploadSize,
mTextureState == Created,
bounds.TopLeft() + gfx::IntPoint(aFrom.x, aFrom.y),
false);
if (uploadSize > 0) {
UpdateUploadSize(uploadSize);
}
mTextureState = Valid;
return true;
+18 -16
View File
@@ -77,7 +77,7 @@ class HashMap
// HashMap construction is fallible (due to OOM); thus the user must call
// init after constructing a HashMap and check the return value.
explicit HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {}
bool init(uint32_t len = 16) { return impl.init(len); }
MOZ_WARN_UNUSED_RESULT bool init(uint32_t len = 16) { return impl.init(len); }
bool initialized() const { return impl.initialized(); }
// Return whether the given lookup value is present in the map. E.g.:
@@ -140,19 +140,19 @@ class HashMap
}
template<typename KeyInput, typename ValueInput>
bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) {
MOZ_WARN_UNUSED_RESULT bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) {
return impl.add(p,
mozilla::Forward<KeyInput>(k),
mozilla::Forward<ValueInput>(v));
}
template<typename KeyInput>
bool add(AddPtr& p, KeyInput&& k) {
MOZ_WARN_UNUSED_RESULT bool add(AddPtr& p, KeyInput&& k) {
return impl.add(p, mozilla::Forward<KeyInput>(k), Value());
}
template<typename KeyInput, typename ValueInput>
bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) {
MOZ_WARN_UNUSED_RESULT bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) {
return impl.relookupOrAdd(p, k,
mozilla::Forward<KeyInput>(k),
mozilla::Forward<ValueInput>(v));
@@ -223,7 +223,7 @@ class HashMap
// Overwrite existing value with v. Return false on oom.
template<typename KeyInput, typename ValueInput>
bool put(KeyInput&& k, ValueInput&& v) {
MOZ_WARN_UNUSED_RESULT bool put(KeyInput&& k, ValueInput&& v) {
AddPtr p = lookupForAdd(k);
if (p) {
p->value() = mozilla::Forward<ValueInput>(v);
@@ -234,7 +234,7 @@ class HashMap
// Like put, but assert that the given key is not already present.
template<typename KeyInput, typename ValueInput>
bool putNew(KeyInput&& k, ValueInput&& v) {
MOZ_WARN_UNUSED_RESULT bool putNew(KeyInput&& k, ValueInput&& v) {
return impl.putNew(k, mozilla::Forward<KeyInput>(k), mozilla::Forward<ValueInput>(v));
}
@@ -249,7 +249,9 @@ class HashMap
AddPtr p = lookupForAdd(k);
if (p)
return p;
(void)add(p, k, defaultValue); // p is left false-y on oom.
bool ok = add(p, k, defaultValue);
MOZ_ASSERT_IF(!ok, !p); // p is left false-y on oom.
(void)ok;
return p;
}
@@ -329,7 +331,7 @@ class HashSet
// HashSet construction is fallible (due to OOM); thus the user must call
// init after constructing a HashSet and check the return value.
explicit HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {}
bool init(uint32_t len = 16) { return impl.init(len); }
MOZ_WARN_UNUSED_RESULT bool init(uint32_t len = 16) { return impl.init(len); }
bool initialized() const { return impl.initialized(); }
// Return whether the given lookup value is present in the map. E.g.:
@@ -387,12 +389,12 @@ class HashSet
AddPtr lookupForAdd(const Lookup& l) const { return impl.lookupForAdd(l); }
template <typename U>
bool add(AddPtr& p, U&& u) {
MOZ_WARN_UNUSED_RESULT bool add(AddPtr& p, U&& u) {
return impl.add(p, mozilla::Forward<U>(u));
}
template <typename U>
bool relookupOrAdd(AddPtr& p, const Lookup& l, U&& u) {
MOZ_WARN_UNUSED_RESULT bool relookupOrAdd(AddPtr& p, const Lookup& l, U&& u) {
return impl.relookupOrAdd(p, l, mozilla::Forward<U>(u));
}
@@ -461,19 +463,19 @@ class HashSet
// Add |u| if it is not present already. Return false on oom.
template <typename U>
bool put(U&& u) {
MOZ_WARN_UNUSED_RESULT bool put(U&& u) {
AddPtr p = lookupForAdd(u);
return p ? true : add(p, mozilla::Forward<U>(u));
}
// Like put, but assert that the given key is not already present.
template <typename U>
bool putNew(U&& u) {
MOZ_WARN_UNUSED_RESULT bool putNew(U&& u) {
return impl.putNew(u, mozilla::Forward<U>(u));
}
template <typename U>
bool putNew(const Lookup& l, U&& u) {
MOZ_WARN_UNUSED_RESULT bool putNew(const Lookup& l, U&& u) {
return impl.putNew(l, mozilla::Forward<U>(u));
}
@@ -1655,7 +1657,7 @@ class HashTable : private AllocPolicy
}
template <typename... Args>
bool add(AddPtr& p, Args&&... args)
MOZ_WARN_UNUSED_RESULT bool add(AddPtr& p, Args&&... args)
{
mozilla::ReentrancyGuard g(*this);
MOZ_ASSERT(table);
@@ -1718,7 +1720,7 @@ class HashTable : private AllocPolicy
// Note: |l| may be alias arguments in |args|, so this function must take
// care not to use |l| after moving |args|.
template <typename... Args>
bool putNew(const Lookup& l, Args&&... args)
MOZ_WARN_UNUSED_RESULT bool putNew(const Lookup& l, Args&&... args)
{
if (!this->checkSimulatedOOM())
return false;
@@ -1733,7 +1735,7 @@ class HashTable : private AllocPolicy
// Note: |l| may be a reference to a piece of |u|, so this function
// must take care not to use |l| after moving |u|.
template <typename... Args>
bool relookupOrAdd(AddPtr& p, const Lookup& l, Args&&... args)
MOZ_WARN_UNUSED_RESULT bool relookupOrAdd(AddPtr& p, const Lookup& l, Args&&... args)
{
#ifdef JS_DEBUG
p.generation = generation();
+138 -96
View File
@@ -918,6 +918,10 @@ ParseVarOrConstStatement(AsmJSParser& parser, ParseNode** var)
// out of range: otherwise
// Lastly, a literal may be a float literal which is any double or integer
// literal coerced with Math.fround.
//
// This class distinguishes between signed and unsigned integer SIMD types like
// Int32x4 and Uint32x4, and so does Type below. The wasm ValType and ExprType
// enums, and the wasm::Val class do not.
class NumLit
{
public:
@@ -928,6 +932,7 @@ class NumLit
Double,
Float,
Int32x4,
Uint32x4,
Float32x4,
Bool32x4,
OutOfRangeInt = -1
@@ -982,7 +987,8 @@ class NumLit
}
bool isSimd() const {
return which_ == Int32x4 || which_ == Float32x4 || which_ == Bool32x4;
return which_ == Int32x4 || which_ == Uint32x4 || which_ == Float32x4 ||
which_ == Bool32x4;
}
const SimdConstant& simdValue() const {
@@ -1006,6 +1012,7 @@ class NumLit
case NumLit::Float:
return toFloat() == 0.f && !IsNegativeZero(toFloat());
case NumLit::Int32x4:
case NumLit::Uint32x4:
return simdValue() == SimdConstant::SplatX4(0);
case NumLit::Float32x4:
return simdValue() == SimdConstant::SplatX4(0.f);
@@ -1028,6 +1035,7 @@ class NumLit
case NumLit::Double:
return Val(toDouble());
case NumLit::Int32x4:
case NumLit::Uint32x4:
return Val(simdValue().asInt32x4());
case NumLit::Float32x4:
return Val(simdValue().asFloat32x4());
@@ -1063,6 +1071,7 @@ class Type
DoubleLit = NumLit::Double,
Float = NumLit::Float,
Int32x4 = NumLit::Int32x4,
Uint32x4 = NumLit::Uint32x4,
Float32x4 = NumLit::Float32x4,
Bool32x4 = NumLit::Bool32x4,
Double,
@@ -1083,6 +1092,7 @@ class Type
MOZ_IMPLICIT Type(SimdType type) {
switch (type) {
case SimdType::Int32x4: which_ = Int32x4; return;
case SimdType::Uint32x4: which_ = Uint32x4; return;
case SimdType::Float32x4: which_ = Float32x4; return;
case SimdType::Bool32x4: which_ = Bool32x4; return;
default: break;
@@ -1090,35 +1100,6 @@ class Type
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad SimdType");
}
static Type var(ValType t) {
switch (t) {
case ValType::I32: return Int;
case ValType::I64: MOZ_CRASH("no int64 in asm.js");
case ValType::F32: return Float;
case ValType::F64: return Double;
case ValType::I32x4: return Int32x4;
case ValType::F32x4: return Float32x4;
case ValType::B32x4: return Bool32x4;
case ValType::Limit: break;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type");
}
static Type ret(ExprType t) {
switch (t) {
case ExprType::Void: return Type::Void;
case ExprType::I32: return Signed;
case ExprType::I64: MOZ_CRASH("no int64 in asm.js");
case ExprType::F32: return Float;
case ExprType::F64: return Double;
case ExprType::I32x4: return Int32x4;
case ExprType::F32x4: return Float32x4;
case ExprType::B32x4: return Bool32x4;
case ExprType::Limit: break;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type");
}
// Map an already canonicalized Type to the return type of a function call.
static Type ret(Type t) {
MOZ_ASSERT(t.isCanonical());
@@ -1156,6 +1137,7 @@ class Type
return Void;
case Int32x4:
case Uint32x4:
case Float32x4:
case Bool32x4:
return t;
@@ -1184,6 +1166,7 @@ class Type
case Double: return isDouble();
case Float: return isFloat();
case Int32x4: return isInt32x4();
case Uint32x4: return isUint32x4();
case Float32x4: return isFloat32x4();
case Bool32x4: return isBool32x4();
case MaybeDouble: return isMaybeDouble();
@@ -1253,6 +1236,10 @@ class Type
return which_ == Int32x4;
}
bool isUint32x4() const {
return which_ == Uint32x4;
}
bool isFloat32x4() const {
return which_ == Float32x4;
}
@@ -1262,17 +1249,27 @@ class Type
}
bool isSimd() const {
return isInt32x4() || isFloat32x4() || isBool32x4();
return isInt32x4() || isUint32x4() || isFloat32x4() || isBool32x4();
}
bool isUnsignedSimd() const {
return isUint32x4();
}
// Check if this is one of the valid types for a function argument.
bool isArgType() const {
return isInt() || isFloat() || isDouble() || isSimd();
return isInt() || isFloat() || isDouble() || (isSimd() && !isUnsignedSimd());
}
// Check if this is one of the valid types for a function return value.
bool isReturnType() const {
return isSigned() || isFloat() || isDouble() || isSimd() || isVoid();
return isSigned() || isFloat() || isDouble() || (isSimd() && !isUnsignedSimd()) ||
isVoid();
}
// Check if this is one of the valid types for a global variable.
bool isGlobalVarType() const {
return isArgType();
}
// Check if this is one of the canonical vartype representations of a
@@ -1301,6 +1298,7 @@ class Type
case Float: return ExprType::F32;
case Double: return ExprType::F64;
case Void: return ExprType::Void;
case Uint32x4:
case Int32x4: return ExprType::I32x4;
case Float32x4: return ExprType::F32x4;
case Bool32x4: return ExprType::B32x4;
@@ -1327,6 +1325,7 @@ class Type
case Unsigned: return "unsigned";
case Intish: return "intish";
case Int32x4: return "int32x4";
case Uint32x4: return "uint32x4";
case Float32x4: return "float32x4";
case Bool32x4: return "bool32x4";
case Void: return "void";
@@ -1830,11 +1829,13 @@ class MOZ_STACK_CLASS ModuleValidator
MOZ_ASSERT(n->isTenured());
module_->bufferArgumentName = n;
}
bool addGlobalVarInit(PropertyName* var, const NumLit& lit, bool isConst) {
bool addGlobalVarInit(PropertyName* var, const NumLit& lit, Type type, bool isConst)
{
MOZ_ASSERT(type.isGlobalVarType());
MOZ_ASSERT(type == Type::canonicalize(Type::lit(lit)));
uint32_t index;
Type litType = Type::lit(lit);
Type canonicalType = Type::canonicalize(litType);
if (!mg_.allocateGlobalVar(canonicalType.canonicalToValType(), isConst, &index))
if (!mg_.allocateGlobalVar(type.canonicalToValType(), isConst, &index))
return false;
Global::Which which = isConst ? Global::ConstantLiteral : Global::Variable;
@@ -1842,7 +1843,7 @@ class MOZ_STACK_CLASS ModuleValidator
if (!global)
return false;
global->u.varOrConst.index_ = index;
global->u.varOrConst.type_ = (isConst ? litType : canonicalType).which();
global->u.varOrConst.type_ = (isConst ? Type::lit(lit) : type).which();
if (isConst)
global->u.varOrConst.literalValue_ = lit;
if (!globalMap_.putNew(var, global))
@@ -1854,9 +1855,12 @@ class MOZ_STACK_CLASS ModuleValidator
g.pod.u.var.globalDataOffset_ = mg_.globalVar(index).globalDataOffset;
return module_->globals.append(g);
}
bool addGlobalVarImport(PropertyName* var, PropertyName* field, ValType type, bool isConst) {
bool addGlobalVarImport(PropertyName* var, PropertyName* field, Type type, bool isConst) {
MOZ_ASSERT(type.isGlobalVarType());
uint32_t index;
if (!mg_.allocateGlobalVar(type, isConst, &index))
ValType valType = type.canonicalToValType();
if (!mg_.allocateGlobalVar(valType, isConst, &index))
return false;
Global::Which which = isConst ? Global::ConstantImport : Global::Variable;
@@ -1864,13 +1868,13 @@ class MOZ_STACK_CLASS ModuleValidator
if (!global)
return false;
global->u.varOrConst.index_ = index;
global->u.varOrConst.type_ = Type::var(type).which();
global->u.varOrConst.type_ = type.which();
if (!globalMap_.putNew(var, global))
return false;
AsmJSGlobal g(AsmJSGlobal::Variable, field);
g.pod.u.var.initKind_ = AsmJSGlobal::InitImport;
g.pod.u.var.u.importType_ = type;
g.pod.u.var.u.importType_ = valType;
g.pod.u.var.globalDataOffset_ = mg_.globalVar(index).globalDataOffset;
return module_->globals.append(g);
}
@@ -2369,6 +2373,7 @@ IsSimdLiteral(ModuleValidator& m, ParseNode* pn)
uint32_t _;
switch (type) {
case SimdType::Int32x4:
case SimdType::Uint32x4:
case SimdType::Bool32x4:
if (!IsLiteralInt(m, arg, &_))
return false;
@@ -2425,7 +2430,8 @@ ExtractSimdValue(ModuleValidator& m, ParseNode* pn)
ParseNode* arg = CallArgList(pn);
switch (type) {
case SimdType::Int32x4: {
case SimdType::Int32x4:
case SimdType::Uint32x4: {
MOZ_ASSERT(GetSimdLanes(type) == 4);
int32_t val[4];
for (size_t i = 0; i < 4; i++, arg = NextNode(arg)) {
@@ -2434,7 +2440,8 @@ ExtractSimdValue(ModuleValidator& m, ParseNode* pn)
val[i] = int32_t(u32);
}
MOZ_ASSERT(arg== nullptr);
return NumLit(NumLit::Int32x4, SimdConstant::CreateX4(val));
NumLit::Which w = type == SimdType::Uint32x4 ? NumLit::Uint32x4 : NumLit::Int32x4;
return NumLit(w, SimdConstant::CreateX4(val));
}
case SimdType::Float32x4: {
MOZ_ASSERT(GetSimdLanes(type) == 4);
@@ -2524,6 +2531,7 @@ IsLiteralInt(NumLit lit, uint32_t* u32)
case NumLit::Float:
case NumLit::OutOfRangeInt:
case NumLit::Int32x4:
case NumLit::Uint32x4:
case NumLit::Float32x4:
case NumLit::Bool32x4:
return false;
@@ -2751,6 +2759,7 @@ class MOZ_STACK_CLASS FunctionValidator
return encoder().writeExpr(Expr::F64Const) &&
encoder().writeFixedF64(lit.toDouble());
case NumLit::Int32x4:
case NumLit::Uint32x4:
return encoder().writeExpr(Expr::I32x4Const) &&
encoder().writeFixedI32x4(lit.simdValue().asInt32x4());
case NumLit::Float32x4:
@@ -2901,7 +2910,11 @@ CheckGlobalVariableInitConstant(ModuleValidator& m, PropertyName* varName, Parse
if (!lit.valid())
return m.fail(initNode, "global initializer is out of representable integer range");
return m.addGlobalVarInit(varName, lit, isConst);
Type canonicalType = Type::canonicalize(Type::lit(lit));
if (!canonicalType.isGlobalVarType())
return m.fail(initNode, "global variable type not allowed");
return m.addGlobalVarInit(varName, lit, canonicalType, isConst);
}
static bool
@@ -2937,12 +2950,20 @@ CheckTypeAnnotation(ModuleValidator& m, ParseNode* coercionNode, Type* coerceTo,
}
static bool
CheckGlobalVariableImportExpr(ModuleValidator& m, PropertyName* varName, ValType coerceTo,
ParseNode* coercedExpr, bool isConst)
CheckGlobalVariableInitImport(ModuleValidator& m, PropertyName* varName, ParseNode* initNode,
bool isConst)
{
Type coerceTo;
ParseNode* coercedExpr;
if (!CheckTypeAnnotation(m, initNode, &coerceTo, &coercedExpr))
return false;
if (!coercedExpr->isKind(PNK_DOT))
return m.failName(coercedExpr, "invalid import expression for global '%s'", varName);
if (!coerceTo.isGlobalVarType())
return m.fail(initNode, "global variable type not allowed");
ParseNode* base = DotBase(coercedExpr);
PropertyName* field = DotMember(coercedExpr);
@@ -2955,17 +2976,6 @@ CheckGlobalVariableImportExpr(ModuleValidator& m, PropertyName* varName, ValType
return m.addGlobalVarImport(varName, field, coerceTo, isConst);
}
static bool
CheckGlobalVariableInitImport(ModuleValidator& m, PropertyName* varName, ParseNode* initNode,
bool isConst)
{
Type coerceTo;
ParseNode* coercedExpr;
if (!CheckTypeAnnotation(m, initNode, &coerceTo, &coercedExpr))
return false;
return CheckGlobalVariableImportExpr(m, varName, coerceTo.canonicalToValType(), coercedExpr, isConst);
}
static bool
IsArrayViewCtorName(ModuleValidator& m, PropertyName* name, Scalar::Type* type)
{
@@ -3051,24 +3061,6 @@ CheckNewArrayView(ModuleValidator& m, PropertyName* varName, ParseNode* newExpr)
return m.addArrayView(varName, type, field);
}
static bool
IsSimdTypeName(ModuleValidator& m, PropertyName* name, SimdType* type)
{
if (name == m.cx()->names().Int32x4) {
*type = SimdType::Int32x4;
return true;
}
if (name == m.cx()->names().Float32x4) {
*type = SimdType::Float32x4;
return true;
}
if (name == m.cx()->names().Bool32x4) {
*type = SimdType::Bool32x4;
return true;
}
return false;
}
static bool
IsSimdValidOperationType(SimdType type, SimdOperation op)
{
@@ -3076,27 +3068,39 @@ IsSimdValidOperationType(SimdType type, SimdOperation op)
switch(type) {
case SimdType::Int32x4:
switch (op) {
case SimdOperation::Constructor:
case SimdOperation::Fn_fromUint32x4Bits:
FORALL_INT32X4_ASMJS_OP(CASE) return true;
default: return false;
}
break;
case SimdType::Uint32x4:
switch (op) {
case SimdOperation::Constructor:
case SimdOperation::Fn_fromInt32x4Bits:
FORALL_INT32X4_ASMJS_OP(CASE) return true;
default: return false;
}
break;
case SimdType::Float32x4:
switch (op) {
case SimdOperation::Constructor:
FORALL_FLOAT32X4_ASMJS_OP(CASE) return true;
default: return false;
}
break;
case SimdType::Bool32x4:
switch (op) {
case SimdOperation::Constructor:
FORALL_BOOL_SIMD_OP(CASE) return true;
default: return false;
}
break;
default:
break;
// Unimplemented SIMD type.
return false;
}
#undef CASE
MOZ_CRASH("Unhandles SIMD type");
}
static bool
@@ -3140,8 +3144,17 @@ CheckGlobalSimdImport(ModuleValidator& m, ParseNode* initNode, PropertyName* var
// SIMD constructor, with the form glob.SIMD.[[type]]
SimdType simdType;
if (!IsSimdTypeName(m, field, &simdType))
if (!IsSimdTypeName(m.cx()->names(), field, &simdType))
return m.failName(initNode, "'%s' is not a standard SIMD type", field);
// IsSimdTypeName will return true for any SIMD type supported by the VM.
//
// Since we may not support all of those SIMD types in asm.js, use the
// asm.js-specific IsSimdValidOperationType() to check if this specific
// constructor is supported in asm.js.
if (!IsSimdValidOperationType(simdType, SimdOperation::Constructor))
return m.failName(initNode, "'%s' is not a supported SIMD type", field);
return m.addSimdCtor(varName, simdType, field);
}
@@ -3313,6 +3326,9 @@ CheckArgumentType(FunctionValidator& f, ParseNode* stmt, PropertyName* name, Typ
if (!CheckTypeAnnotation(f.m(), coercionNode, type, &coercedExpr))
return false;
if (!type->isArgType())
return f.failName(stmt, "invalid type for argument '%s'", name);
if (!IsUseOfName(coercedExpr, name))
return ArgFail(f, name, stmt);
@@ -3591,6 +3607,14 @@ static bool
CheckAndPrepareArrayAccess(FunctionValidator& f, ParseNode* viewName, ParseNode* indexExpr,
Scalar::Type* viewType, int32_t* mask)
{
// asm.js doesn't have constant offsets, so just encode a 0.
if (!f.encoder().writeVarU32(0))
return false;
size_t alignAt;
if (!f.encoder().writePatchableVarU8(&alignAt))
return false;
size_t prepareAt;
if (!f.encoder().writePatchableExpr(&prepareAt))
return false;
@@ -3598,6 +3622,9 @@ CheckAndPrepareArrayAccess(FunctionValidator& f, ParseNode* viewName, ParseNode*
if (!CheckArrayAccess(f, viewName, indexExpr, viewType, mask))
return false;
// asm.js only has naturally-aligned accesses.
f.encoder().patchVarU8(alignAt, TypedArrayElemSize(*viewType));
// Don't generate the mask op if there is no need for it which could happen for
// a shift of zero or a SIMD access.
if (*mask != NoMask) {
@@ -4244,14 +4271,14 @@ CheckSignatureAgainstExisting(ModuleValidator& m, ParseNode* usepn, const Sig& s
for (unsigned i = 0; i < sig.args().length(); i++) {
if (sig.arg(i) != existing.arg(i)) {
return m.failf(usepn, "incompatible type for argument %u: (%s here vs. %s before)",
i, Type::var(sig.arg(i)).toChars(), Type::var(existing.arg(i)).toChars());
return m.failf(usepn, "incompatible type for argument %u: (%s here vs. %s before)", i,
ToCString(sig.arg(i)), ToCString(existing.arg(i)));
}
}
if (sig.ret() != existing.ret()) {
return m.failf(usepn, "%s incompatible with previous return of type %s",
Type::ret(sig.ret()).toChars(), Type::ret(existing.ret()).toChars());
ToCString(sig.ret()), ToCString(existing.ret()));
}
MOZ_ASSERT(sig == existing);
@@ -4280,7 +4307,10 @@ static bool
CheckIsArgType(FunctionValidator& f, ParseNode* argNode, Type type)
{
if (!type.isArgType())
return f.failf(argNode, "%s is not a subtype of int, float or double", type.toChars());
return f.failf(argNode,
"%s is not a subtype of int, float, double, or an allowed SIMD type",
type.toChars());
return true;
}
@@ -4663,6 +4693,7 @@ SimdToCoercedScalarType(SimdType t)
{
switch (t) {
case SimdType::Int32x4:
case SimdType::Uint32x4:
case SimdType::Bool32x4:
return Type::Intish;
case SimdType::Float32x4:
@@ -4851,7 +4882,7 @@ CheckSimdBinaryShift(FunctionValidator& f, ParseNode* call, SimdType opType, Sim
return false;
if (!CheckSimdCallArgs(f, call, 2, CheckSimdVectorScalarArgs(opType)))
return false;
*type = Type::Int32x4;
*type = opType;
return true;
}
@@ -4863,7 +4894,7 @@ CheckSimdBinaryComp(FunctionValidator& f, ParseNode* call, SimdType opType, Simd
return false;
if (!CheckSimdCallArgs(f, call, 2, CheckArgIsSubtypeOf(opType)))
return false;
*type = Type::Bool32x4;
*type = GetBooleanSimdType(opType);
return true;
}
@@ -4886,6 +4917,7 @@ CheckSimdExtractLane(FunctionValidator& f, ParseNode* call, SimdType opType, Typ
return false;
switch (opType) {
case SimdType::Int32x4: *type = Type::Signed; break;
case SimdType::Uint32x4: *type = Type::Unsigned; break;
case SimdType::Float32x4: *type = Type::Float; break;
case SimdType::Bool32x4: *type = Type::Int; break;
default: MOZ_CRASH("unhandled simd type");
@@ -5166,6 +5198,9 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida
case SimdOperation::Fn_fromInt32x4:
case SimdOperation::Fn_fromInt32x4Bits:
return CheckSimdCast(f, call, SimdType::Int32x4, opType, op, type);
case SimdOperation::Fn_fromUint32x4:
case SimdOperation::Fn_fromUint32x4Bits:
return CheckSimdCast(f, call, SimdType::Uint32x4, opType, op, type);
case SimdOperation::Fn_fromFloat32x4:
case SimdOperation::Fn_fromFloat32x4Bits:
return CheckSimdCast(f, call, SimdType::Float32x4, opType, op, type);
@@ -5207,12 +5242,10 @@ CheckSimdOperationCall(FunctionValidator& f, ParseNode* call, const ModuleValida
case SimdOperation::Constructor:
MOZ_CRASH("constructors are handled in CheckSimdCtorCall");
case SimdOperation::Fn_fromUint32x4:
case SimdOperation::Fn_fromInt8x16Bits:
case SimdOperation::Fn_fromInt16x8Bits:
case SimdOperation::Fn_fromUint8x16Bits:
case SimdOperation::Fn_fromUint16x8Bits:
case SimdOperation::Fn_fromUint32x4Bits:
case SimdOperation::Fn_fromFloat64x2Bits:
MOZ_CRASH("NYI");
}
@@ -5593,12 +5626,8 @@ CheckConditional(FunctionValidator& f, ParseNode* ternary, Type* type)
*type = Type::Double;
} else if (thenType.isFloat() && elseType.isFloat()) {
*type = Type::Float;
} else if (elseType.isInt32x4() && thenType.isInt32x4()) {
*type = Type::Int32x4;
} else if (elseType.isFloat32x4() && thenType.isFloat32x4()) {
*type = Type::Float32x4;
} else if (elseType.isBool32x4() && thenType.isBool32x4()) {
*type = Type::Bool32x4;
} else if (thenType.isSimd() && elseType == thenType) {
*type = thenType;
} else {
return f.failf(ternary, "then/else branches of conditional must both produce int, float, "
"double or SIMD types, current types are %s and %s",
@@ -5626,6 +5655,7 @@ IsValidIntMultiplyConstant(ModuleValidator& m, ParseNode* expr)
case NumLit::Float:
case NumLit::OutOfRangeInt:
case NumLit::Int32x4:
case NumLit::Uint32x4:
case NumLit::Float32x4:
case NumLit::Bool32x4:
return false;
@@ -6167,6 +6197,7 @@ CheckCaseExpr(FunctionValidator& f, ParseNode* caseExpr, int32_t* value)
case NumLit::Double:
case NumLit::Float:
case NumLit::Int32x4:
case NumLit::Uint32x4:
case NumLit::Float32x4:
case NumLit::Bool32x4:
return f.fail(caseExpr, "switch case expression must be an integer literal");
@@ -6327,7 +6358,7 @@ CheckReturnType(FunctionValidator& f, ParseNode* usepn, Type ret)
if (f.returnedType() != ret.canonicalToExprType()) {
return f.failf(usepn, "%s incompatible with previous return of type %s",
Type::ret(ret).toChars(), Type::ret(f.returnedType()).toChars());
Type::ret(ret).toChars(), ToCString(f.returnedType()));
}
return true;
@@ -6840,6 +6871,7 @@ GetDataProperty(JSContext* cx, HandleValue objVal, HandlePropertyName field, Mut
static bool
HasPureCoercion(JSContext* cx, HandleValue v)
{
// Unsigned SIMD types are not allowed in function signatures.
if (IsVectorObject<Int32x4>(v) || IsVectorObject<Float32x4>(v) || IsVectorObject<Bool32x4>(v))
return true;
@@ -7040,7 +7072,7 @@ ValidateSimdType(JSContext* cx, const AsmJSGlobal& global, HandleValue globalVal
else
type = global.simdOperationType();
RootedPropertyName simdTypeName(cx, SimdTypeToName(cx, type));
RootedPropertyName simdTypeName(cx, SimdTypeToName(cx->names(), type));
if (!GetDataProperty(cx, v, simdTypeName, &v))
return false;
@@ -7080,12 +7112,21 @@ ValidateSimdOperation(JSContext* cx, const AsmJSGlobal& global, HandleValue glob
Native native = nullptr;
switch (global.simdOperationType()) {
#define SET_NATIVE_INT32X4(op) case SimdOperation::Fn_##op: native = simd_int32x4_##op; break;
#define SET_NATIVE_UINT32X4(op) case SimdOperation::Fn_##op: native = simd_uint32x4_##op; break;
#define SET_NATIVE_FLOAT32X4(op) case SimdOperation::Fn_##op: native = simd_float32x4_##op; break;
#define SET_NATIVE_BOOL32X4(op) case SimdOperation::Fn_##op: native = simd_bool32x4_##op; break;
#define FALLTHROUGH(op) case SimdOperation::Fn_##op:
case SimdType::Int32x4:
switch (global.simdOperation()) {
FORALL_INT32X4_ASMJS_OP(SET_NATIVE_INT32X4)
SET_NATIVE_INT32X4(fromUint32x4Bits)
default: MOZ_CRASH("shouldn't have been validated in the first place");
}
break;
case SimdType::Uint32x4:
switch (global.simdOperation()) {
FORALL_INT32X4_ASMJS_OP(SET_NATIVE_UINT32X4)
SET_NATIVE_UINT32X4(fromInt32x4Bits)
default: MOZ_CRASH("shouldn't have been validated in the first place");
}
break;
@@ -7103,8 +7144,9 @@ ValidateSimdOperation(JSContext* cx, const AsmJSGlobal& global, HandleValue glob
break;
default: MOZ_CRASH("unhandled simd type");
#undef FALLTHROUGH
#undef SET_NATIVE_FLOAT32X4
#undef SET_NATIVE_INT32X4
#undef SET_NATIVE_UINT32X4
#undef SET_NATIVE_FLOAT32X4
#undef SET_NATIVE_BOOL32X4
#undef SET_NATIVE
}
+10 -23
View File
@@ -83,23 +83,6 @@ class FunctionDecoder
}
};
static const char*
ToCString(ExprType type)
{
switch (type) {
case ExprType::Void: return "void";
case ExprType::I32: return "i32";
case ExprType::I64: return "i64";
case ExprType::F32: return "f32";
case ExprType::F64: return "f64";
case ExprType::I32x4: return "i32x4";
case ExprType::F32x4: return "f32x4";
case ExprType::B32x4: return "b32x4";
case ExprType::Limit:;
}
MOZ_CRASH("bad expression type");
}
static bool
CheckType(FunctionDecoder& f, ExprType actual, ExprType expected)
{
@@ -129,6 +112,10 @@ DecodeValType(JSContext* cx, Decoder& d, ValType *type)
case ValType::F64:
break;
case ValType::I64:
#ifndef JS_CPU_X64
return Fail(cx, d, "i64 NYI on this platform");
#endif
break;
case ValType::I32x4:
case ValType::F32x4:
case ValType::B32x4:
@@ -153,6 +140,10 @@ DecodeExprType(JSContext* cx, Decoder& d, ExprType *type)
case ExprType::Void:
break;
case ExprType::I64:
#ifndef JS_CPU_X64
return Fail(cx, d, "i64 NYI on this platform");
#endif
break;
case ExprType::I32x4:
case ExprType::F32x4:
case ExprType::B32x4:
@@ -376,10 +367,7 @@ DecodeLoadStoreAddress(FunctionDecoder &f)
if (!mozilla::IsPowerOfTwo(align))
return f.fail("memory access alignment must be a power of two");
if (!DecodeExpr(f, ExprType::I32))
return false;
return f.fail("NYI: wasm loads and stores");
return DecodeExpr(f, ExprType::I32);
}
static bool
@@ -423,8 +411,7 @@ DecodeExpr(FunctionDecoder& f, ExprType expected)
case Expr::I32Const:
return DecodeConstI32(f, expected);
case Expr::I64Const:
return f.fail("NYI: i64") &&
DecodeConstI64(f, expected);
return DecodeConstI64(f, expected);
case Expr::F32Const:
return DecodeConstF32(f, expected);
case Expr::F64Const:
+9
View File
@@ -476,6 +476,15 @@ class Encoder
return patchVarU32(offset, patchBits, UINT32_MAX);
}
MOZ_WARN_UNUSED_RESULT bool writePatchableVarU8(size_t* offset) {
*offset = bytecode_.length();
return writeU8(UINT8_MAX);
}
void patchVarU8(size_t offset, uint8_t patchBits) {
MOZ_ASSERT(patchBits < 0x80);
return patchU8(offset, patchBits);
}
MOZ_WARN_UNUSED_RESULT bool writePatchableExpr(size_t* offset) {
return writePatchableEnum<Expr>(offset);
}
+47 -21
View File
@@ -118,7 +118,8 @@ class FunctionCompiler
ins = MConstant::NewAsmJS(alloc(), Int32Value(0), MIRType_Int32);
break;
case ValType::I64:
MOZ_CRASH("int64");
ins = MConstant::NewInt64(alloc(), 0);
break;
case ValType::F32:
ins = MConstant::NewAsmJS(alloc(), Float32Value(0.f), MIRType_Float32);
break;
@@ -1421,10 +1422,22 @@ static bool EmitExpr(FunctionCompiler&, ExprType, MDefinition**, LabelVector* =
static bool EmitExprStmt(FunctionCompiler&, MDefinition**, LabelVector* = nullptr);
static bool
EmitLoadArray(FunctionCompiler& f, Scalar::Type scalarType, MDefinition** def)
EmitLoadStoreAddress(FunctionCompiler& f, uint32_t* offset, uint32_t* align, MDefinition** base)
{
*offset = f.readVarU32();
MOZ_ASSERT(*offset == 0, "Non-zero offsets not supported yet");
*align = f.readVarU32();
return EmitExpr(f, ExprType::I32, base);
}
static bool
EmitLoad(FunctionCompiler& f, Scalar::Type scalarType, MDefinition** def)
{
uint32_t offset, align;
MDefinition* ptr;
if (!EmitExpr(f, ExprType::I32, &ptr))
if (!EmitLoadStoreAddress(f, &offset, &align, &ptr))
return false;
*def = f.loadHeap(scalarType, ptr);
return true;
@@ -1433,8 +1446,9 @@ EmitLoadArray(FunctionCompiler& f, Scalar::Type scalarType, MDefinition** def)
static bool
EmitStore(FunctionCompiler& f, Scalar::Type viewType, MDefinition** def)
{
uint32_t offset, align;
MDefinition* ptr;
if (!EmitExpr(f, ExprType::I32, &ptr))
if (!EmitLoadStoreAddress(f, &offset, &align, &ptr))
return false;
MDefinition* rhs = nullptr;
@@ -1465,8 +1479,9 @@ static bool
EmitStoreWithCoercion(FunctionCompiler& f, Scalar::Type rhsType, Scalar::Type viewType,
MDefinition **def)
{
uint32_t offset, align;
MDefinition* ptr;
if (!EmitExpr(f, ExprType::I32, &ptr))
if (!EmitLoadStoreAddress(f, &offset, &align, &ptr))
return false;
MDefinition* rhs = nullptr;
@@ -1536,9 +1551,12 @@ static bool
EmitAtomicsLoad(FunctionCompiler& f, MDefinition** def)
{
Scalar::Type viewType = Scalar::Type(f.readU8());
uint32_t offset, align;
MDefinition* index;
if (!EmitExpr(f, ExprType::I32, &index))
if (!EmitLoadStoreAddress(f, &offset, &align, &index))
return false;
*def = f.atomicLoadHeap(viewType, index);
return true;
}
@@ -1547,9 +1565,12 @@ static bool
EmitAtomicsStore(FunctionCompiler& f, MDefinition** def)
{
Scalar::Type viewType = Scalar::Type(f.readU8());
uint32_t offset, align;
MDefinition* index;
if (!EmitExpr(f, ExprType::I32, &index))
if (!EmitLoadStoreAddress(f, &offset, &align, &index))
return false;
MDefinition* value;
if (!EmitExpr(f, ExprType::I32, &value))
return false;
@@ -1563,9 +1584,12 @@ EmitAtomicsBinOp(FunctionCompiler& f, MDefinition** def)
{
Scalar::Type viewType = Scalar::Type(f.readU8());
js::jit::AtomicOp op = js::jit::AtomicOp(f.readU8());
uint32_t offset, align;
MDefinition* index;
if (!EmitExpr(f, ExprType::I32, &index))
if (!EmitLoadStoreAddress(f, &offset, &align, &index))
return false;
MDefinition* value;
if (!EmitExpr(f, ExprType::I32, &value))
return false;
@@ -1577,9 +1601,12 @@ static bool
EmitAtomicsCompareExchange(FunctionCompiler& f, MDefinition** def)
{
Scalar::Type viewType = Scalar::Type(f.readU8());
uint32_t offset, align;
MDefinition* index;
if (!EmitExpr(f, ExprType::I32, &index))
if (!EmitLoadStoreAddress(f, &offset, &align, &index))
return false;
MDefinition* oldValue;
if (!EmitExpr(f, ExprType::I32, &oldValue))
return false;
@@ -1594,9 +1621,12 @@ static bool
EmitAtomicsExchange(FunctionCompiler& f, MDefinition** def)
{
Scalar::Type viewType = Scalar::Type(f.readU8());
uint32_t offset, align;
MDefinition* index;
if (!EmitExpr(f, ExprType::I32, &index))
if (!EmitLoadStoreAddress(f, &offset, &align, &index))
return false;
MDefinition* value;
if (!EmitExpr(f, ExprType::I32, &value))
return false;
@@ -2338,10 +2368,6 @@ EmitSimdOp(FunctionCompiler& f, ExprType type, SimdOperation op, SimdSign sign,
return EmitSimdShift(f, type, MSimdShift::lsh, def);
case SimdOperation::Fn_shiftRightByScalar:
return EmitSimdShift(f, type, MSimdShift::rshForSign(sign), def);
case SimdOperation::Fn_shiftRightArithmeticByScalar:
return EmitSimdShift(f, type, MSimdShift::rsh, def);
case SimdOperation::Fn_shiftRightLogicalByScalar:
return EmitSimdShift(f, type, MSimdShift::ursh, def);
#define _CASE(OP) \
case SimdOperation::Fn_##OP: \
return EmitSimdBinaryComp(f, type, MSimdBinaryComp::OP, sign, def);
@@ -2774,15 +2800,15 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may
case Expr::I32BitNot:
return EmitBitwise<MBitNot>(f, def);
case Expr::I32LoadMem8S:
return EmitLoadArray(f, Scalar::Int8, def);
return EmitLoad(f, Scalar::Int8, def);
case Expr::I32LoadMem8U:
return EmitLoadArray(f, Scalar::Uint8, def);
return EmitLoad(f, Scalar::Uint8, def);
case Expr::I32LoadMem16S:
return EmitLoadArray(f, Scalar::Int16, def);
return EmitLoad(f, Scalar::Int16, def);
case Expr::I32LoadMem16U:
return EmitLoadArray(f, Scalar::Uint16, def);
return EmitLoad(f, Scalar::Uint16, def);
case Expr::I32LoadMem:
return EmitLoadArray(f, Scalar::Int32, def);
return EmitLoad(f, Scalar::Int32, def);
case Expr::I32StoreMem8:
return EmitStore(f, Scalar::Int8, def);
case Expr::I32StoreMem16:
@@ -2856,7 +2882,7 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may
case Expr::F32ConvertUI32:
return EmitUnary<MAsmJSUnsignedToFloat32>(f, ExprType::I32, def);
case Expr::F32LoadMem:
return EmitLoadArray(f, Scalar::Float32, def);
return EmitLoad(f, Scalar::Float32, def);
case Expr::F32StoreMem:
return EmitStore(f, Scalar::Float32, def);
case Expr::F32StoreMemF64:
@@ -2904,7 +2930,7 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may
case Expr::F64ConvertUI32:
return EmitUnary<MAsmJSUnsignedToDouble>(f, ExprType::I32, def);
case Expr::F64LoadMem:
return EmitLoadArray(f, Scalar::Float64, def);
return EmitLoad(f, Scalar::Float64, def);
case Expr::F64StoreMem:
return EmitStore(f, Scalar::Float64, def);
case Expr::F64StoreMemF32:
+24 -1
View File
@@ -74,7 +74,7 @@ ToMIRType(ValType vt)
{
switch (vt) {
case ValType::I32: return jit::MIRType_Int32;
case ValType::I64: MOZ_CRASH("NYI");
case ValType::I64: return jit::MIRType_Int64;
case ValType::F32: return jit::MIRType_Float32;
case ValType::F64: return jit::MIRType_Double;
case ValType::I32x4: return jit::MIRType_Int32x4;
@@ -194,6 +194,29 @@ ToMIRType(ExprType et)
return IsVoid(et) ? jit::MIRType_None : ToMIRType(ValType(et));
}
static inline const char*
ToCString(ExprType type)
{
switch (type) {
case ExprType::Void: return "void";
case ExprType::I32: return "i32";
case ExprType::I64: return "i64";
case ExprType::F32: return "f32";
case ExprType::F64: return "f64";
case ExprType::I32x4: return "i32x4";
case ExprType::F32x4: return "f32x4";
case ExprType::B32x4: return "b32x4";
case ExprType::Limit:;
}
MOZ_CRASH("bad expression type");
}
static inline const char*
ToCString(ValType type)
{
return ToCString(ToExprType(type));
}
// The Sig class represents a WebAssembly function signature which takes a list
// of value types and returns an expression type. The engine uses two in-memory
// representations of the argument Vector's memory (when elements do not fit
+4 -2
View File
@@ -92,8 +92,10 @@ class EvalScriptGuard
script_->cacheForEval();
EvalCacheEntry cacheEntry = {lookupStr_, script_, lookup_.callerScript, lookup_.pc};
lookup_.str = lookupStr_;
if (lookup_.str && IsEvalCacheCandidate(script_))
cx_->runtime()->evalCache.relookupOrAdd(p_, lookup_, cacheEntry);
if (lookup_.str && IsEvalCacheCandidate(script_)) {
bool ok = cx_->runtime()->evalCache.relookupOrAdd(p_, lookup_, cacheEntry);
(void)ok; // Ignore failure to add cache entry.
}
}
}
+39 -18
View File
@@ -39,19 +39,6 @@ using mozilla::NumberIsInt32;
static_assert(unsigned(SimdType::Count) == 12, "sync with TypedObjectConstants.h");
PropertyName*
js::SimdTypeToName(JSContext* cx, SimdType type)
{
switch (type) {
case SimdType::Int32x4: return cx->names().Int32x4;
case SimdType::Float32x4: return cx->names().Float32x4;
case SimdType::Bool32x4: return cx->names().Bool32x4;
default: break;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("unexpected SIMD type");
}
static bool
CheckVectorObject(HandleValue v, SimdType expectedType)
{
@@ -107,6 +94,30 @@ js::SimdTypeToString(SimdType type)
return "<bad SimdType>";
}
PropertyName*
js::SimdTypeToName(const JSAtomState& atoms, SimdType type)
{
switch (type) {
#define CASE_(TypeName) case SimdType::TypeName: return atoms.TypeName;
FOR_EACH_SIMD(CASE_)
#undef CASE_
case SimdType::Count: break;
}
MOZ_CRASH("bad SIMD type");
}
bool
js::IsSimdTypeName(const JSAtomState& atoms, const PropertyName* name, SimdType* type)
{
#define CHECK_(TypeName) if (name == atoms.TypeName) { \
*type = SimdType::TypeName; \
return true; \
}
FOR_EACH_SIMD(CHECK_)
#undef CHECK_
return false;
}
static inline bool
ErrorBadArgs(JSContext* cx)
{
@@ -701,27 +712,37 @@ template<typename T>
struct Or {
static T apply(T l, T r) { return l | r; }
};
// For the following three operators, if the value v we're trying to shift is
// such that v << bits can't fit in the int32 range, then we have undefined
// behavior, according to C++11 [expr.shift]p2.
// behavior, according to C++11 [expr.shift]p2. However, left-shifting an
// unsigned type is well-defined.
//
// In C++, shifting by an amount outside the range [0;N-1] is undefined
// behavior. SIMD.js reduces the shift amount modulo the number of bits in a
// lane and has defined behavior for all shift amounts.
template<typename T>
struct ShiftLeft {
static T apply(T v, int32_t bits) {
return uint32_t(bits) >= sizeof(T) * 8 ? 0 : v << bits;
typedef typename mozilla::MakeUnsigned<T>::Type UnsignedT;
uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8);
return UnsignedT(v) << maskedBits;
}
};
template<typename T>
struct ShiftRightArithmetic {
static T apply(T v, int32_t bits) {
typedef typename mozilla::MakeSigned<T>::Type SignedT;
uint32_t maxBits = sizeof(T) * 8;
return SignedT(v) >> (uint32_t(bits) >= maxBits ? maxBits - 1 : bits);
uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8);
return SignedT(v) >> maskedBits;
}
};
template<typename T>
struct ShiftRightLogical {
static T apply(T v, int32_t bits) {
return uint32_t(bits) >= sizeof(T) * 8 ? 0 : uint32_t(v) >> bits;
typedef typename mozilla::MakeUnsigned<T>::Type UnsignedT;
uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8);
return UnsignedT(v) >> maskedBits;
}
};
+7 -16
View File
@@ -250,8 +250,6 @@
V(subSaturate, (BinaryFunc<Int8x16, SubSaturate, Int8x16>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int8x16, ShiftLeft>), 2) \
V(shiftRightByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Int8x16, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Int8x16, Xor, Int8x16>), 2)
#define INT8X16_TERNARY_FUNCTION_LIST(V) \
@@ -301,8 +299,6 @@
V(subSaturate, (BinaryFunc<Uint8x16, SubSaturate, Uint8x16>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Uint8x16, ShiftLeft>), 2) \
V(shiftRightByScalar, (BinaryScalar<Uint8x16, ShiftRightLogical>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Uint8x16, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Uint8x16, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Uint8x16, Xor, Uint8x16>), 2)
#define UINT8X16_TERNARY_FUNCTION_LIST(V) \
@@ -352,8 +348,6 @@
V(subSaturate, (BinaryFunc<Int16x8, SubSaturate, Int16x8>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int16x8, ShiftLeft>), 2) \
V(shiftRightByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Int16x8, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Int16x8, Xor, Int16x8>), 2)
#define INT16X8_TERNARY_FUNCTION_LIST(V) \
@@ -403,8 +397,6 @@
V(subSaturate, (BinaryFunc<Uint16x8, SubSaturate, Uint16x8>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Uint16x8, ShiftLeft>), 2) \
V(shiftRightByScalar, (BinaryScalar<Uint16x8, ShiftRightLogical>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Uint16x8, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Uint16x8, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Uint16x8, Xor, Uint16x8>), 2)
#define UINT16X8_TERNARY_FUNCTION_LIST(V) \
@@ -456,8 +448,6 @@
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Int32x4, ShiftLeft>), 2) \
V(shiftRightByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Int32x4, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2)
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
@@ -512,8 +502,6 @@
V(sub, (BinaryFunc<Uint32x4, Sub, Uint32x4>), 2) \
V(shiftLeftByScalar, (BinaryScalar<Uint32x4, ShiftLeft>), 2) \
V(shiftRightByScalar, (BinaryScalar<Uint32x4, ShiftRightLogical>), 2) \
V(shiftRightArithmeticByScalar, (BinaryScalar<Uint32x4, ShiftRightArithmetic>), 2) \
V(shiftRightLogicalByScalar, (BinaryScalar<Uint32x4, ShiftRightLogical>), 2) \
V(xor, (BinaryFunc<Uint32x4, Xor, Uint32x4>), 2)
#define UINT32X4_TERNARY_FUNCTION_LIST(V) \
@@ -586,9 +574,7 @@
// Bitwise shifts defined on integer SIMD types.
#define FOREACH_SHIFT_SIMD_OP(_) \
_(shiftLeftByScalar) \
_(shiftRightByScalar) \
_(shiftRightArithmeticByScalar) \
_(shiftRightLogicalByScalar)
_(shiftRightByScalar)
// Unary arithmetic operators defined on numeric SIMD types.
#define FOREACH_NUMERIC_SIMD_UNOP(_) \
@@ -1103,7 +1089,12 @@ struct Bool64x2 {
}
};
PropertyName* SimdTypeToName(JSContext* cx, SimdType type);
// Get the well known name of the SIMD.* object corresponding to type.
PropertyName* SimdTypeToName(const JSAtomState& atoms, SimdType type);
// Check if name is the well known name of a SIMD type.
// Returns true and sets *type iff name is known.
bool IsSimdTypeName(const JSAtomState& atoms, const PropertyName* name, SimdType* type);
const char* SimdTypeToString(SimdType type);
+68 -155
View File
@@ -388,8 +388,6 @@ case "$target" in
_CC_SUITE=14
MSVC_C_RUNTIME_DLL=vcruntime140.dll
MSVC_CXX_RUNTIME_DLL=msvcp140.dll
MSVC_APPCRT_DLL=appcrt140.dll
MSVC_DESKTOPCRT_DLL=desktopcrt140.dll
# -Wv:18 disables all warnings introduced after VS2013
# See http://blogs.msdn.com/b/vcblog/archive/2014/11/12/improvements-to-warnings-in-the-c-compiler.aspx
@@ -407,8 +405,6 @@ case "$target" in
fi
AC_SUBST(MSVC_C_RUNTIME_DLL)
AC_SUBST(MSVC_CXX_RUNTIME_DLL)
AC_SUBST(MSVC_APPCRT_DLL)
AC_SUBST(MSVC_DESKTOPCRT_DLL)
dnl Ensure that mt.exe is 'Microsoft (R) Manifest Tool',
dnl not something else like "magnetic tape manipulation utility".
@@ -1206,79 +1202,40 @@ if test "$GNU_CC"; then
LDFLAGS=$_SAVE_LDFLAGS)
# Turn on gcc/clang warnings:
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
#
# -Wall - turn on a lot of warnings
# -Waddress - catches suspicious uses of memory addresses
# -Wchar-subscripts - catches array index using signed char
# -Wcomment - catches nested comments
# https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Warning-Options.html
# -Wall - lots of useful warnings
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
# -Wenum-compare - catches comparison of different enum types
# -Wignored-qualifiers - catches returns types with qualifiers like const
# -Wimplicit-function-declaration - catches missing C function prototypes
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmissing-braces - catches aggregate initializers missing nested braces
# -Wmultichar - catches multicharacter integer constants like 'THIS'
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wnonnull - catches NULL used with functions arguments marked as non-null
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
# -Wignored-qualifiers - catches return types with qualifiers like const
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
# -Wpointer-sign - catches mixing pointers to signed and unsigned types
# -Wpointer-to-int-cast - catches casts from pointer to different sized int
# -Wreturn-type - catches missing returns, zero false positives
# -Wsequence-point - catches undefined order behavior like `a = a++`
# -Wsign-compare - catches comparison of signed and unsigned types
# -Wswitch - catches switches without all enum cases or default case
# -Wtrigraphs - catches unlikely use of trigraphs
# -Wtype-limits - catches overflow bugs, few false positives
# -Wunknown-pragmas - catches unexpected #pragma directives
# -Wwrite-strings - catches non-const char* pointers to string literals
#
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wsign-compare"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wempty-body"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wignored-qualifiers"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wpointer-arith"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits"
# Treat some warnings as errors if --enable-warnings-as-errors:
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=address"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=char-subscripts"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=comment"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=empty-body"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=endif-labels"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=enum-compare"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=ignored-qualifiers"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=implicit-function-declaration"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=missing-braces"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=multichar"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=nonnull"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=parentheses"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-arith"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-sign"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-to-int-cast"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=return-type"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=switch"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=uninitialized"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=write-strings"
MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_werror_non_literal_null_conversion)
MOZ_C_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_c_has_sometimes_uninitialized)
fi
# Turn off the following warnings that -Wall turns on:
# -Wno-unused - lots of violations in third-party code
# -Wno-inline-new-delete - we inline 'new' and 'delete' in mozalloc
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
# -Wclass-varargs - catches objects passed by value to variadic functions.
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wsometimes-initialized - catches some uninitialized values
# -Wunreachable-code-aggressive - catches lots of dead code
#
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wno-unused"
# XXX: at the time of writing, the version of clang used on the OS X test
# machines has a bug that causes it to reject some valid files if both
# -Wnon-literal-null-conversion and -Wsometimes-uninitialized are
# specified. We work around this by instead using
# -Werror=non-literal-null-conversion, but we only do that when
# --enable-warnings-as-errors is specified so that no unexpected fatal
# warnings are produced.
MOZ_C_SUPPORTS_WARNING(-W, class-varargs, ac_c_has_wclass_varargs)
MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete)
MOZ_CXX_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_cxx_has_wno_unused_local_typedef)
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_non_literal_null_conversion)
fi
MOZ_C_SUPPORTS_WARNING(-W, sometimes-uninitialized, ac_c_has_sometimes_uninitialized)
MOZ_C_SUPPORTS_WARNING(-W, unreachable-code-aggressive, ac_c_has_wunreachable_code_aggressive)
# -Wcast-align - catches problems with cast alignment
if test -z "$INTEL_CC" -a -z "$CLANG_CC"; then
# Don't use -Wcast-align with ICC or clang
case "$CPU_ARCH" in
@@ -1291,6 +1248,11 @@ if test "$GNU_CC"; then
esac
fi
# Turn off some non-useful warnings that -Wall turns on.
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
MOZ_C_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_c_has_wno_unused_local_typedef)
_DEFINES_CFLAGS='-include $(DEPTH)/js/src/js-confdefs.h -DMOZILLA_CLIENT'
_USE_CPP_INCLUDE_FLAG=1
@@ -1320,77 +1282,44 @@ fi
if test "$GNU_CXX"; then
# Turn on gcc/clang warnings:
# https://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Warning-Options.html
#
# -Wall - turn on a lot of warnings
# -Wchar-subscripts - catches array index using signed char
# -Wcomment - catches nested comments
# -Wconversion-null - catches conversions between NULL and non-pointer types
# https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Warning-Options.html
# -Wall - lots of useful warnings
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
# -Wignored-qualifiers - catches returns types with qualifiers like const
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmissing-braces - catches aggregate initializers missing nested braces
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wignored-qualifiers - catches return types with qualifiers like const
# -Woverloaded-virtual - function declaration hides virtual function from base class
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
# -Wpointer-to-int-cast - catches casts from pointer to different sized int
# -Wrange-loop-analysis - catches copies during range-based for loops.
# -Wreorder - catches ctor initializer list not matching class definition order
# -Wreturn-type - catches missing returns, zero false positives
# -Wsequence-point - catches undefined order behavior like `a = a++`
# -Wsign-compare - catches comparison of signed and unsigned types
# -Wswitch - catches switches without all enum cases or default case
# -Wtrigraphs - catches unlikely use of trigraphs
# -Wtype-limits - catches overflow bugs, few false positives
# -Wunknown-pragmas - catches unexpected #pragma directives
# -Wunused-label - catches unused goto labels
# -Wunused-value - catches unused expression results
# -Wwrite-strings - catches non-const char* pointers to string literals
#
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wempty-body"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wignored-qualifiers"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Woverloaded-virtual"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wpointer-arith"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
# -Wclass-varargs - catches objects passed by value to variadic functions.
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wrange-loop-analysis - catches copies during range-based for loops.
# -Wsometimes-initialized - catches some uninitialized values
# -Wunreachable-code-aggressive - catches lots of dead code
#
# XXX: at the time of writing, the version of clang used on the OS X test
# machines has a bug that causes it to reject some valid files if both
# -Wnon-literal-null-conversion and -Wsometimes-uninitialized are
# specified. We work around this by instead using
# -Werror=non-literal-null-conversion, but we only do that when
# --enable-warnings-as-errors is specified so that no unexpected fatal
# warnings are produced.
MOZ_CXX_SUPPORTS_WARNING(-W, class-varargs, ac_cxx_has_wclass_varargs)
# Treat some warnings as errors if --enable-warnings-as-errors:
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=char-subscripts"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=comment"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=ignored-qualifiers"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=overloaded-virtual"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=parentheses"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=pointer-arith"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=reorder"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=switch"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=uninitialized"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unknown-pragmas"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-value"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=write-strings"
MOZ_CXX_SUPPORTS_WARNING(-Werror=, conversion-null, ac_cxx_has_werror_conversion_null)
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
MOZ_CXX_SUPPORTS_WARNING(-Werror=, range-loop-analysis, ac_cxx_has_range_loop_analysis)
MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_non_literal_null_conversion)
fi
MOZ_CXX_SUPPORTS_WARNING(-W, range-loop-analysis, ac_cxx_has_range_loop_analysis)
MOZ_CXX_SUPPORTS_WARNING(-W, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
MOZ_CXX_SUPPORTS_WARNING(-W, unreachable-code-aggressive, ac_cxx_has_wunreachable_code_aggressive)
# Turn off the following warnings that -Wall turns on:
# -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
#
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
MOZ_CXX_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_cxx_has_wno_unused_local_typedef)
# -Wcast-align - catches problems with cast alignment
if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
# Don't use -Wcast-align with ICC or clang
case "$CPU_ARCH" in
@@ -1403,8 +1332,15 @@ if test "$GNU_CXX"; then
esac
fi
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/js/src/js-confdefs.h'
_USE_CPP_INCLUDE_FLAG=1
# Turn off some non-useful warnings that -Wall turns on.
# -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
# -Wno-inline-new-delete - we inline 'new' and 'delete' in mozalloc
# -Wno-unused-local-typedef - catches unused typedefs, which are commonly used in assertion macros
MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete)
MOZ_CXX_SUPPORTS_WARNING(-Wno-, unused-local-typedef, ac_cxx_has_wno_unused_local_typedef)
# Recent clang and gcc support C++11 deleted functions without warnings if
# compiling with -std=c++0x or -std=gnu++0x (or c++11 or gnu++11 in very new
@@ -1417,6 +1353,9 @@ if test "$GNU_CXX"; then
MOZ_CXX_SUPPORTS_WARNING(-Wno-, extended-offsetof, ac_cxx_has_wno_extended_offsetof)
fi
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(topobjdir)/js/src/js-confdefs.h'
_USE_CPP_INCLUDE_FLAG=1
else
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_JS_CONFDEFS_H_ $(ACDEFINES)'
fi
@@ -1464,11 +1403,6 @@ case "$host" in
HOST_CFLAGS="$HOST_CFLAGS -DXP_WIN32 -DXP_WIN -DWIN32 -D_WIN32 -DNO_X11 -D_CRT_SECURE_NO_WARNINGS"
HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O2}"
HOST_BIN_SUFFIX=.exe
case "$host" in
*mingw*)
PERL="/bin/sh ${_topsrcdir}/build/msys-perl-wrapper"
;;
esac
case "${host_cpu}" in
i*86)
@@ -2972,24 +2906,6 @@ elif test "$GNU_CC"; then
fi
fi
dnl ========================================================
dnl = Enable DMD
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(dmd,
[ --enable-dmd Enable DMD; also enables jemalloc and replace-malloc],
MOZ_DMD=1,
MOZ_DMD= )
if test "$MOZ_DMD"; then
AC_DEFINE(MOZ_DMD)
if test "${CPU_ARCH}" = "arm"; then
CFLAGS="$CFLAGS -funwind-tables"
CXXFLAGS="$CXXFLAGS -funwind-tables"
fi
fi
dnl ========================================================
dnl = Enable jemalloc
dnl ========================================================
@@ -3717,9 +3633,6 @@ AC_SUBST(MOZ_PKG_SPECIAL)
AC_SUBST(MOZILLA_OFFICIAL)
dnl win32 options
AC_SUBST(MOZ_BROWSE_INFO)
dnl Echo the CFLAGS to remove extra whitespace.
CFLAGS=`echo \
$_WARNINGS_CFLAGS \
+5 -1
View File
@@ -146,7 +146,11 @@ MakeNode(VerifyPreTracer* trc, void* thing, JS::TraceKind kind)
node->thing = thing;
node->count = 0;
node->kind = kind;
trc->nodemap.add(p, thing, node);
if (!trc->nodemap.add(p, thing, node)) {
trc->edgeptr = trc->term;
return nullptr;
}
return node;
}
return nullptr;
+33 -22
View File
@@ -4,21 +4,25 @@ setJitCompilerOption("ion.warmup.trigger", 50);
function curry(f, arg) { return f.bind(null, arg); }
function binaryLsh(count, v) { if (count>>>0 >= 32) return 0; return (v << count) | 0; }
function binaryLsh(count, v) { count &= 31; return (v << count) | 0; }
function lsh(count) { return curry(binaryLsh, count); }
function binaryRsh(count, v) { if (count>>>0 >= 32) count = 31; return (v >> count) | 0; }
function binaryRsh(count, v) { count &= 31; return (v >> count) | 0; }
function rsh(count) { return curry(binaryRsh, count); }
function binaryUrsh(count, v) { if (count>>>0 >= 32) return 0; return (v >>> count) | 0; }
function binaryUlsh(count, v) { count &= 31; return (v << count) >>> 0; }
function ulsh(count) { return curry(binaryUlsh, count); }
function binaryUrsh(count, v) { count &= 31; return v >>> count; }
function ursh(count) { return curry(binaryUrsh, count); }
function f() {
var v = SIMD.Int32x4(1, 2, -3, 4);
var u = SIMD.Uint32x4(1, 0x55005500, -3, 0xaa00aa00);
var a = [1, 2, -3, 4];
var zeros = [0,0,0,0];
var b = [1, 0x55005500, -3, 0xaa00aa00];
var shifts = [-1, 0, 1, 31, 32];
var shifts = [-2, -1, 0, 1, 31, 32, 33];
var r;
for (var i = 0; i < 150; i++) {
@@ -29,33 +33,40 @@ function f() {
assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 2), a.map(lsh(2)));
assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 31), a.map(lsh(31)));
assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 32), a.map(lsh(32)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, -1), a.map(rsh(31)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 0), a.map(rsh(0)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 1), a.map(rsh(1)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 2), a.map(rsh(2)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 31), a.map(rsh(31)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, 32), a.map(rsh(31)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, -1), a.map(ursh(-1)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 0), a.map(ursh(0)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 1), a.map(ursh(1)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 2), a.map(ursh(2)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 31), a.map(ursh(31)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, 32), a.map(ursh(32)));
assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, 33), a.map(lsh(33)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, -1), a.map(rsh(31)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 0), a.map(rsh(0)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 1), a.map(rsh(1)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 2), a.map(rsh(2)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 31), a.map(rsh(31)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 32), a.map(rsh(31)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 32), a.map(rsh(32)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, 33), a.map(rsh(33)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, -1), b.map(ulsh(-1)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 0), b.map(ulsh(0)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 1), b.map(ulsh(1)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 2), b.map(ulsh(2)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 31), b.map(ulsh(31)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 32), b.map(ulsh(32)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, 33), b.map(ulsh(33)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, -1), b.map(ursh(-1)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 0), b.map(ursh(0)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 1), b.map(ursh(1)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 2), b.map(ursh(2)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 31), b.map(ursh(31)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 32), b.map(ursh(32)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, 33), b.map(ursh(33)));
// Non constant shift counts
var c = shifts[i % shifts.length];
assertEqX4(SIMD.Int32x4.shiftLeftByScalar(v, c), a.map(lsh(c)));
assertEqX4(SIMD.Int32x4.shiftRightArithmeticByScalar(v, c), a.map(rsh(c)));
assertEqX4(SIMD.Int32x4.shiftRightLogicalByScalar(v, c), a.map(ursh(c)));
assertEqX4(SIMD.Int32x4.shiftRightByScalar(v, c), a.map(rsh(c)));
assertEqX4(SIMD.Uint32x4.shiftLeftByScalar(u, c), b.map(ulsh(c)));
assertEqX4(SIMD.Uint32x4.shiftRightByScalar(u, c), b.map(ursh(c)));
}
return r;
}
+189 -15
View File
@@ -16,6 +16,15 @@ const CI32 = 'var ci4 = i4.check;'
const I32A = 'var i4a = i4.add;'
const I32S = 'var i4s = i4.sub;'
const I32M = 'var i4m = i4.mul;'
const I32U32 = 'var i4u4 = i4.fromUint32x4Bits;'
const U32 = 'var u4 = glob.SIMD.Uint32x4;'
const CU32 = 'var cu4 = u4.check;'
const U32A = 'var u4a = u4.add;'
const U32S = 'var u4s = u4.sub;'
const U32M = 'var u4m = u4.mul;'
const U32I32 = 'var u4i4 = u4.fromInt32x4Bits;'
const F32 = 'var f4 = glob.SIMD.Float32x4;'
const CF32 = 'var cf4 = f4.check;'
const F32A = 'var f4a = f4.add;'
@@ -27,6 +36,7 @@ const B32 = 'var b4 = glob.SIMD.Bool32x4;'
const CB32 = 'var cb4 = b4.check;'
const EXTI4 = 'var e = i4.extractLane;'
const EXTU4 = 'var e = u4.extractLane;'
const EXTF4 = 'var e = f4.extractLane;'
const EXTB4 = 'var e = b4.extractLane;'
@@ -36,6 +46,7 @@ const ALLB4 = 'var allt=b4.allTrue;'
const INT32_MAX = Math.pow(2, 31) - 1;
const INT32_MIN = INT32_MAX + 1 | 0;
const UINT32_MAX = Math.pow(2, 32) - 1;
const assertEqFFI = {assertEq:assertEq};
@@ -46,6 +57,15 @@ function CheckI4(header, code, expected) {
assertEqX4(observed, expected);
}
function CheckU4(header, code, expected) {
// code needs to contain a local called x.
header = USE_ASM + U32 + CU32 + EXTU4 + I32 + CI32 + I32U32 + header;
var observed = asmLink(asmCompile('glob', header + ';function f() {' + code + ';return ci4(i4u4(x))} return f'), this)();
// We can't return an unsigned SIMD type. Return Int32x4, convert to unsigned here.
observed = SIMD.Uint32x4.fromInt32x4Bits(observed)
assertEqX4(observed, expected);
}
function CheckF4(header, code, expected) {
// code needs to contain a local called x
header = USE_ASM + F32 + CF32 + EXTF4 + header;
@@ -176,6 +196,7 @@ assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42; return x.signMask;}
assertAsmTypeFail('glob', USE_ASM + "function f() {var x=42.; return x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + FROUND + "function f() {var x=f32(42.); return x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + 'function f() { var x=i4(1,2,3,4); return x.signMask | 0 } return f');
assertAsmTypeFail('glob', USE_ASM + U32 + 'function f() { var x=u4(1,2,3,4); return x.signMask | 0 } return f');
assertAsmTypeFail('glob', USE_ASM + F32 + FROUND + 'var Infinity = glob.Infinity; function f() { var x=f4(0,0,0,0); x=f4(f32(1), f32(-13.37), f32(42), f32(-Infinity)); return x.signMask | 0 } return f');
// Check lane extraction.
@@ -186,6 +207,11 @@ function CheckLanes(innerBody, type, expected) {
coerceBefore = '';
coerceAfter = '|0';
extractLane = 'ei';
} else if (type === SIMD.Uint32x4) {
// Coerce Uint32 lanes to double so they can be legally returned.
coerceBefore = '+';
coerceAfter = '';
extractLane = 'eu';
} else if (type === SIMD.Float32x4) {
coerceBefore = '+';
coerceAfter = '';
@@ -201,9 +227,11 @@ function CheckLanes(innerBody, type, expected) {
var lane = i;
var laneCheckCode = `"use asm";
var i4=glob.SIMD.Int32x4;
var u4=glob.SIMD.Uint32x4;
var f4=glob.SIMD.Float32x4;
var b4=glob.SIMD.Bool32x4;
var ei=i4.extractLane;
var eu=u4.extractLane;
var ef=f4.extractLane;
var eb=b4.extractLane;
function f() {${innerBody}; return ${coerceBefore}${extractLane}(x, ${lane})${coerceAfter} }
@@ -212,6 +240,7 @@ function CheckLanes(innerBody, type, expected) {
}
}
function CheckLanesI4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Int32x4, expected); }
function CheckLanesU4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Uint32x4, expected); }
function CheckLanesF4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Float32x4, expected); }
function CheckLanesB4(innerBody, expected) { return CheckLanes(innerBody, SIMD.Bool32x4, expected); }
@@ -222,6 +251,13 @@ CheckLanesI4('var x=i4(1,2,3,4); var y=i4(5,6,7,8)', [1,2,3,4]);
CheckLanesI4('var a=1; var b=i4(9,8,7,6); var c=13.37; var x=i4(1,2,3,4); var y=i4(5,6,7,8)', [1,2,3,4]);
CheckLanesI4('var y=i4(5,6,7,8); var x=i4(1,2,3,4)', [1,2,3,4]);
CheckLanesU4('var x=u4(0,0,0,0);', [0,0,0,0]);
CheckLanesU4('var x=u4(1,2,3,4000000000);', [1,2,3,4000000000]);
CheckLanesU4('var x=u4(' + INT32_MIN + ',2,3,' + UINT32_MAX + ')', [INT32_MIN>>>0,2,3,UINT32_MAX]);
CheckLanesU4('var x=u4(1,2,3,4); var y=u4(5,6,7,8)', [1,2,3,4]);
CheckLanesU4('var a=1; var b=u4(9,8,7,6); var c=13.37; var x=u4(1,2,3,4); var y=u4(5,6,7,8)', [1,2,3,4]);
CheckLanesU4('var y=u4(5,6,7,8); var x=u4(1,2,3,4)', [1,2,3,4]);
CheckLanesF4('var x=f4(' + INT32_MAX + ', 2, 3, ' + INT32_MIN + ')', [INT32_MAX, 2, 3, INT32_MIN]);
CheckLanesF4('var x=f4(' + (INT32_MAX + 1) + ', 2, 3, 4)', [INT32_MAX + 1, 2, 3, 4]);
CheckLanesF4('var x=f4(1.3, 2.4, 3.5, 98.76)', [1.3, 2.4, 3.5, 98.76]);
@@ -253,6 +289,10 @@ CheckI4('', 'var x=i4(1,2,3,4); x=i4(5,6,7,8)', [5, 6, 7, 8]);
CheckI4('', 'var x=i4(1,2,3,4); var c=6; x=i4(5,c|0,7,8)', [5, 6, 7, 8]);
CheckI4('', 'var x=i4(8,7,6,5); x=i4(e(x,3)|0,e(x,2)|0,e(x,1)|0,e(x,0)|0)', [5, 6, 7, 8]);
CheckU4('', 'var x=u4(1,2,3,4); x=u4(5,6,7,4000000000)', [5, 6, 7, 4000000000]);
CheckU4('', 'var x=u4(1,2,3,4); var c=6; x=u4(5,c|0,7,8)', [5, 6, 7, 8]);
CheckU4('', 'var x=u4(8,7,6,5); x=u4(e(x,3)|0,e(x,2)|0,e(x,1)|0,e(x,0)|0)', [5, 6, 7, 8]);
assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=f4(1,2,3,c);} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=f4(1.,2.,3.,c);} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4.; x=f4(1,2,3,c);} return f");
@@ -281,6 +321,8 @@ assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var
assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?x:y;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f");
assertAsmTypeFail('glob', USE_ASM + B32 + I32 + "function f() {var x=b4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f");
assertAsmTypeFail('glob', USE_ASM + U32 + I32 + "function f() {var x=u4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f");
assertAsmTypeFail('glob', USE_ASM + U32 + I32 + "function f() {var x=i4(1,2,3,4); var y=u4(1,2,3,4); x=1?y:y;} return f");
CheckF4('', 'var x=f4(1,2,3,4); var y=f4(4,3,2,1); x=3?y:x', [4, 3, 2, 1]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + "function f(x) {x=x|0; var v=f4(1,2,3,4); var w=f4(5,6,7,8); return cf4(x?w:v);} return f"), this)(1), [5,6,7,8]);
@@ -292,6 +334,10 @@ assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(x) {x=x
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(v) {v=ci4(v); var w=i4(5,6,7,8); return ci4(4?w:v);} return f"), this)(SIMD.Int32x4(1,2,3,4)), [5,6,7,8]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + "function f(v, x) {v=ci4(v); x=x|0; var w=i4(5,6,7,8); return ci4(x?w:v);} return f"), this)(SIMD.Int32x4(1,2,3,4), 0), [1,2,3,4]);
// Unsigned SIMD types can't be function arguments or return values.
assertAsmTypeFail('glob', USE_ASM + U32 + CU32 + "function f(x) {x=cu4(x);} return f");
assertAsmTypeFail('glob', USE_ASM + U32 + CU32 + "function f() {x=u4(0,0,0,0); return cu4(x);} return f");
// 1.3.4 Return values
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {var x=1; return ci4(x)} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + "function f() {var x=1; return ci4(x + x)} return f");
@@ -395,11 +441,15 @@ assertAsmTypeFail('glob', USE_ASM + F32 + "var g=f4(1., 2., 3., 4.); var f32=glo
assertAsmTypeFail('glob', USE_ASM + F32 + I32 + CI32 + "var g=f4(1., 2., 3., 4.); function f() {var x=i4(1,2,3,4); x=ci4(g);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CF32 + "var g=i4(1,2,3,4); function f() {var x=f4(1.,2.,3.,4.); x=cf4(g);} return f");
assertAsmTypeFail('glob', USE_ASM + U32 + I32 + CI32 + "var g=u4(1,2,3,4); function f() {var x=i4(1,2,3,4); x=ci4(g);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "var g=0; function f() {var x=i4(1,2,3,4); x=g|0;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "var g=0.; function f() {var x=i4(1,2,3,4); x=+g;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "var f32=glob.Math.fround; var g=f32(0.); function f() {var x=i4(1,2,3,4); x=f32(g);} return f");
// Unsigned SIMD globals are not allowed.
assertAsmTypeFail('glob', USE_ASM + U32 + "var g=u4(0,0,0,0); function f() {var x=u4(1,2,3,4); x=g;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + "var g=0; function f() {var x=f4(0.,0.,0.,0.); x=g|0;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + "var g=0.; function f() {var x=f4(0.,0.,0.,0.); x=+g;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + "var f32=glob.Math.fround; var g=f32(0.); function f() {var x=f4(0.,0.,0.,0.); x=f32(g);} return f");
@@ -447,6 +497,9 @@ assertEq(SIMD.Int32x4.extractLane(Int32x4, 3), 4);
for (var v of [1, {}, "totally legit SIMD variable", SIMD.Float32x4(1,2,3,4)])
assertCaught(asmCompile('glob', 'ffi', USE_ASM + I32 + CI32 + "var g=ci4(ffi.g); function f() {return ci4(g)} return f"), this, {g: v});
// Unsigned SIMD globals are not allowed.
assertAsmTypeFail('glob', 'ffi', USE_ASM + U32 + CU32 + "var g=cu4(ffi.g); function f() {} return f");
var Float32x4 = asmLink(asmCompile('glob', 'ffi', USE_ASM + F32 + CF32 + "var g=cf4(ffi.g); function f() {return cf4(g)} return f"), this, {g: SIMD.Float32x4(1,2,3,4)})();
assertEq(SIMD.Float32x4.extractLane(Float32x4, 0), 1);
assertEq(SIMD.Float32x4.extractLane(Float32x4, 1), 2);
@@ -492,6 +545,8 @@ assertAsmTypeFail('glob', USE_ASM + "var g = 3; var add = g.add; return {}");
assertAsmTypeFail('glob', USE_ASM + I32 + "var func = i4.doTheHarlemShake; return {}");
assertAsmTypeFail('glob', USE_ASM + I32 + "var div = i4.div; return {}");
assertAsmTypeFail('glob', USE_ASM + "var f32 = glob.Math.fround; var i4a = f32.add; return {}");
// Operation exists, but in a different type.
assertAsmTypeFail('glob', USE_ASM + I32 + "var func = i4.fromUint32x4; return {}");
// 2.2 Linking
assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + I32 + I32A + "function f() {} return f"), {});
@@ -519,6 +574,7 @@ assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(1,2,3,4
assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(1,2,3,4); var y=4; x=i4a(x, y);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(0,0,0,0); var y=4; x=i4a(y, y);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + I32A + "function f() {var x=i4(0,0,0,0); var y=4; y=i4a(x, x);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + I32A + U32 + "function f() {var x=i4(0,0,0,0); var y=u4(1,2,3,4); y=i4a(x, y);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); x=i4a(x, y);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=i4a(x, y);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32A + "function f() {var x=i4(0,0,0,0); var y=f4(4,3,2,1); y=i4a(x, x);} return f");
@@ -535,6 +591,10 @@ CheckI4(I32A, 'var x=i4(1,2,3,4); x=i4a(x,x)', [2,4,6,8]);
CheckI4(I32A, 'var x=i4(' + INT32_MAX + ',2,3,4); var y=i4(1,1,0,3); x=i4a(x,y)', [INT32_MIN,3,3,7]);
CheckI4(I32A, 'var x=i4(' + INT32_MAX + ',2,3,4); var y=i4(1,1,0,3); x=ci4(i4a(x,y))', [INT32_MIN,3,3,7]);
CheckU4(U32A, 'var z=u4(1,2,3,4); var y=u4(0,1,0,3); var x=u4(0,0,0,0); x=u4a(z,y)', [1,3,3,7]);
CheckU4(U32A, 'var x=u4(2,3,4,5); var y=u4(0,1,0,3); x=u4a(x,y)', [2,4,4,8]);
CheckU4(U32A, 'var x=u4(1,2,3,4); x=u4a(x,x)', [2,4,6,8]);
CheckF4(F32A, 'var x=f4(1,2,3,4); x=f4a(x,x)', [2,4,6,8]);
CheckF4(F32A, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4a(x,y)', [5,5,8,6]);
CheckF4(F32A, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4a(x,y)', [Math.fround(13.37) + 4,5,8,6]);
@@ -547,6 +607,12 @@ CheckI4(I32S, 'var x=i4(1,2,3,4); x=i4s(x,x)', [0,0,0,0]);
CheckI4(I32S, 'var x=i4(' + INT32_MIN + ',2,3,4); var y=i4(1,1,0,3); x=i4s(x,y)', [INT32_MAX,1,3,1]);
CheckI4(I32S, 'var x=i4(' + INT32_MIN + ',2,3,4); var y=i4(1,1,0,3); x=ci4(i4s(x,y))', [INT32_MAX,1,3,1]);
CheckU4(U32S, 'var x=u4(1,2,3,4); var y=u4(-1,1,0,2); x=u4s(x,y)', [2,1,3,2]);
CheckU4(U32S, 'var x=u4(5,4,3,2); var y=u4(1,2,3,4); x=u4s(x,y)', [4,2,0,-2>>>0]);
CheckU4(U32S, 'var x=u4(1,2,3,4); x=u4s(x,x)', [0,0,0,0]);
CheckU4(U32S, 'var x=u4(' + INT32_MIN + ',2,3,4); var y=u4(1,1,0,3); x=u4s(x,y)', [INT32_MAX,1,3,1]);
CheckU4(U32S, 'var x=u4(' + INT32_MIN + ',2,3,4); var y=u4(1,1,0,3); x=cu4(u4s(x,y))', [INT32_MAX,1,3,1]);
CheckF4(F32S, 'var x=f4(1,2,3,4); x=f4s(x,x)', [0,0,0,0]);
CheckF4(F32S, 'var x=f4(1,2,3,4); var y=f4(4,3,5,2); x=f4s(x,y)', [-3,-1,-2,2]);
CheckF4(F32S, 'var x=f4(13.37,2,3,4); var y=f4(4,3,5,2); x=f4s(x,y)', [Math.fround(13.37) - 4,-1,-2,2]);
@@ -603,6 +669,16 @@ function CheckUnaryI4(op, checkFunc) {
}
}
function CheckUnaryU4(op, checkFunc) {
var _ = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32U32 + U32 + U32I32 +
'var op=u4.' + op + '; function f(x){x=ci4(x); return ci4(i4u4(op(u4i4(x)))); } return f'), this);
return function(input) {
var simd = SIMD.Int32x4(input[0], input[1], input[2], input[3]);
var res = SIMD.Uint32x4.fromInt32x4Bits(_(simd));
assertEqX4(res, input.map(checkFunc).map(function(x) { return x >>> 0 }));
}
}
function CheckUnaryB4(op, checkFunc) {
var _ = asmLink(asmCompile('glob', USE_ASM + B32 + CB32 + 'var op=b4.' + op + '; function f(x){x=cb4(x); return cb4(op(x)); } return f'), this);
return function(input) {
@@ -614,6 +690,9 @@ function CheckUnaryB4(op, checkFunc) {
CheckUnaryI4('neg', function(x) { return -x })([1, -2, INT32_MIN, INT32_MAX]);
CheckUnaryI4('not', function(x) { return ~x })([1, -2, INT32_MIN, INT32_MAX]);
CheckUnaryU4('neg', function(x) { return -x })([1, -2, INT32_MIN, INT32_MAX]);
CheckUnaryU4('not', function(x) { return ~x })([1, -2, INT32_MIN, INT32_MAX]);
var CheckNotB = CheckUnaryB4('not', function(x) { return !x });
CheckNotB([true, false, true, true]);
CheckNotB([true, true, true, true]);
@@ -714,6 +793,12 @@ CheckI4(RLI, 'var x = i4(1,2,3,4); x = r(x, 1, 42);', [1, 42, 3, 4]);
CheckI4(RLI, 'var x = i4(1,2,3,4); x = r(x, 2, 42);', [1, 2, 42, 4]);
CheckI4(RLI, 'var x = i4(1,2,3,4); x = r(x, 3, 42);', [1, 2, 3, 42]);
const RLU = 'var r = u4.replaceLane;';
CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 0, 42);', [42, 2, 3, 4]);
CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 1, 42);', [1, 42, 3, 4]);
CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 2, 42);', [1, 2, 42, 4]);
CheckU4(RLU, 'var x = u4(1,2,3,4); x = r(x, 3, 42);', [1, 2, 3, 42]);
const RLB = 'var r = b4.replaceLane;';
CheckB4(RLB, 'var x = b4(1,1,0,0); x = r(x, 0, 0);', [false, true, false, false]);
CheckB4(RLB, 'var x = b4(1,1,0,0); x = r(x, 1, 0);', [true, false, false, false]);
@@ -756,6 +841,37 @@ CheckB4(I32+GEI32, 'var x=b4(0,0,0,0); var a=i4(1,2,3,4); var b=i4(-1,1,0,2); x
CheckB4(I32+GEI32, 'var x=b4(0,0,0,0); var a=i4(-1,1,0,2); var b=i4(1,2,3,4); x=ge(a,b)', [F, F, F, F]);
CheckB4(I32+GEI32, 'var x=b4(0,0,0,0); var a=i4(1,0,3,4); var b=i4(1,1,7,0); x=ge(a,b)', [T, F, F, T]);
const EQU32 = 'var eq = u4.equal';
const NEU32 = 'var ne = u4.notEqual';
const LTU32 = 'var lt = u4.lessThan;';
const LEU32 = 'var le = u4.lessThanOrEqual';
const GTU32 = 'var gt = u4.greaterThan;';
const GEU32 = 'var ge = u4.greaterThanOrEqual';
CheckB4(U32+EQU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=eq(a,b)', [F, F, F, F]);
CheckB4(U32+EQU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=eq(a,b)', [F, F, F, F]);
CheckB4(U32+EQU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=eq(a,b)', [T, F, F, F]);
CheckB4(U32+NEU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=ne(a,b)', [T, T, T, T]);
CheckB4(U32+NEU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=ne(a,b)', [T, T, T, T]);
CheckB4(U32+NEU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=ne(a,b)', [F, T, T, T]);
CheckB4(U32+LTU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=lt(a,b)', [T, F, F, F]);
CheckB4(U32+LTU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=lt(a,b)', [F, T, T, T]);
CheckB4(U32+LTU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=lt(a,b)', [F, T, T, F]);
CheckB4(U32+LEU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=le(a,b)', [T, F, F, F]);
CheckB4(U32+LEU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=le(a,b)', [F, T, T, T]);
CheckB4(U32+LEU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=le(a,b)', [T, T, T, F]);
CheckB4(U32+GTU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=gt(a,b)', [F, T, T, T]);
CheckB4(U32+GTU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=gt(a,b)', [T, F, F, F]);
CheckB4(U32+GTU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=gt(a,b)', [F, F, F, T]);
CheckB4(U32+GEU32, 'var x=b4(0,0,0,0); var a=u4(1,2,3,4); var b=u4(-1,1,0,2); x=ge(a,b)', [F, T, T, T]);
CheckB4(U32+GEU32, 'var x=b4(0,0,0,0); var a=u4(-1,1,0,2); var b=u4(1,2,3,4); x=ge(a,b)', [T, F, F, F]);
CheckB4(U32+GEU32, 'var x=b4(0,0,0,0); var a=u4(1,0,3,4); var b=u4(1,1,7,0); x=ge(a,b)', [T, F, F, T]);
const LTF32 = 'var lt=f4.lessThan;';
const LEF32 = 'var le=f4.lessThanOrEqual;';
const GTF32 = 'var gt=f4.greaterThan;';
@@ -808,8 +924,13 @@ assertEq(f(SIMD.Int32x4(1,2,3,5)), 0);
// Conversions operators
const CVTIF = 'var cvt=f4.fromInt32x4;';
const CVTFI = 'var cvt=i4.fromFloat32x4;';
const CVTUF = 'var cvt=f4.fromUint32x4;';
const CVTFU = 'var cvt=u4.fromFloat32x4;';
assertAsmTypeFail('glob', USE_ASM + I32 + "var cvt=i4.fromInt32x4; return {}");
assertAsmTypeFail('glob', USE_ASM + I32 + "var cvt=i4.fromUint32x4; return {}");
assertAsmTypeFail('glob', USE_ASM + U32 + "var cvt=u4.fromInt32x4; return {}");
assertAsmTypeFail('glob', USE_ASM + U32 + "var cvt=u4.fromUint32x4; return {}");
assertAsmTypeFail('glob', USE_ASM + F32 + "var cvt=f4.fromFloat32x4; return {}");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=i4(1,2,3,4); x=cvt(x);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=f4(1,2,3,4); x=cvt(x);} return f");
@@ -818,6 +939,11 @@ var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CF32 + CI32 + CVTIF + '
assertEqX4(f(SIMD.Int32x4(1,2,3,4)), [1, 2, 3, 4]);
assertEqX4(f(SIMD.Int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, Math.fround(INT32_MIN), Math.fround(INT32_MAX), -1]);
var f = asmLink(asmCompile('glob', USE_ASM + I32 + U32 + U32I32 + F32 + CF32 + CI32 + CVTUF +
'function f(x){x=ci4(x); var y=f4(0,0,0,0); y=cvt(u4i4(x)); return cf4(y);} return f'), this);
assertEqX4(f(SIMD.Int32x4(1,2,3,4)), [1, 2, 3, 4]);
assertEqX4(f(SIMD.Int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, Math.fround(INT32_MAX+1), Math.fround(INT32_MAX), Math.fround(UINT32_MAX)]);
var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + F32 + CF32 + CVTFI + 'function f(x){x=cf4(x); var y=i4(0,0,0,0); y=cvt(x); return ci4(y);} return f'), this);
assertEqX4(f(SIMD.Float32x4(1,2,3,4)), [1, 2, 3, 4]);
// Test that INT32_MIN (exactly representable as an float32) and the first
@@ -832,6 +958,20 @@ assertThrowsInstanceOf(() => f(SIMD.Float32x4(NaN, 0, 0, 0)), RangeError);
assertThrowsInstanceOf(() => f(SIMD.Float32x4(Infinity, 0, 0, 0)), RangeError);
assertThrowsInstanceOf(() => f(SIMD.Float32x4(-Infinity, 0, 0, 0)), RangeError);
var f = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + U32 + I32U32 + F32 + CF32 + CVTFU +
'function f(x){x=cf4(x); var y=u4(0,0,0,0); y=cvt(x); return ci4(i4u4(y));} return f'), this);
assertEqX4(f(SIMD.Float32x4(1,2,3,4)), [1, 2, 3, 4]);
// TODO: Test negative numbers > -1. They should truncate to 0. See https://github.com/tc39/ecmascript_simd/issues/315
assertEqX4(SIMD.Uint32x4.fromInt32x4Bits(f(SIMD.Float32x4(0xffffff00, INT32_MAX+1, -0, 0))),
[0xffffff00, INT32_MAX+1, 0, 0].map(Math.fround));
// Test boundaries: -1 or less.
assertThrowsInstanceOf(() => f(SIMD.Float32x4(-1, 0, 0, 0)), RangeError);
assertThrowsInstanceOf(() => f(SIMD.Float32x4(Math.pow(2, 32), 0, 0, 0)), RangeError);
// Special values
assertThrowsInstanceOf(() => f(SIMD.Float32x4(NaN, 0, 0, 0)), RangeError);
assertThrowsInstanceOf(() => f(SIMD.Float32x4(Infinity, 0, 0, 0)), RangeError);
assertThrowsInstanceOf(() => f(SIMD.Float32x4(-Infinity, 0, 0, 0)), RangeError);
// Cast operators
const CVTIFB = 'var cvt=f4.fromInt32x4Bits;';
const CVTFIB = 'var cvt=i4.fromFloat32x4Bits;';
@@ -886,6 +1026,14 @@ CheckI4(ANDI32, 'var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=andd(x,y)', [
CheckI4(ORI32, ' var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=orr(x,y)', [42 | 2, 1337 | 4, -1 | 7, 13 | 15]);
CheckI4(XORI32, 'var x=i4(42,1337,-1,13); var y=i4(2, 4, 7, 15); x=xorr(x,y)', [42 ^ 2, 1337 ^ 4, -1 ^ 7, 13 ^ 15]);
const ANDU32 = 'var andd=u4.and;';
const ORU32 = 'var orr=u4.or;';
const XORU32 = 'var xorr=u4.xor;';
CheckU4(ANDU32, 'var x=u4(42,1337,-1,13); var y=u4(2, 4, 7, 15); x=andd(x,y)', [42 & 2, 1337 & 4, (-1 & 7) >>> 0, 13 & 15]);
CheckU4(ORU32, ' var x=u4(42,1337,-1,13); var y=u4(2, 4, 7, 15); x=orr(x,y)', [42 | 2, 1337 | 4, (-1 | 7) >>> 0, 13 | 15]);
CheckU4(XORU32, 'var x=u4(42,1337,-1,13); var y=u4(2, 4, 7, 15); x=xorr(x,y)', [42 ^ 2, 1337 ^ 4, (-1 ^ 7) >>> 0, 13 ^ 15]);
const ANDB32 = 'var andd=b4.and;';
const ORB32 = 'var orr=b4.or;';
const XORB32 = 'var xorr=b4.xor;';
@@ -908,8 +1056,6 @@ assertAsmTypeFail('glob', USE_ASM + F32 + CF32 + NOTF32 + 'function f() {var x=f
// Logical ops
const LSHI = 'var lsh=i4.shiftLeftByScalar;'
const RSHI = 'var rsh=i4.shiftRightByScalar;'
const ARSHI = 'var arsh=i4.shiftRightArithmeticByScalar;'
const URSHI = 'var ursh=i4.shiftRightLogicalByScalar;'
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,f32(42)));} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return ci4(lsh(x,42));} return f");
@@ -919,33 +1065,49 @@ assertAsmTypeFail('glob', USE_ASM + I32 + CI32 + FROUND + LSHI + "function f() {
var input = 'i4(0, 1, ' + INT32_MIN + ', ' + INT32_MAX + ')';
var vinput = [0, 1, INT32_MIN, INT32_MAX];
// TODO: What to do for masks > 31? Should we keep only the five low bits of
// the mask (JS) or not (x86)?
// Behave as x86 for now, fix when more broadly specified. See also bug 1068028
function Lsh(i) { if (i > 31) return () => 0; return function(x) { return (x << i) | 0 } }
function Rsh(i) { if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } }
function Arsh(i) { if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } }
function Ursh(i) { if (i > 31) return () => 0; return function(x) { return (x >>> i) | 0 } }
function Lsh(i) { return function(x) { return (x << (i & 31)) | 0 } }
function Rsh(i) { return function(x) { return (x >> (i & 31)) | 0 } }
var asmLsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + LSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(lsh(v, x+y))} return f;'), this)
var asmRsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + RSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(rsh(v, x+y))} return f;'), this)
var asmArsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + ARSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(arsh(v, x+y))} return f;'), this)
var asmUrsh = asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + URSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(ursh(v, x+y))} return f;'), this)
for (var i = 1; i < 64; i++) {
CheckI4(LSHI, 'var x=' + input + '; x=lsh(x, ' + i + ')', vinput.map(Lsh(i)));
CheckI4(RSHI, 'var x=' + input + '; x=rsh(x, ' + i + ')', vinput.map(Rsh(i)));
CheckI4(ARSHI, 'var x=' + input + '; x=arsh(x, ' + i + ')', vinput.map(Arsh(i)));
CheckI4(URSHI, 'var x=' + input + '; x=ursh(x, ' + i + ')', vinput.map(Ursh(i)));
assertEqX4(asmLsh(i, 3), vinput.map(Lsh(i + 3)));
assertEqX4(asmRsh(i, 3), vinput.map(Rsh(i + 3)));
assertEqX4(asmArsh(i, 3), vinput.map(Arsh(i + 3)));
assertEqX4(asmUrsh(i, 3), vinput.map(Ursh(i + 3)));
}
// Same thing for Uint32x4.
const LSHU = 'var lsh=u4.shiftLeftByScalar;'
const RSHU = 'var rsh=u4.shiftRightByScalar;'
input = 'u4(0, 1, 0x80008000, ' + INT32_MAX + ')';
vinput = [0, 1, 0x80008000, INT32_MAX];
function uLsh(i) { return function(x) { return (x << (i & 31)) >>> 0 } }
function uRsh(i) { return function(x) { return (x >>> (i & 31)) } }
// Need to bitcast to Int32x4 before returning result.
asmLsh = asmLink(asmCompile('glob', USE_ASM + U32 + CU32 + LSHU + I32 + CI32 + I32U32 +
'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(i4u4(lsh(v, x+y)));} return f;'), this)
asmRsh = asmLink(asmCompile('glob', USE_ASM + U32 + CU32 + RSHU + I32 + CI32 + I32U32 +
'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return ci4(i4u4(rsh(v, x+y)));} return f;'), this)
for (var i = 1; i < 64; i++) {
// Constant shifts.
CheckU4(LSHU, 'var x=' + input + '; x=lsh(x, ' + i + ')', vinput.map(uLsh(i)));
CheckU4(RSHU, 'var x=' + input + '; x=rsh(x, ' + i + ')', vinput.map(uRsh(i)));
// Dynamically computed shifts. The asm function returns a Int32x4.
assertEqX4(SIMD.Uint32x4.fromInt32x4Bits(asmLsh(i, 3)), vinput.map(uLsh(i + 3)));
assertEqX4(SIMD.Uint32x4.fromInt32x4Bits(asmRsh(i, 3)), vinput.map(uRsh(i + 3)));
}
// Select
const I32SEL = 'var i4sel = i4.select;'
const U32SEL = 'var u4sel = u4.select;'
const F32SEL = 'var f4sel = f4.select;'
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + B32 + CI32 + I32SEL + "function f() {var x=f4(1,2,3,4); return ci4(i4sel(x,x,x));} return f");
@@ -975,8 +1137,14 @@ assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + B32 + F32 + CF32 + F32SEL
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + B32 + F32 + CF32 + F32SEL + "function f() {var m=b4(0,1,0,1); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + B32 + F32 + CF32 + F32SEL + "function f() {var m=b4(0,0,1,1); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return cf4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
CheckU4(B32 + U32SEL, "var m=b4(0,0,0,0); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [5, 6, 7, 8]);
CheckU4(B32 + U32SEL, "var m=b4(1,1,1,1); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [1, 2, 3, 4]);
CheckU4(B32 + U32SEL, "var m=b4(0,1,0,1); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [5, 2, 7, 4]);
CheckU4(B32 + U32SEL, "var m=b4(0,0,1,1); var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=u4sel(m,x,y);", [5, 6, 3, 4]);
// Splat
const I32SPLAT = 'var splat=i4.splat;'
const U32SPLAT = 'var splat=u4.splat;'
const F32SPLAT = 'var splat=f4.splat;'
const B32SPLAT = 'var splat=b4.splat;'
@@ -991,6 +1159,8 @@ assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + FROUND + "function f() {var
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + CI32 + I32SPLAT + 'function f(){return ci4(splat(42));} return f'), this)(), [42, 42, 42, 42]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + B32 + CB32 + B32SPLAT + 'function f(){return cb4(splat(42));} return f'), this)(), [true, true, true, true]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + B32 + CB32 + B32SPLAT + 'function f(){return cb4(splat(0));} return f'), this)(), [false, false, false, false]);
CheckU4(B32 + U32SPLAT, "var x=u4(1,2,3,4); x=splat(0);", [0, 0, 0, 0]);
CheckU4(B32 + U32SPLAT, "var x=u4(1,2,3,4); x=splat(0xaabbccdd);", [0xaabbccdd, 0xaabbccdd, 0xaabbccdd, 0xaabbccdd]);
const l33t = Math.fround(13.37);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + CF32 + F32SPLAT + FROUND + 'function f(){return cf4(splat(f32(1)));} return f'), this)(), [1, 1, 1, 1]);
@@ -1030,6 +1200,7 @@ var before = Date.now();
for (var i = 0; i < Math.pow(4, 4); i++) {
var lanes = [i & 3, (i >> 2) & 3, (i >> 4) & 3, (i >> 6) & 3];
CheckI4('var swizzle=i4.swizzle;', 'var x=i4(1,2,3,4); x=swizzle(x, ' + lanes.join(',') + ')', swizzle([1,2,3,4], lanes));
CheckU4('var swizzle=u4.swizzle;', 'var x=u4(1,2,3,4); x=swizzle(x, ' + lanes.join(',') + ')', swizzle([1,2,3,4], lanes));
CheckF4('var swizzle=f4.swizzle;', 'var x=f4(1,2,3,4); x=swizzle(x, ' + lanes.join(',') + ')', swizzle([1,2,3,4], lanes));
}
DEBUG && print('time for checking all swizzles:', Date.now() - before);
@@ -1102,6 +1273,7 @@ const LANE_SELECTORS = [
for (var lanes of LANE_SELECTORS) {
CheckI4('var shuffle=i4.shuffle;', 'var x=i4(1,2,3,4); var y=i4(5,6,7,8); x=shuffle(x, y, ' + lanes.join(',') + ')', shuffle([1,2,3,4], [5,6,7,8], lanes));
CheckU4('var shuffle=u4.shuffle;', 'var x=u4(1,2,3,4); var y=u4(5,6,7,8); x=shuffle(x, y, ' + lanes.join(',') + ')', shuffle([1,2,3,4], [5,6,7,8], lanes));
CheckF4('var shuffle=f4.shuffle;', 'var x=f4(1,2,3,4); var y=f4(5,6,7,8); x=shuffle(x, y, ' + lanes.join(',') + ')', shuffle([1,2,3,4], [5,6,7,8], lanes));
}
DEBUG && print('time for checking all shuffles:', Date.now() - before);
@@ -1121,11 +1293,13 @@ assertAsmTypeFail('glob', USE_ASM + I32 + "var pow=glob.Math.pow; function f() {
// 3.2. FFI calls
// Can't pass SIMD arguments to FFI
assertAsmTypeFail('glob', 'ffi', USE_ASM + I32 + "var func=ffi.func; function f() {var x=i4(1,2,3,4); func(x);} return f");
assertAsmTypeFail('glob', 'ffi', USE_ASM + U32 + "var func=ffi.func; function f() {var x=u4(1,2,3,4); func(x);} return f");
assertAsmTypeFail('glob', 'ffi', USE_ASM + F32 + "var func=ffi.func; function f() {var x=f4(1,2,3,4); func(x);} return f");
assertAsmTypeFail('glob', 'ffi', USE_ASM + B32 + "var func=ffi.func; function f() {var x=b4(1,2,3,4); func(x);} return f");
// Can't have FFI return SIMD values
assertAsmTypeFail('glob', 'ffi', USE_ASM + I32 + "var func=ffi.func; function f() {var x=i4(1,2,3,4); x=i4(func());} return f");
assertAsmTypeFail('glob', 'ffi', USE_ASM + U32 + "var func=ffi.func; function f() {var x=u4(1,2,3,4); x=i4(func());} return f");
assertAsmTypeFail('glob', 'ffi', USE_ASM + F32 + "var func=ffi.func; function f() {var x=f4(1,2,3,4); x=f4(func());} return f");
assertAsmTypeFail('glob', 'ffi', USE_ASM + B32 + "var func=ffi.func; function f() {var x=b4(1,2,3,4); x=b4(func());} return f");
+13 -12
View File
@@ -87,8 +87,11 @@ wasmEvalText('(module (func (result i32) (param i32) (i32.const 42)))');
wasmEvalText('(module (func (param f32)))');
wasmEvalText('(module (func (param f64)))');
assertErrorMessage(() => wasmEvalText('(module (func (param i64)))'), TypeError, /NYI/);
assertErrorMessage(() => wasmEvalText('(module (func (result i64)))'), TypeError, /NYI/);
var hasI64 = getBuildConfiguration().x64;
if (!hasI64) {
assertErrorMessage(() => wasmEvalText('(module (func (param i64)))'), TypeError, /NYI/);
assertErrorMessage(() => wasmEvalText('(module (func (result i64)))'), TypeError, /NYI/);
}
// ----------------------------------------------------------------------------
// imports
@@ -223,7 +226,8 @@ wasmEvalText('(module (func (local i32) (local f32) (set_local 1 (get_local 1)))
assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (i32.const 42))) (export "" 0))')(), 42);
assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (get_local 0))) (export "" 0))')(), 0);
assertErrorMessage(() => wasmEvalText('(module (func (local i64)))'), TypeError, /NYI/);
if (!hasI64)
assertErrorMessage(() => wasmEvalText('(module (func (local i64)))'), TypeError, /NYI/);
assertEq(wasmEvalText('(module (func (param $a i32) (result i32) (get_local $a)) (export "" 0))')(), 0);
assertEq(wasmEvalText('(module (func (param $a i32) (local $b i32) (result i32) (block (set_local $b (get_local $a)) (get_local $b))) (export "" 0))')(42), 42);
@@ -348,15 +352,12 @@ for (bad of [6, 7, 100, Math.pow(2,31)-1, Math.pow(2,31), Math.pow(2,31)+1, Math
assertThrowsInstanceOf(() => i2v(bad, 0), RangeError);
}
// When the test below starts failing, remove it and uncomment the lines below!
assertErrorMessage(() => wasmEvalText('(module (func (param i64)))'), TypeError, /NYI/);
/*
assertErrorMessage(() => wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))'), TypeError, /i64 argument/);
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))'), TypeError, /i64 return type/);
assertErrorMessage(() => wasmEvalText('(module (import "a" "" (param i64) (result i32)))'), TypeError, /i64 argument/);
assertErrorMessage(() => wasmEvalText('(module (import "a" "" (result i64)))'), TypeError, /i64 return type/);
*/
if (hasI64) {
assertErrorMessage(() => wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))'), TypeError, /i64 argument/);
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))'), TypeError, /i64 return type/);
assertErrorMessage(() => wasmEvalText('(module (import "a" "" (param i64) (result i32)))'), TypeError, /i64 argument/);
assertErrorMessage(() => wasmEvalText('(module (import "a" "" (result i64)))'), TypeError, /i64 return type/);
}
var {v2i, i2i, i2v} = wasmEvalText(`(module
(type $a (func (result i32)))
+11 -5
View File
@@ -2490,6 +2490,12 @@ CodeGenerator::visitInteger(LInteger* lir)
masm.move32(Imm32(lir->getValue()), ToRegister(lir->output()));
}
void
CodeGenerator::visitInteger64(LInteger64* lir)
{
masm.move64(Imm64(lir->getValue()), ToOutRegister64(lir));
}
void
CodeGenerator::visitPointer(LPointer* lir)
{
@@ -9312,23 +9318,23 @@ CodeGenerator::visitToIdV(LToIdV* lir)
Label notInt32;
FloatRegister temp = ToFloatRegister(lir->tempFloat());
const ValueOperand out = ToOutValue(lir);
ValueOperand index = ToValue(lir, LToIdV::Index);
ValueOperand input = ToValue(lir, LToIdV::Input);
OutOfLineCode* ool = oolCallVM(ToIdInfo, lir,
ArgList(ImmGCPtr(current->mir()->info().script()),
ImmPtr(lir->mir()->resumePoint()->pc()),
ToValue(lir, LToIdV::Index)),
ToValue(lir, LToIdV::Input)),
StoreValueTo(out));
Register tag = masm.splitTagForTest(index);
Register tag = masm.splitTagForTest(input);
masm.branchTestInt32(Assembler::NotEqual, tag, &notInt32);
masm.moveValue(index, out);
masm.moveValue(input, out);
masm.jump(ool->rejoin());
masm.bind(&notInt32);
masm.branchTestDouble(Assembler::NotEqual, tag, ool->entry());
masm.unboxDouble(index, temp);
masm.unboxDouble(input, temp);
masm.convertDoubleToInt32(temp, out.scratchReg(), ool->entry(), true);
masm.tagValue(JSVAL_TYPE_INT32, out.scratchReg(), out);
+1
View File
@@ -106,6 +106,7 @@ class CodeGenerator : public CodeGeneratorSpecific
void visitValueToString(LValueToString* lir);
void visitValueToObjectOrNull(LValueToObjectOrNull* lir);
void visitInteger(LInteger* lir);
void visitInteger64(LInteger64* lir);
void visitRegExp(LRegExp* lir);
void visitRegExpMatcher(LRegExpMatcher* lir);
void visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool);
+57
View File
@@ -50,6 +50,8 @@ static const uint32_t PAYLOAD_INDEX = 1;
# error "Unknown!"
#endif
static const uint32_t INT64_PIECES = sizeof(int64_t) / sizeof(uintptr_t);
// Represents storage for an operand. For constants, the pointer is tagged
// with a single bit, and the untagged pointer is a pointer to a Value.
class LAllocation : public TempObject
@@ -291,6 +293,50 @@ class LUse : public LAllocation
static const uint32_t MAX_VIRTUAL_REGISTERS = LUse::VREG_MASK;
class LBoxAllocation
{
#ifdef JS_NUNBOX32
LAllocation type_;
LAllocation payload_;
#else
LAllocation value_;
#endif
public:
#ifdef JS_NUNBOX32
LBoxAllocation(LAllocation type, LAllocation payload) : type_(type), payload_(payload) {}
LAllocation type() const { return type_; }
LAllocation payload() const { return payload_; }
#else
explicit LBoxAllocation(LAllocation value) : value_(value) {}
LAllocation value() const { return value_; }
#endif
};
class LInt64Allocation
{
#if JS_BITS_PER_WORD == 32
LAllocation high_;
LAllocation low_;
#else
LAllocation value_;
#endif
public:
#if JS_BITS_PER_WORD == 32
LInt64Allocation(LAllocation high, LAllocation low) : high_(high), low_(low) {}
LAllocation high() const { return high_; }
LAllocation low() const { return low_; }
#else
explicit LInt64Allocation(LAllocation value) : value_(value) {}
LAllocation value() const { return value_; }
#endif
};
class LGeneralReg : public LAllocation
{
public:
@@ -567,6 +613,9 @@ class LDefinition
case MIRType_Elements:
return LDefinition::SLOTS;
case MIRType_Pointer:
#if JS_BITS_PER_WORD == 64
case MIRType_Int64:
#endif
return LDefinition::GENERAL;
case MIRType_Bool32x4:
case MIRType_Int32x4:
@@ -1050,6 +1099,14 @@ class LInstructionHelper : public details::LInstructionFixedDefsTempsHelper<Defs
void setOperand(size_t index, const LAllocation& a) final override {
operands_[index] = a;
}
void setBoxOperand(size_t index, const LBoxAllocation& alloc) {
#ifdef JS_NUNBOX32
operands_[index] = alloc.type();
operands_[index + 1] = alloc.payload();
#else
operands_[index] = alloc.value();
#endif
}
};
template<size_t Defs, size_t Temps>
+135 -184
View File
@@ -24,22 +24,22 @@ using namespace jit;
using mozilla::DebugOnly;
using JS::GenericNaN;
void
LIRGenerator::useBoxAtStart(LInstruction* lir, size_t n, MDefinition* mir, LUse::Policy policy)
{
return useBox(lir, n, mir, policy, true);
}
void
LIRGenerator::useBoxFixedAtStart(LInstruction* lir, size_t n, MDefinition* mir, ValueOperand op)
LBoxAllocation
LIRGenerator::useBoxFixedAtStart(MDefinition* mir, ValueOperand op)
{
#if defined(JS_NUNBOX32)
return useBoxFixed(lir, n, mir, op.typeReg(), op.payloadReg(), true);
return useBoxFixed(mir, op.typeReg(), op.payloadReg(), true);
#elif defined(JS_PUNBOX64)
return useBoxFixed(lir, n, mir, op.valueReg(), op.scratchReg(), true);
return useBoxFixed(mir, op.valueReg(), op.scratchReg(), true);
#endif
}
LBoxAllocation
LIRGenerator::useBoxAtStart(MDefinition* mir, LUse::Policy policy)
{
return useBox(mir, policy, /* useAtStart = */ true);
}
void
LIRGenerator::visitCloneLiteral(MCloneLiteral* ins)
{
@@ -155,7 +155,6 @@ LIRGenerator::visitTableSwitch(MTableSwitch* tableswitch)
// If we don't know the type.
if (opd->type() == MIRType_Value) {
LTableSwitchV* lir = newLTableSwitchV(tableswitch);
useBox(lir, LTableSwitchV::InputValue, opd);
add(lir);
return;
}
@@ -312,9 +311,9 @@ LIRGenerator::visitNewStringObject(MNewStringObject* ins)
void
LIRGenerator::visitInitElem(MInitElem* ins)
{
LInitElem* lir = new(alloc()) LInitElem(useRegisterAtStart(ins->getObject()));
useBoxAtStart(lir, LInitElem::IdIndex, ins->getId());
useBoxAtStart(lir, LInitElem::ValueIndex, ins->getValue());
LInitElem* lir = new(alloc()) LInitElem(useRegisterAtStart(ins->getObject()),
useBoxAtStart(ins->getId()),
useBoxAtStart(ins->getValue()));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -324,8 +323,8 @@ LIRGenerator::visitInitElemGetterSetter(MInitElemGetterSetter* ins)
{
LInitElemGetterSetter* lir =
new(alloc()) LInitElemGetterSetter(useRegisterAtStart(ins->object()),
useBoxAtStart(ins->idValue()),
useRegisterAtStart(ins->value()));
useBoxAtStart(lir, LInitElemGetterSetter::IdIndex, ins->idValue());
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -333,8 +332,8 @@ LIRGenerator::visitInitElemGetterSetter(MInitElemGetterSetter* ins)
void
LIRGenerator::visitMutateProto(MMutateProto* ins)
{
LMutateProto* lir = new(alloc()) LMutateProto(useRegisterAtStart(ins->getObject()));
useBoxAtStart(lir, LMutateProto::ValueIndex, ins->getValue());
LMutateProto* lir = new(alloc()) LMutateProto(useRegisterAtStart(ins->getObject()),
useBoxAtStart(ins->getValue()));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -342,8 +341,8 @@ LIRGenerator::visitMutateProto(MMutateProto* ins)
void
LIRGenerator::visitInitProp(MInitProp* ins)
{
LInitProp* lir = new(alloc()) LInitProp(useRegisterAtStart(ins->getObject()));
useBoxAtStart(lir, LInitProp::ValueIndex, ins->getValue());
LInitProp* lir = new(alloc()) LInitProp(useRegisterAtStart(ins->getObject()),
useBoxAtStart(ins->getValue()));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -408,16 +407,16 @@ void
LIRGenerator::visitSetArgumentsObjectArg(MSetArgumentsObjectArg* ins)
{
LAllocation argsObj = useRegister(ins->getArgsObject());
LSetArgumentsObjectArg* lir = new(alloc()) LSetArgumentsObjectArg(argsObj, temp());
useBox(lir, LSetArgumentsObjectArg::ValueIndex, ins->getValue());
LSetArgumentsObjectArg* lir =
new(alloc()) LSetArgumentsObjectArg(argsObj, useBox(ins->getValue()), temp());
add(lir, ins);
}
void
LIRGenerator::visitReturnFromCtor(MReturnFromCtor* ins)
{
LReturnFromCtor* lir = new(alloc()) LReturnFromCtor(useRegister(ins->getObject()));
useBox(lir, LReturnFromCtor::ValueIndex, ins->getValue());
LReturnFromCtor* lir = new(alloc()) LReturnFromCtor(useBox(ins->getValue()),
useRegister(ins->getObject()));
define(lir, ins);
}
@@ -427,13 +426,10 @@ LIRGenerator::visitComputeThis(MComputeThis* ins)
MOZ_ASSERT(ins->type() == MIRType_Value);
MOZ_ASSERT(ins->input()->type() == MIRType_Value);
LComputeThis* lir = new(alloc()) LComputeThis();
// Don't use useBoxAtStart because ComputeThis has a safepoint and needs to
// have its inputs in different registers than its return value so that
// they aren't clobbered.
useBox(lir, LComputeThis::ValueIndex, ins->input());
LComputeThis* lir = new(alloc()) LComputeThis(useBox(ins->input()));
defineBox(lir, ins);
assignSafepoint(lir, ins);
}
@@ -472,8 +468,7 @@ LIRGenerator::lowerCallArguments(MCall* call)
// Values take a slow path.
if (arg->type() == MIRType_Value) {
LStackArgV* stack = new(alloc()) LStackArgV(argslot);
useBox(stack, 0, arg);
LStackArgV* stack = new(alloc()) LStackArgV(argslot, useBox(arg));
add(stack);
} else {
// Known types can move constant types and/or payloads.
@@ -554,12 +549,10 @@ LIRGenerator::visitApplyArgs(MApplyArgs* apply)
LApplyArgsGeneric* lir = new(alloc()) LApplyArgsGeneric(
useFixed(apply->getFunction(), CallTempReg3),
useFixed(apply->getArgc(), CallTempReg0),
useBoxFixed(apply->getThis(), CallTempReg4, CallTempReg5),
tempFixed(CallTempReg1), // object register
tempFixed(CallTempReg2)); // stack counter register
MDefinition* self = apply->getThis();
useBoxFixed(lir, LApplyArgsGeneric::ThisIndex, self, CallTempReg4, CallTempReg5);
// Bailout is only needed in the case of possible non-JSFunction callee.
if (!apply->getSingleTarget())
assignSnapshot(lir, Bailout_NonJSFunctionCallee);
@@ -582,15 +575,13 @@ LIRGenerator::visitApplyArray(MApplyArray* apply)
MOZ_ASSERT(CallTempReg2 != JSReturnReg_Data);
LApplyArrayGeneric* lir = new(alloc()) LApplyArrayGeneric(
useFixed(apply->getFunction(), CallTempReg3),
useFixed(apply->getElements(), CallTempReg0),
useFixedAtStart(apply->getFunction(), CallTempReg3),
useFixedAtStart(apply->getElements(), CallTempReg0),
useBoxFixed(apply->getThis(), CallTempReg4, CallTempReg5),
tempFixed(CallTempReg1), // object register
tempFixed(CallTempReg2)); // stack counter register
MDefinition* self = apply->getThis();
useBoxFixed(lir, LApplyArrayGeneric::ThisIndex, self, CallTempReg4, CallTempReg5);
// Bailout is needed in the case of possible non-JSFunction callee
// Bailout is needed in the case of possible non-JSFunction callee,
// too many values in the array, or empty space at the end of the
// array. I'm going to use NonJSFunctionCallee for the code even
// if that is not an adequate description.
@@ -682,9 +673,8 @@ LIRGenerator::visitCallDirectEval(MCallDirectEval* ins)
MDefinition* newTargetValue = ins->getNewTargetValue();
LInstruction* lir = new(alloc()) LCallDirectEval(useRegisterAtStart(scopeChain),
useRegisterAtStart(string));
useBoxAtStart(lir, LCallDirectEval::NewTarget, newTargetValue);
useRegisterAtStart(string),
useBoxAtStart(newTargetValue));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -733,8 +723,7 @@ LIRGenerator::visitTest(MTest* test)
temp1 = LDefinition::BogusTemp();
}
LTestVAndBranch* lir =
new(alloc()) LTestVAndBranch(ifTrue, ifFalse, tempDouble(), temp0, temp1);
useBox(lir, LTestVAndBranch::Input, opd);
new(alloc()) LTestVAndBranch(ifTrue, ifFalse, useBox(opd), tempDouble(), temp0, temp1);
add(lir, test);
return;
}
@@ -814,9 +803,8 @@ LIRGenerator::visitTest(MTest* test)
}
LIsNullOrLikeUndefinedAndBranchV* lir =
new(alloc()) LIsNullOrLikeUndefinedAndBranchV(comp, ifTrue, ifFalse,
new(alloc()) LIsNullOrLikeUndefinedAndBranchV(comp, ifTrue, ifFalse, useBox(left),
tmp, tmpToUnbox);
useBox(lir, LIsNullOrLikeUndefinedAndBranchV::Value, left);
add(lir, test);
return;
}
@@ -826,9 +814,9 @@ LIRGenerator::visitTest(MTest* test)
MOZ_ASSERT(left->type() == MIRType_Value);
MOZ_ASSERT(right->type() == MIRType_Boolean);
LAllocation rhs = useRegisterOrConstant(right);
LCompareBAndBranch* lir = new(alloc()) LCompareBAndBranch(comp, rhs, ifTrue, ifFalse);
useBox(lir, LCompareBAndBranch::Lhs, left);
LCompareBAndBranch* lir = new(alloc()) LCompareBAndBranch(comp, useBox(left),
useRegisterOrConstant(right),
ifTrue, ifFalse);
add(lir, test);
return;
}
@@ -874,9 +862,9 @@ LIRGenerator::visitTest(MTest* test)
// Compare values.
if (comp->compareType() == MCompare::Compare_Bitwise) {
LCompareBitwiseAndBranch* lir =
new(alloc()) LCompareBitwiseAndBranch(comp, ifTrue, ifFalse);
useBoxAtStart(lir, LCompareBitwiseAndBranch::LhsInput, left);
useBoxAtStart(lir, LCompareBitwiseAndBranch::RhsInput, right);
new(alloc()) LCompareBitwiseAndBranch(comp, ifTrue, ifFalse,
useBoxAtStart(left),
useBoxAtStart(right));
add(lir, test);
return;
}
@@ -898,8 +886,8 @@ LIRGenerator::visitTest(MTest* test)
MDefinition* input = opd->toIsObject()->input();
MOZ_ASSERT(input->type() == MIRType_Value);
LIsObjectAndBranch* lir = new(alloc()) LIsObjectAndBranch(ifTrue, ifFalse);
useBoxAtStart(lir, LIsObjectAndBranch::Input, input);
LIsObjectAndBranch* lir = new(alloc()) LIsObjectAndBranch(ifTrue, ifFalse,
useBoxAtStart(input));
add(lir, test);
return;
}
@@ -910,8 +898,8 @@ LIRGenerator::visitTest(MTest* test)
MDefinition* input = opd->toIsNoIter()->input();
MOZ_ASSERT(input->type() == MIRType_Value);
LIsNoIterAndBranch* lir = new(alloc()) LIsNoIterAndBranch(ifTrue, ifFalse);
useBox(lir, LIsNoIterAndBranch::Input, input);
LIsNoIterAndBranch* lir = new(alloc()) LIsNoIterAndBranch(ifTrue, ifFalse,
useBox(input));
add(lir, test);
return;
}
@@ -1000,8 +988,8 @@ LIRGenerator::visitCompare(MCompare* comp)
MOZ_ASSERT(left->type() == MIRType_Value);
MOZ_ASSERT(right->type() == MIRType_String);
LCompareStrictS* lir = new(alloc()) LCompareStrictS(useRegister(right), tempToUnbox());
useBox(lir, LCompareStrictS::Lhs, left);
LCompareStrictS* lir = new(alloc()) LCompareStrictS(useBox(left), useRegister(right),
tempToUnbox());
define(lir, comp);
assignSafepoint(lir, comp);
return;
@@ -1009,9 +997,7 @@ LIRGenerator::visitCompare(MCompare* comp)
// Unknown/unspecialized compare use a VM call.
if (comp->compareType() == MCompare::Compare_Unknown) {
LCompareVM* lir = new(alloc()) LCompareVM();
useBoxAtStart(lir, LCompareVM::LhsInput, left);
useBoxAtStart(lir, LCompareVM::RhsInput, right);
LCompareVM* lir = new(alloc()) LCompareVM(useBoxAtStart(left), useBoxAtStart(right));
defineReturn(lir, comp);
assignSafepoint(lir, comp);
return;
@@ -1048,8 +1034,8 @@ LIRGenerator::visitCompare(MCompare* comp)
tmpToUnbox = LDefinition::BogusTemp();
}
LIsNullOrLikeUndefinedV* lir = new(alloc()) LIsNullOrLikeUndefinedV(tmp, tmpToUnbox);
useBox(lir, LIsNullOrLikeUndefinedV::Value, left);
LIsNullOrLikeUndefinedV* lir = new(alloc()) LIsNullOrLikeUndefinedV(useBox(left),
tmp, tmpToUnbox);
define(lir, comp);
return;
}
@@ -1059,8 +1045,7 @@ LIRGenerator::visitCompare(MCompare* comp)
MOZ_ASSERT(left->type() == MIRType_Value);
MOZ_ASSERT(right->type() == MIRType_Boolean);
LCompareB* lir = new(alloc()) LCompareB(useRegisterOrConstant(right));
useBox(lir, LCompareB::Lhs, left);
LCompareB* lir = new(alloc()) LCompareB(useBox(left), useRegisterOrConstant(right));
define(lir, comp);
return;
}
@@ -1098,9 +1083,8 @@ LIRGenerator::visitCompare(MCompare* comp)
// Compare values.
if (comp->compareType() == MCompare::Compare_Bitwise) {
LCompareBitwise* lir = new(alloc()) LCompareBitwise();
useBoxAtStart(lir, LCompareBitwise::LhsInput, left);
useBoxAtStart(lir, LCompareBitwise::RhsInput, right);
LCompareBitwise* lir = new(alloc()) LCompareBitwise(useBoxAtStart(left),
useBoxAtStart(right));
define(lir, comp);
return;
}
@@ -1120,9 +1104,7 @@ LIRGenerator::lowerBitOp(JSOp op, MInstruction* ins)
return;
}
LBitOpV* lir = new(alloc()) LBitOpV(op);
useBoxAtStart(lir, LBitOpV::LhsInput, lhs);
useBoxAtStart(lir, LBitOpV::RhsInput, rhs);
LBitOpV* lir = new(alloc()) LBitOpV(op, useBoxAtStart(lhs), useBoxAtStart(rhs));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -1133,16 +1115,14 @@ LIRGenerator::visitTypeOf(MTypeOf* ins)
MDefinition* opd = ins->input();
MOZ_ASSERT(opd->type() == MIRType_Value);
LTypeOfV* lir = new(alloc()) LTypeOfV(tempToUnbox());
useBox(lir, LTypeOfV::Input, opd);
LTypeOfV* lir = new(alloc()) LTypeOfV(useBox(opd), tempToUnbox());
define(lir, ins);
}
void
LIRGenerator::visitToId(MToId* ins)
{
LToIdV* lir = new(alloc()) LToIdV(tempDouble());
useBox(lir, LToIdV::Index, ins->input());
LToIdV* lir = new(alloc()) LToIdV(useBox(ins->input()), tempDouble());
defineBox(lir, ins);
assignSafepoint(lir, ins);
}
@@ -1157,8 +1137,7 @@ LIRGenerator::visitBitNot(MBitNot* ins)
return;
}
LBitNotV* lir = new(alloc()) LBitNotV;
useBoxAtStart(lir, LBitNotV::Input, input);
LBitNotV* lir = new(alloc()) LBitNotV(useBoxAtStart(input));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -1242,9 +1221,7 @@ LIRGenerator::lowerShiftOp(JSOp op, MShiftInstruction* ins)
return;
}
LBitOpV* lir = new(alloc()) LBitOpV(op);
useBoxAtStart(lir, LBitOpV::LhsInput, lhs);
useBoxAtStart(lir, LBitOpV::RhsInput, rhs);
LBitOpV* lir = new(alloc()) LBitOpV(op, useBoxAtStart(lhs), useBoxAtStart(rhs));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -1676,9 +1653,7 @@ LIRGenerator::lowerBinaryV(JSOp op, MBinaryInstruction* ins)
MOZ_ASSERT(lhs->type() == MIRType_Value);
MOZ_ASSERT(rhs->type() == MIRType_Value);
LBinaryV* lir = new(alloc()) LBinaryV(op);
useBoxAtStart(lir, LBinaryV::LhsInput, lhs);
useBoxAtStart(lir, LBinaryV::RhsInput, rhs);
LBinaryV* lir = new(alloc()) LBinaryV(op, useBoxAtStart(lhs), useBoxAtStart(rhs));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -1797,8 +1772,7 @@ LIRGenerator::visitToDouble(MToDouble* convert)
switch (opd->type()) {
case MIRType_Value:
{
LValueToDouble* lir = new(alloc()) LValueToDouble();
useBox(lir, LValueToDouble::Input, opd);
LValueToDouble* lir = new(alloc()) LValueToDouble(useBox(opd));
assignSnapshot(lir, Bailout_NonPrimitiveInput);
define(lir, convert);
break;
@@ -1853,8 +1827,7 @@ LIRGenerator::visitToFloat32(MToFloat32* convert)
switch (opd->type()) {
case MIRType_Value:
{
LValueToFloat32* lir = new(alloc()) LValueToFloat32();
useBox(lir, LValueToFloat32::Input, opd);
LValueToFloat32* lir = new(alloc()) LValueToFloat32(useBox(opd));
assignSnapshot(lir, Bailout_NonPrimitiveInput);
define(lir, convert);
break;
@@ -1909,8 +1882,7 @@ LIRGenerator::visitToInt32(MToInt32* convert)
case MIRType_Value:
{
LValueToInt32* lir =
new(alloc()) LValueToInt32(tempDouble(), temp(), LValueToInt32::NORMAL);
useBox(lir, LValueToInt32::Input, opd);
new(alloc()) LValueToInt32(useBox(opd), tempDouble(), temp(), LValueToInt32::NORMAL);
assignSnapshot(lir, Bailout_NonPrimitiveInput);
define(lir, convert);
assignSafepoint(lir, convert);
@@ -1968,9 +1940,8 @@ LIRGenerator::visitTruncateToInt32(MTruncateToInt32* truncate)
switch (opd->type()) {
case MIRType_Value:
{
LValueToInt32* lir = new(alloc()) LValueToInt32(tempDouble(), temp(),
LValueToInt32* lir = new(alloc()) LValueToInt32(useBox(opd), tempDouble(), temp(),
LValueToInt32::TRUNCATE);
useBox(lir, LValueToInt32::Input, opd);
assignSnapshot(lir, Bailout_NonPrimitiveInput);
define(lir, truncate);
assignSafepoint(lir, truncate);
@@ -2049,8 +2020,7 @@ LIRGenerator::visitToString(MToString* ins)
break;
case MIRType_Value: {
LValueToString* lir = new(alloc()) LValueToString(tempToUnbox());
useBox(lir, LValueToString::Input, opd);
LValueToString* lir = new(alloc()) LValueToString(useBox(opd), tempToUnbox());
if (ins->fallible())
assignSnapshot(lir, Bailout_NonPrimitiveInput);
define(lir, ins);
@@ -2069,8 +2039,7 @@ LIRGenerator::visitToObjectOrNull(MToObjectOrNull* ins)
{
MOZ_ASSERT(ins->input()->type() == MIRType_Value);
LValueToObjectOrNull* lir = new(alloc()) LValueToObjectOrNull();
useBox(lir, LValueToString::Input, ins->input());
LValueToObjectOrNull* lir = new(alloc()) LValueToObjectOrNull(useBox(ins->input()));
define(lir, ins);
assignSafepoint(lir, ins);
}
@@ -2220,11 +2189,8 @@ LIRGenerator::visitBinarySharedStub(MBinarySharedStub* ins)
MOZ_ASSERT(ins->type() == MIRType_Value);
MOZ_ASSERT(ins->type() == MIRType_Value);
LBinarySharedStub* lir = new(alloc()) LBinarySharedStub();
useBoxFixedAtStart(lir, LBinarySharedStub::LhsInput, lhs, R0);
useBoxFixedAtStart(lir, LBinarySharedStub::RhsInput, rhs, R1);
LBinarySharedStub* lir = new(alloc()) LBinarySharedStub(useBoxFixedAtStart(lhs, R0),
useBoxFixedAtStart(rhs, R1));
defineSharedStubReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -2235,10 +2201,7 @@ LIRGenerator::visitUnarySharedStub(MUnarySharedStub* ins)
MDefinition* input = ins->getOperand(0);
MOZ_ASSERT(ins->type() == MIRType_Value);
LUnarySharedStub* lir = new(alloc()) LUnarySharedStub();
useBoxFixedAtStart(lir, LUnarySharedStub::Input, input, R0);
LUnarySharedStub* lir = new(alloc()) LUnarySharedStub(useBoxFixedAtStart(input, R0));
defineSharedStubReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -2268,8 +2231,8 @@ LIRGenerator::visitLambdaArrow(MLambdaArrow* ins)
MOZ_ASSERT(ins->scopeChain()->type() == MIRType_Object);
MOZ_ASSERT(ins->newTargetDef()->type() == MIRType_Value);
LLambdaArrow* lir = new(alloc()) LLambdaArrow(useRegister(ins->scopeChain()));
useBox(lir, LLambdaArrow::NewTargetValue, ins->newTargetDef());
LLambdaArrow* lir = new(alloc()) LLambdaArrow(useRegister(ins->scopeChain()),
useBox(ins->newTargetDef()));
define(lir, ins);
assignSafepoint(lir, ins);
}
@@ -2377,8 +2340,7 @@ LIRGenerator::visitStoreSlot(MStoreSlot* ins)
switch (ins->value()->type()) {
case MIRType_Value:
lir = new(alloc()) LStoreSlotV(useRegister(ins->slots()));
useBox(lir, LStoreSlotV::Value, ins->value());
lir = new(alloc()) LStoreSlotV(useRegister(ins->slots()), useBox(ins->value()));
add(lir, ins);
break;
@@ -2429,8 +2391,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier* ins)
// Handle typebarrier with Value as input.
if (inputType == MIRType_Value) {
LDefinition tmp = needTemp ? temp() : tempToUnbox();
LTypeBarrierV* barrier = new(alloc()) LTypeBarrierV(tmp);
useBox(barrier, LTypeBarrierV::Input, ins->input());
LTypeBarrierV* barrier = new(alloc()) LTypeBarrierV(useBox(ins->input()), tmp);
assignSnapshot(barrier, Bailout_TypeBarrierV);
add(barrier, ins);
redefine(ins, ins->input());
@@ -2471,8 +2432,7 @@ LIRGenerator::visitMonitorTypes(MMonitorTypes* ins)
bool needTemp = !types->unknownObject() && types->getObjectCount() > 0;
LDefinition tmp = needTemp ? temp() : tempToUnbox();
LMonitorTypes* lir = new(alloc()) LMonitorTypes(tmp);
useBox(lir, LMonitorTypes::Input, ins->input());
LMonitorTypes* lir = new(alloc()) LMonitorTypes(useBox(ins->input()), tmp);
assignSnapshot(lir, Bailout_MonitorTypes);
add(lir, ins);
}
@@ -2518,8 +2478,8 @@ LIRGenerator::visitPostWriteBarrier(MPostWriteBarrier* ins)
new(alloc()) LPostWriteBarrierV(useConstantObject
? useOrConstant(ins->object())
: useRegister(ins->object()),
useBox(ins->value()),
tmp);
useBox(lir, LPostWriteBarrierV::Input, ins->value());
add(lir, ins);
assignSafepoint(lir, ins);
break;
@@ -2567,8 +2527,8 @@ LIRGenerator::visitPostWriteElementBarrier(MPostWriteElementBarrier* ins)
? useOrConstant(ins->object())
: useRegister(ins->object()),
useRegister(ins->index()),
useBox(ins->value()),
tmp);
useBox(lir, LPostWriteElementBarrierV::Input, ins->value());
add(lir, ins);
assignSafepoint(lir, ins);
break;
@@ -2756,8 +2716,7 @@ LIRGenerator::visitNot(MNot* ins)
temp1 = LDefinition::BogusTemp();
}
LNotV* lir = new(alloc()) LNotV(tempDouble(), temp0, temp1);
useBox(lir, LNotV::Input, op);
LNotV* lir = new(alloc()) LNotV(useBox(op), tempDouble(), temp0, temp1);
define(lir, ins);
break;
}
@@ -2912,10 +2871,9 @@ LIRGenerator::visitStoreElement(MStoreElement* ins)
switch (ins->value()->type()) {
case MIRType_Value:
{
LInstruction* lir = new(alloc()) LStoreElementV(elements, index);
LInstruction* lir = new(alloc()) LStoreElementV(elements, index, useBox(ins->value()));
if (ins->fallible())
assignSnapshot(lir, Bailout_Hole);
useBox(lir, LStoreElementV::Value, ins->value());
add(lir, ins);
break;
}
@@ -2950,8 +2908,8 @@ LIRGenerator::visitStoreElementHole(MStoreElementHole* ins)
LInstruction* lir;
switch (ins->value()->type()) {
case MIRType_Value:
lir = new(alloc()) LStoreElementHoleV(object, elements, index, tempDef);
useBox(lir, LStoreElementHoleV::Value, ins->value());
lir = new(alloc()) LStoreElementHoleV(object, elements, index, useBox(ins->value()),
tempDef);
break;
default:
@@ -3049,8 +3007,7 @@ LIRGenerator::visitArrayPush(MArrayPush* ins)
switch (ins->value()->type()) {
case MIRType_Value:
{
LArrayPushV* lir = new(alloc()) LArrayPushV(object, temp());
useBox(lir, LArrayPushV::Value, ins->value());
LArrayPushV* lir = new(alloc()) LArrayPushV(object, useBox(ins->value()), temp());
define(lir, ins);
assignSafepoint(lir, ins);
break;
@@ -3192,8 +3149,7 @@ LIRGenerator::visitClampToUint8(MClampToUint8* ins)
case MIRType_Value:
{
LClampVToUint8* lir = new(alloc()) LClampVToUint8(tempDouble());
useBox(lir, LClampVToUint8::Input, in);
LClampVToUint8* lir = new(alloc()) LClampVToUint8(useBox(in), tempDouble());
assignSnapshot(lir, Bailout_NonPrimitiveInput);
define(lir, ins);
assignSafepoint(lir, ins);
@@ -3339,8 +3295,8 @@ LIRGenerator::visitStoreFixedSlot(MStoreFixedSlot* ins)
MOZ_ASSERT(ins->object()->type() == MIRType_Object);
if (ins->value()->type() == MIRType_Value) {
LStoreFixedSlotV* lir = new(alloc()) LStoreFixedSlotV(useRegister(ins->object()));
useBox(lir, LStoreFixedSlotV::Value, ins->value());
LStoreFixedSlotV* lir = new(alloc()) LStoreFixedSlotV(useRegister(ins->object()),
useBox(ins->value()));
add(lir, ins);
} else {
LStoreFixedSlotT* lir = new(alloc()) LStoreFixedSlotT(useRegister(ins->object()),
@@ -3395,13 +3351,15 @@ LIRGenerator::visitGetPropertyCache(MGetPropertyCache* ins)
bool useConstId = id->type() == MIRType_String || id->type() == MIRType_Symbol;
if (ins->type() == MIRType_Value) {
LGetPropertyCacheV* lir = new(alloc()) LGetPropertyCacheV(useRegister(ins->object()));
useBoxOrTypedOrConstant(lir, LGetPropertyCacheV::Id, id, useConstId);
LGetPropertyCacheV* lir =
new(alloc()) LGetPropertyCacheV(useRegister(ins->object()),
useBoxOrTypedOrConstant(id, useConstId));
defineBox(lir, ins);
assignSafepoint(lir, ins);
} else {
LGetPropertyCacheT* lir = new(alloc()) LGetPropertyCacheT(useRegister(ins->object()));
useBoxOrTypedOrConstant(lir, LGetPropertyCacheT::Id, id, useConstId);
LGetPropertyCacheT* lir =
new(alloc()) LGetPropertyCacheT(useRegister(ins->object()),
useBoxOrTypedOrConstant(id, useConstId));
define(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3433,8 +3391,9 @@ LIRGenerator::visitSetPropertyPolymorphic(MSetPropertyPolymorphic* ins)
if (ins->value()->type() == MIRType_Value) {
LSetPropertyPolymorphicV* lir =
new(alloc()) LSetPropertyPolymorphicV(useRegister(ins->obj()), temp());
useBox(lir, LSetPropertyPolymorphicV::Value, ins->value());
new(alloc()) LSetPropertyPolymorphicV(useRegister(ins->obj()),
useBox(ins->value()),
temp());
assignSnapshot(lir, Bailout_ShapeGuard);
add(lir, ins);
} else {
@@ -3575,8 +3534,7 @@ LIRGenerator::visitAssertRange(MAssertRange* ins)
break;
}
case MIRType_Value:
lir = new(alloc()) LAssertRangeV(tempToUnbox(), tempDouble(), tempDouble());
useBox(lir, LAssertRangeV::Input, input);
lir = new(alloc()) LAssertRangeV(useBox(input), tempToUnbox(), tempDouble(), tempDouble());
break;
default:
@@ -3591,8 +3549,7 @@ LIRGenerator::visitAssertRange(MAssertRange* ins)
void
LIRGenerator::visitCallGetProperty(MCallGetProperty* ins)
{
LCallGetProperty* lir = new(alloc()) LCallGetProperty();
useBoxAtStart(lir, LCallGetProperty::Value, ins->value());
LCallGetProperty* lir = new(alloc()) LCallGetProperty(useBoxAtStart(ins->value()));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3603,9 +3560,8 @@ LIRGenerator::visitCallGetElement(MCallGetElement* ins)
MOZ_ASSERT(ins->lhs()->type() == MIRType_Value);
MOZ_ASSERT(ins->rhs()->type() == MIRType_Value);
LCallGetElement* lir = new(alloc()) LCallGetElement();
useBoxAtStart(lir, LCallGetElement::LhsInput, ins->lhs());
useBoxAtStart(lir, LCallGetElement::RhsInput, ins->rhs());
LCallGetElement* lir = new(alloc()) LCallGetElement(useBoxAtStart(ins->lhs()),
useBoxAtStart(ins->rhs()));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3613,8 +3569,8 @@ LIRGenerator::visitCallGetElement(MCallGetElement* ins)
void
LIRGenerator::visitCallSetProperty(MCallSetProperty* ins)
{
LInstruction* lir = new(alloc()) LCallSetProperty(useRegisterAtStart(ins->object()));
useBoxAtStart(lir, LCallSetProperty::Value, ins->value());
LInstruction* lir = new(alloc()) LCallSetProperty(useRegisterAtStart(ins->object()),
useBoxAtStart(ins->value()));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3622,8 +3578,7 @@ LIRGenerator::visitCallSetProperty(MCallSetProperty* ins)
void
LIRGenerator::visitDeleteProperty(MDeleteProperty* ins)
{
LCallDeleteProperty* lir = new(alloc()) LCallDeleteProperty();
useBoxAtStart(lir, LCallDeleteProperty::Value, ins->value());
LCallDeleteProperty* lir = new(alloc()) LCallDeleteProperty(useBoxAtStart(ins->value()));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3631,9 +3586,8 @@ LIRGenerator::visitDeleteProperty(MDeleteProperty* ins)
void
LIRGenerator::visitDeleteElement(MDeleteElement* ins)
{
LCallDeleteElement* lir = new(alloc()) LCallDeleteElement();
useBoxAtStart(lir, LCallDeleteElement::Value, ins->value());
useBoxAtStart(lir, LCallDeleteElement::Index, ins->index());
LCallDeleteElement* lir = new(alloc()) LCallDeleteElement(useBoxAtStart(ins->value()),
useBoxAtStart(ins->index()));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3672,11 +3626,12 @@ LIRGenerator::visitSetPropertyCache(MSetPropertyCache* ins)
tempF32 = hasUnaliasedDouble() ? tempFloat32() : LDefinition::BogusTemp();
}
LInstruction* lir = new(alloc()) LSetPropertyCache(useRegister(ins->object()), temp(),
tempToUnboxIndex, tempD, tempF32);
useBoxOrTypedOrConstant(lir, LSetPropertyCache::Id, id, useConstId);
useBoxOrTypedOrConstant(lir, LSetPropertyCache::Value, ins->value(), useConstValue);
LInstruction* lir =
new(alloc()) LSetPropertyCache(useRegister(ins->object()),
useBoxOrTypedOrConstant(id, useConstId),
useBoxOrTypedOrConstant(ins->value(), useConstValue),
temp(),
tempToUnboxIndex, tempD, tempF32);
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3688,10 +3643,9 @@ LIRGenerator::visitCallSetElement(MCallSetElement* ins)
MOZ_ASSERT(ins->index()->type() == MIRType_Value);
MOZ_ASSERT(ins->value()->type() == MIRType_Value);
LCallSetElement* lir = new(alloc()) LCallSetElement();
lir->setOperand(0, useRegisterAtStart(ins->object()));
useBoxAtStart(lir, LCallSetElement::Index, ins->index());
useBoxAtStart(lir, LCallSetElement::Value, ins->value());
LCallSetElement* lir = new(alloc()) LCallSetElement(useRegisterAtStart(ins->object()),
useBoxAtStart(ins->index()),
useBoxAtStart(ins->value()));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3699,9 +3653,8 @@ LIRGenerator::visitCallSetElement(MCallSetElement* ins)
void
LIRGenerator::visitCallInitElementArray(MCallInitElementArray* ins)
{
LCallInitElementArray* lir = new(alloc()) LCallInitElementArray();
lir->setOperand(0, useRegisterAtStart(ins->object()));
useBoxAtStart(lir, LCallInitElementArray::Value, ins->value());
LCallInitElementArray* lir = new(alloc()) LCallInitElementArray(useRegisterAtStart(ins->object()),
useBoxAtStart(ins->value()));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3777,8 +3730,7 @@ LIRGenerator::visitSetFrameArgument(MSetFrameArgument* ins)
MDefinition* input = ins->input();
if (input->type() == MIRType_Value) {
LSetFrameArgumentV* lir = new(alloc()) LSetFrameArgumentV();
useBox(lir, LSetFrameArgumentV::Input, input);
LSetFrameArgumentV* lir = new(alloc()) LSetFrameArgumentV(useBox(input));
add(lir, ins);
} else if (input->type() == MIRType_Undefined || input->type() == MIRType_Null) {
Value val = input->type() == MIRType_Undefined ? UndefinedValue() : NullValue();
@@ -3817,8 +3769,7 @@ LIRGenerator::visitThrow(MThrow* ins)
MDefinition* value = ins->getOperand(0);
MOZ_ASSERT(value->type() == MIRType_Value);
LThrow* lir = new(alloc()) LThrow;
useBoxAtStart(lir, LThrow::Value, value);
LThrow* lir = new(alloc()) LThrow(useBoxAtStart(value));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3832,8 +3783,7 @@ LIRGenerator::visitIn(MIn* ins)
MOZ_ASSERT(lhs->type() == MIRType_Value);
MOZ_ASSERT(rhs->type() == MIRType_Object);
LIn* lir = new(alloc()) LIn(useRegisterAtStart(rhs));
useBoxAtStart(lir, LIn::LHS, lhs);
LIn* lir = new(alloc()) LIn(useBoxAtStart(lhs), useRegisterAtStart(rhs));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3850,8 +3800,7 @@ LIRGenerator::visitInstanceOf(MInstanceOf* ins)
define(lir, ins);
assignSafepoint(lir, ins);
} else {
LInstanceOfV* lir = new(alloc()) LInstanceOfV();
useBox(lir, LInstanceOfV::LHS, lhs);
LInstanceOfV* lir = new(alloc()) LInstanceOfV(useBox(lhs));
define(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3866,8 +3815,8 @@ LIRGenerator::visitCallInstanceOf(MCallInstanceOf* ins)
MOZ_ASSERT(lhs->type() == MIRType_Value);
MOZ_ASSERT(rhs->type() == MIRType_Object);
LCallInstanceOf* lir = new(alloc()) LCallInstanceOf(useRegisterAtStart(rhs));
useBoxAtStart(lir, LCallInstanceOf::LHS, lhs);
LCallInstanceOf* lir = new(alloc()) LCallInstanceOf(useBoxAtStart(lhs),
useRegisterAtStart(rhs));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
@@ -3911,8 +3860,7 @@ LIRGenerator::visitIsObject(MIsObject* ins)
MDefinition* opd = ins->input();
MOZ_ASSERT(opd->type() == MIRType_Value);
LIsObject* lir = new(alloc()) LIsObject();
useBoxAtStart(lir, LIsObject::Input, opd);
LIsObject* lir = new(alloc()) LIsObject(useBoxAtStart(opd));
define(lir, ins);
}
@@ -3967,6 +3915,10 @@ LIRGenerator::visitAsmJSReturn(MAsmJSReturn* ins)
lir->setOperand(0, useFixed(rval, ReturnSimd128Reg));
else if (rval->type() == MIRType_Int32)
lir->setOperand(0, useFixed(rval, ReturnReg));
#if JS_BITS_PER_WORD == 64
else if (rval->type() == MIRType_Int64)
lir->setOperand(0, useFixed(rval, ReturnReg));
#endif
else
MOZ_CRASH("Unexpected asm.js return type");
add(lir);
@@ -4023,10 +3975,6 @@ LIRGenerator::visitSetDOMProperty(MSetDOMProperty* ins)
GetTempRegForIntArg(1, 0, &objReg);
GetTempRegForIntArg(2, 0, &privReg);
GetTempRegForIntArg(3, 0, &valueReg);
LSetDOMProperty* lir = new(alloc()) LSetDOMProperty(tempFixed(cxReg),
useFixed(ins->object(), objReg),
tempFixed(privReg),
tempFixed(valueReg));
// Keep using GetTempRegForIntArg, since we want to make sure we
// don't clobber registers we're already using.
@@ -4034,7 +3982,12 @@ LIRGenerator::visitSetDOMProperty(MSetDOMProperty* ins)
GetTempRegForIntArg(4, 0, &tempReg1);
mozilla::DebugOnly<bool> ok = GetTempRegForIntArg(5, 0, &tempReg2);
MOZ_ASSERT(ok, "How can we not have six temp registers?");
useBoxFixed(lir, LSetDOMProperty::Value, val, tempReg1, tempReg2);
LSetDOMProperty* lir = new(alloc()) LSetDOMProperty(tempFixed(cxReg),
useFixed(ins->object(), objReg),
useBoxFixed(val, tempReg1, tempReg2),
tempFixed(privReg),
tempFixed(valueReg));
add(lir, ins);
assignSafepoint(lir, ins);
}
@@ -4422,7 +4375,10 @@ LIRGenerator::visitSimdShift(MSimdShift* ins)
LUse vector = useRegisterAtStart(ins->lhs());
LAllocation value = useRegisterOrConstant(ins->rhs());
LSimdShift* lir = new(alloc()) LSimdShift(vector, value);
// We need a temp register to mask the shift amount, but not if the shift
// amount is a constant.
LDefinition tempReg = value.isConstant() ? LDefinition::BogusTemp() : temp();
LSimdShift* lir = new(alloc()) LSimdShift(vector, value, tempReg);
defineReuseInput(lir, ins, 0);
}
@@ -4431,8 +4387,7 @@ LIRGenerator::visitLexicalCheck(MLexicalCheck* ins)
{
MDefinition* input = ins->input();
MOZ_ASSERT(input->type() == MIRType_Value);
LLexicalCheck* lir = new(alloc()) LLexicalCheck();
useBox(lir, LLexicalCheck::Input, input);
LLexicalCheck* lir = new(alloc()) LLexicalCheck(useBox(input));
assignSnapshot(lir, ins->bailoutKind());
add(lir, ins);
redefine(ins, input);
@@ -4476,9 +4431,7 @@ LIRGenerator::visitCheckReturn(MCheckReturn* ins)
MOZ_ASSERT(retVal->type() == MIRType_Value);
MOZ_ASSERT(thisVal->type() == MIRType_Value);
LCheckReturn* lir = new(alloc()) LCheckReturn();
useBoxAtStart(lir, LCheckReturn::ReturnValue, retVal);
useBoxAtStart(lir, LCheckReturn::ThisValue, thisVal);
LCheckReturn* lir = new(alloc()) LCheckReturn(useBoxAtStart(retVal), useBoxAtStart(thisVal));
assignSnapshot(lir, Bailout_BadDerivedConstructorReturn);
add(lir, ins);
redefine(ins, retVal);
@@ -4490,8 +4443,7 @@ LIRGenerator::visitCheckObjCoercible(MCheckObjCoercible* ins)
MDefinition* checkVal = ins->checkValue();
MOZ_ASSERT(checkVal->type() == MIRType_Value);
LCheckObjCoercible* lir = new(alloc()) LCheckObjCoercible();
useBoxAtStart(lir, LCheckObjCoercible::CheckValue, checkVal);
LCheckObjCoercible* lir = new(alloc()) LCheckObjCoercible(useBoxAtStart(checkVal));
redefine(ins, checkVal);
add(lir, ins);
assignSafepoint(lir, ins);
@@ -4503,8 +4455,7 @@ LIRGenerator::visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins)
MDefinition* checkVal = ins->checkValue();
MOZ_ASSERT(checkVal->type() == MIRType_Value);
LDebugCheckSelfHosted* lir = new (alloc()) LDebugCheckSelfHosted();
useBoxAtStart(lir, LDebugCheckSelfHosted::CheckValue, checkVal);
LDebugCheckSelfHosted* lir = new (alloc()) LDebugCheckSelfHosted(useBoxAtStart(checkVal));
redefine(ins, checkVal);
add(lir, ins);
assignSafepoint(lir, ins);
+2 -4
View File
@@ -49,10 +49,8 @@ class LIRGenerator : public LIRGeneratorSpecific
bool generate();
private:
void useBoxAtStart(LInstruction* lir, size_t n, MDefinition* mir,
LUse::Policy policy = LUse::REGISTER);
void useBoxFixedAtStart(LInstruction* lir, size_t n, MDefinition* mir, ValueOperand op);
LBoxAllocation useBoxFixedAtStart(MDefinition* mir, ValueOperand op);
LBoxAllocation useBoxAtStart(MDefinition* mir, LUse::Policy policy = LUse::REGISTER);
void lowerBitOp(JSOp op, MInstruction* ins);
void lowerShiftOp(JSOp op, MShiftInstruction* ins);
-4
View File
@@ -3158,10 +3158,6 @@ IonBuilder::inlineSimd(CallInfo& callInfo, JSFunction* target, SimdType type)
return inlineSimdShift(callInfo, native, MSimdShift::lsh, type);
case SimdOperation::Fn_shiftRightByScalar:
return inlineSimdShift(callInfo, native, MSimdShift::rshForSign(GetSimdSign(type)), type);
case SimdOperation::Fn_shiftRightArithmeticByScalar:
return inlineSimdShift(callInfo, native, MSimdShift::rsh, type);
case SimdOperation::Fn_shiftRightLogicalByScalar:
return inlineSimdShift(callInfo, native, MSimdShift::ursh, type);
// Boolean unary.
case SimdOperation::Fn_allTrue:
+6
View File
@@ -672,6 +672,12 @@ class MacroAssembler : public MacroAssemblerSpecific
CodeOffset selfReferencePatch_;
public:
// ===============================================================
// Move instructions
inline void move64(Imm64 imm, Register64 dest) PER_ARCH;
inline void move64(Register64 src, Register64 dest) PER_ARCH;
// ===============================================================
// Logical instructions
+7 -4
View File
@@ -60,9 +60,11 @@ class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0>
static const size_t Input = 0;
LUnboxFloatingPoint(MIRType type)
LUnboxFloatingPoint(const LBoxAllocation& input, MIRType type)
: type_(type)
{ }
{
setBoxOperand(Input, input);
}
MUnbox* mir() const {
return mir_->toUnbox();
@@ -301,9 +303,10 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2>
public:
LIR_HEADER(TableSwitchV);
LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy,
MTableSwitch* ins)
LTableSwitchV(const LBoxAllocation& input, const LDefinition& inputCopy,
const LDefinition& floatCopy, MTableSwitch* ins)
{
setBoxOperand(InputValue, input);
setTemp(0, inputCopy);
setTemp(1, floatCopy);
setMir(ins);
+7 -8
View File
@@ -17,16 +17,15 @@ using namespace js::jit;
using mozilla::FloorLog2;
void
LIRGeneratorARM::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1,
Register reg2, bool useAtStart)
LBoxAllocation
LIRGeneratorARM::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart)
{
MOZ_ASSERT(mir->type() == MIRType_Value);
MOZ_ASSERT(reg1 != reg2);
ensureDefined(mir);
lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart));
lir->setOperand(n + 1, LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart));
return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart),
LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart));
}
LAllocation
@@ -108,10 +107,9 @@ LIRGeneratorARM::visitUnbox(MUnbox* unbox)
ensureDefined(inner);
if (IsFloatingPointType(unbox->type())) {
LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(unbox->type());
LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(useBox(inner), unbox->type());
if (unbox->fallible())
assignSnapshot(lir, unbox->bailoutKind());
useBox(lir, LUnboxFloatingPoint::Input, inner);
define(lir, unbox);
return;
}
@@ -345,7 +343,8 @@ LIRGeneratorARM::newLTableSwitch(const LAllocation& in, const LDefinition& input
LTableSwitchV*
LIRGeneratorARM::newLTableSwitchV(MTableSwitch* tableswitch)
{
return new(alloc()) LTableSwitchV(temp(), tempDouble(), tableswitch);
return new(alloc()) LTableSwitchV(useBox(tableswitch->getOperand(0)),
temp(), tempDouble(), tableswitch);
}
void
+3 -4
View File
@@ -20,10 +20,9 @@ class LIRGeneratorARM : public LIRGeneratorShared
{ }
protected:
// Adds a box input to an instruction, setting operand |n| to the type and
// |n+1| to the payload.
void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
// Returns a box allocation with type set to reg1 and payload set to reg2.
LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
// x86 has constraints on what registers can be formatted for 1-byte
// stores and loads; on ARM all registers are okay.
+15
View File
@@ -13,6 +13,21 @@ namespace js {
namespace jit {
//{{{ check_macroassembler_style
void
MacroAssembler::move64(Register64 src, Register64 dest)
{
move32(src.low, dest.low);
move32(src.high, dest.high);
}
void
MacroAssembler::move64(Imm64 imm, Register64 dest)
{
move32(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
move32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
}
// ===============================================================
// Logical instructions
-4
View File
@@ -1016,10 +1016,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void movePtr(ImmPtr imm, Register dest);
void movePtr(wasm::SymbolicAddress imm, Register dest);
void movePtr(ImmGCPtr imm, Register dest);
void move64(Register64 src, Register64 dest) {
move32(src.low, dest.low);
move32(src.high, dest.high);
}
void load8SignExtend(const Address& address, Register dest);
void load8SignExtend(const BaseIndex& src, Register dest);
+3 -2
View File
@@ -282,9 +282,10 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2>
public:
LIR_HEADER(TableSwitchV);
LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy,
MTableSwitch* ins)
LTableSwitchV(const LBoxAllocation& input, const LDefinition& inputCopy,
const LDefinition& floatCopy, MTableSwitch* ins)
{
setBoxOperand(InputValue, input);
setTemp(0, inputCopy);
setTemp(1, floatCopy);
setMir(ins);
+2 -2
View File
@@ -17,8 +17,8 @@ using namespace js::jit;
using mozilla::FloorLog2;
void
LIRGeneratorARM64::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register, bool useAtStart)
LBoxAllocation
LIRGeneratorARM64::useBoxFixed(MDefinition* mir, Register reg1, Register, bool useAtStart)
{
MOZ_CRASH("useBoxFixed");
}
+3 -4
View File
@@ -20,10 +20,9 @@ class LIRGeneratorARM64 : public LIRGeneratorShared
{ }
protected:
// Adds a box input to an instruction, setting operand |n| to the type and
// |n+1| to the payload.
void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
// Returns a box allocation. reg2 is ignored on 64-bit platforms.
LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
LAllocation useByteOpRegister(MDefinition* mir);
LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition* mir);
@@ -13,6 +13,19 @@ namespace js {
namespace jit {
//{{{ check_macroassembler_style
void
MacroAssembler::move64(Register64 src, Register64 dest)
{
movePtr(src.reg, dest.reg);
}
void
MacroAssembler::move64(Imm64 imm, Register64 dest)
{
movePtr(ImmWord(imm.value), dest.reg);
}
// ===============================================================
// Logical instructions
-3
View File
@@ -763,9 +763,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
BufferOffset load = movePatchablePtr(ImmPtr(imm.value), dest);
writeDataRelocation(imm, load);
}
void move64(Register64 src, Register64 dest) {
movePtr(src.reg, dest.reg);
}
void mov(ImmWord imm, Register dest) {
movePtr(imm, dest);
+4 -2
View File
@@ -182,9 +182,11 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3>
public:
LIR_HEADER(TableSwitchV);
LTableSwitchV(const LDefinition& inputCopy, const LDefinition& floatCopy,
const LDefinition& jumpTablePointer, MTableSwitch* ins)
LTableSwitchV(const LBoxAllocation& input, const LDefinition& inputCopy,
const LDefinition& floatCopy, const LDefinition& jumpTablePointer,
MTableSwitch* ins)
{
setBoxOperand(InputValue, input);
setTemp(0, inputCopy);
setTemp(1, floatCopy);
setTemp(2, jumpTablePointer);
@@ -106,7 +106,7 @@ LIRGeneratorMIPSShared::lowerDivI(MDiv* div)
// Division instructions are slow. Division by constant denominators can be
// rewritten to use other instructions.
if (div->rhs()->isConstant()) {
int32_t rhs = div->rhs()->toConstant()->value().toInt32();
int32_t rhs = div->rhs()->toConstant()->toInt32();
// Check for division by a positive power of two, which is an easy and
// important case to optimize. Note that other optimizations are also
// possible; division by negative powers of two can be optimized in a
@@ -147,7 +147,7 @@ LIRGeneratorMIPSShared::lowerModI(MMod* mod)
}
if (mod->rhs()->isConstant()) {
int32_t rhs = mod->rhs()->toConstant()->value().toInt32();
int32_t rhs = mod->rhs()->toConstant()->toInt32();
int32_t shift = FloorLog2(rhs);
if (rhs > 0 && 1 << shift == rhs) {
LModPowTwoI* lir = new(alloc()) LModPowTwoI(useRegister(mod->lhs()), shift);
@@ -193,7 +193,8 @@ LIRGeneratorMIPSShared::newLTableSwitch(const LAllocation& in, const LDefinition
LTableSwitchV*
LIRGeneratorMIPSShared::newLTableSwitchV(MTableSwitch* tableswitch)
{
return new(alloc()) LTableSwitchV(temp(), tempDouble(), temp(), tableswitch);
return new(alloc()) LTableSwitchV(useBox(tableswitch->getOperand(0)),
temp(), tempDouble(), temp(), tableswitch);
}
void
@@ -301,10 +302,10 @@ LIRGeneratorMIPSShared::visitAsmJSLoadHeap(MAsmJSLoadHeap* ins)
// For MIPS it is best to keep the 'ptr' in a register if a bounds check
// is needed.
if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
if (ptr->isConstant() && !ins->needsBoundsCheck()) {
// A bounds check is only skipped for a positive index.
MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
ptrAlloc = LAllocation(ptr->constantVp());
MOZ_ASSERT(ptr->toConstant()->toInt32() >= 0);
ptrAlloc = LAllocation(ptr->toConstant());
} else
ptrAlloc = useRegisterAtStart(ptr);
@@ -318,9 +319,9 @@ LIRGeneratorMIPSShared::visitAsmJSStoreHeap(MAsmJSStoreHeap* ins)
MOZ_ASSERT(ptr->type() == MIRType_Int32);
LAllocation ptrAlloc;
if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
ptrAlloc = LAllocation(ptr->constantVp());
if (ptr->isConstant() && !ins->needsBoundsCheck()) {
MOZ_ASSERT(ptr->toConstant()->toInt32() >= 0);
ptrAlloc = LAllocation(ptr->toConstant());
} else
ptrAlloc = useRegisterAtStart(ptr);
+4 -2
View File
@@ -60,9 +60,11 @@ class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0>
static const size_t Input = 0;
LUnboxFloatingPoint(MIRType type)
LUnboxFloatingPoint(const LBoxAllocation& input, MIRType type)
: type_(type)
{ }
{
setBoxOperand(Input, input);
}
MUnbox* mir() const {
return mir_->toUnbox();
+6 -8
View File
@@ -15,16 +15,15 @@
using namespace js;
using namespace js::jit;
void
LIRGeneratorMIPS::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1,
Register reg2, bool useAtStart)
LBoxAllocation
LIRGeneratorMIPS::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart)
{
MOZ_ASSERT(mir->type() == MIRType_Value);
MOZ_ASSERT(reg1 != reg2);
ensureDefined(mir);
lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart));
lir->setOperand(n + 1, LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart));
return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart),
LUse(reg2, VirtualRegisterOfPayload(mir), useAtStart));
}
void
@@ -45,7 +44,7 @@ LIRGeneratorMIPS::visitBox(MBox* box)
}
if (inner->isConstant()) {
defineBox(new(alloc()) LValue(inner->toConstant()->value()), box);
defineBox(new(alloc()) LValue(inner->toConstant()->toJSValue()), box);
return;
}
@@ -88,10 +87,9 @@ LIRGeneratorMIPS::visitUnbox(MUnbox* unbox)
ensureDefined(inner);
if (IsFloatingPointType(unbox->type())) {
LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(unbox->type());
LUnboxFloatingPoint* lir = new(alloc()) LUnboxFloatingPoint(useBox(inner), unbox->type());
if (unbox->fallible())
assignSnapshot(lir, unbox->bailoutKind());
useBox(lir, LUnboxFloatingPoint::Input, inner);
define(lir, unbox);
return;
}
+3 -4
View File
@@ -20,10 +20,9 @@ class LIRGeneratorMIPS : public LIRGeneratorMIPSShared
{ }
protected:
// Adds a box input to an instruction, setting operand |n| to the type and
// |n+1| to the payload.
void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
// Returns a box allocation with type set to reg1 and payload set to reg2.
LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
inline LDefinition tempToUnbox() {
return LDefinition::BogusTemp();
@@ -15,6 +15,21 @@ namespace js {
namespace jit {
//{{{ check_macroassembler_style
void
MacroAssembler::move64(Register64 src, Register64 dest)
{
move32(src.low, dest.low);
move32(src.high, dest.high);
}
void
MacroAssembler::move64(Imm64 imm, Register64 dest)
{
move32(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
move32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
}
// ===============================================================
// Logical instructions
@@ -936,10 +936,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
void move32(Imm32 imm, Register dest);
void move32(Register src, Register dest);
void move64(Register64 src, Register64 dest) {
move32(src.low, dest.low);
move32(src.high, dest.high);
}
void movePtr(Register src, Register dest);
void movePtr(ImmWord imm, Register dest);
+2 -2
View File
@@ -222,7 +222,7 @@ CodeGeneratorMIPS64::visitCompareB(LCompareB* lir)
// Load boxed boolean in ScratchRegister.
if (rhs->isConstant())
masm.moveValue(*rhs->toConstant(), ScratchRegister);
masm.moveValue(rhs->toConstant()->toJSValue(), ScratchRegister);
else
masm.boxValue(JSVAL_TYPE_BOOLEAN, ToRegister(rhs), ScratchRegister);
@@ -241,7 +241,7 @@ CodeGeneratorMIPS64::visitCompareBAndBranch(LCompareBAndBranch* lir)
// Load boxed boolean in ScratchRegister.
if (rhs->isConstant())
masm.moveValue(*rhs->toConstant(), ScratchRegister);
masm.moveValue(rhs->toConstant()->toJSValue(), ScratchRegister);
else
masm.boxValue(JSVAL_TYPE_BOOLEAN, ToRegister(rhs), ScratchRegister);
+4 -5
View File
@@ -15,14 +15,13 @@
using namespace js;
using namespace js::jit;
void
LIRGeneratorMIPS64::useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1,
Register reg2, bool useAtStart)
LBoxAllocation
LIRGeneratorMIPS64::useBoxFixed(MDefinition* mir, Register reg1, Register reg2, bool useAtStart)
{
MOZ_ASSERT(mir->type() == MIRType_Value);
ensureDefined(mir);
lir->setOperand(n, LUse(reg1, mir->virtualRegister(), useAtStart));
return LBoxAllocation(LUse(reg1, mir->virtualRegister(), useAtStart));
}
void
@@ -37,7 +36,7 @@ LIRGeneratorMIPS64::visitBox(MBox* box)
}
if (opd->isConstant()) {
define(new(alloc()) LValue(opd->toConstant()->value()), box, LDefinition(LDefinition::BOX));
define(new(alloc()) LValue(opd->toConstant()->toJSValue()), box, LDefinition(LDefinition::BOX));
} else {
LBox* ins = new(alloc()) LBox(useRegister(opd), opd->type());
define(ins, box, LDefinition(LDefinition::BOX));
+3 -4
View File
@@ -20,10 +20,9 @@ class LIRGeneratorMIPS64 : public LIRGeneratorMIPSShared
{ }
protected:
// Adds a box input to an instruction, setting operand |n| to the type and
// |n+1| to the payload.
void useBoxFixed(LInstruction* lir, size_t n, MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
// Returns a box allocation. reg2 is ignored on 64-bit platforms.
LBoxAllocation useBoxFixed(MDefinition* mir, Register reg1, Register reg2,
bool useAtStart = false);
inline LDefinition tempToUnbox() {
return temp();
@@ -15,6 +15,19 @@ namespace js {
namespace jit {
//{{{ check_macroassembler_style
void
MacroAssembler::move64(Register64 src, Register64 dest)
{
movePtr(src.reg, dest.reg);
}
void
MacroAssembler::move64(Imm64 imm, Register64 dest)
{
movePtr(ImmWord(imm.value), dest.reg);
}
// ===============================================================
// Logical instructions
@@ -950,9 +950,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
void move32(Imm32 imm, Register dest);
void move32(Register src, Register dest);
void move64(Register64 src, Register64 dest) {
movePtr(src.reg, dest.reg);
}
void movePtr(Register src, Register dest);
void movePtr(ImmWord imm, Register dest);
+1 -1
View File
@@ -21,7 +21,7 @@ class LIRGeneratorNone : public LIRGeneratorShared
MOZ_CRASH();
}
void useBoxFixed(LInstruction*, size_t, MDefinition*, Register, Register, bool useAtStart = false) { MOZ_CRASH(); }
LBoxAllocation useBoxFixed(MDefinition*, Register, Register, bool useAtStart = false) { MOZ_CRASH(); }
LAllocation useByteOpRegister(MDefinition*) { MOZ_CRASH(); }
LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition*) { MOZ_CRASH(); }
@@ -50,6 +50,18 @@ ToRegister(const LDefinition* def)
return ToRegister(*def->output());
}
static inline Register64
ToOutRegister64(LInstruction* ins)
{
#if JS_BITS_PER_WORD == 32
Register loReg = ToRegister(ins->getDef(0));
Register hiReg = ToRegister(ins->getDef(1));
return Register64(hiReg, loReg);
#else
return Register64(ToRegister(ins->getDef(0)));
#endif
}
static inline Register
ToTempRegisterOrInvalid(const LDefinition* def)
{

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