mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
Merge remote-tracking branch 'origin/master' into kmeleon76
This commit is contained in:
+3
-6
@@ -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
@@ -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
@@ -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"'
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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,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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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__':
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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 = \
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
Vendored
-1
@@ -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.
|
||||
|
||||
Vendored
-9
@@ -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)))
|
||||
|
||||
Vendored
+1
@@ -676,6 +676,7 @@ SSL_SetStapledOCSPResponses
|
||||
SSL_SetURL
|
||||
SSL_SNISocketConfigHook
|
||||
SSL_VersionRangeGet
|
||||
SSL_VersionRangeGetDefault
|
||||
SSL_VersionRangeGetSupported
|
||||
SSL_VersionRangeSet
|
||||
SSL_VersionRangeSetDefault
|
||||
|
||||
@@ -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
@@ -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
@@ -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::
|
||||
|
||||
@@ -799,6 +799,8 @@ protected:
|
||||
|
||||
void ResetResponse();
|
||||
|
||||
bool ShouldBlockAuthPrompt();
|
||||
|
||||
struct RequestHeader
|
||||
{
|
||||
nsCString header;
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -101,6 +101,7 @@ UNIFIED_SOURCES += [
|
||||
'WebGLExtensionColorBufferFloat.cpp',
|
||||
'WebGLExtensionColorBufferHalfFloat.cpp',
|
||||
'WebGLExtensionCompressedTextureATC.cpp',
|
||||
'WebGLExtensionCompressedTextureES3.cpp',
|
||||
'WebGLExtensionCompressedTextureETC1.cpp',
|
||||
'WebGLExtensionCompressedTexturePVRTC.cpp',
|
||||
'WebGLExtensionCompressedTextureS3TC.cpp',
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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']:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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, ¬Int32);
|
||||
masm.moveValue(index, out);
|
||||
masm.moveValue(input, out);
|
||||
masm.jump(ool->rejoin());
|
||||
|
||||
masm.bind(¬Int32);
|
||||
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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user