mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge fx-team to m-c
This commit is contained in:
commit
44be5ce2e3
@ -1587,6 +1587,13 @@ nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
|
||||
|
||||
// Fire MSAA event for client area window.
|
||||
NotifyWinEvent(winEvent, hWnd, OBJID_CLIENT, childID);
|
||||
|
||||
// JAWS announces collapsed combobox navigation based on focus events.
|
||||
if (eventType == nsIAccessibleEvent::EVENT_SELECTION &&
|
||||
accessible->Role() == nsIAccessibleRole::ROLE_COMBOBOX_OPTION &&
|
||||
nsWinUtils::IsWindowEmulationFor(kJAWSModuleHandle)) {
|
||||
NotifyWinEvent(EVENT_OBJECT_FOCUS, hWnd, OBJID_CLIENT, childID);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -61,30 +61,6 @@ DEFINES += -DAB_CD=$(AB_CD)
|
||||
APP_VERSION = $(shell cat $(srcdir)/../config/version.txt)
|
||||
DEFINES += -DAPP_VERSION="$(APP_VERSION)"
|
||||
|
||||
DIST_FILES = application.ini
|
||||
|
||||
GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
|
||||
GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build BuildID)
|
||||
|
||||
DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
|
||||
|
||||
MOZ_SOURCE_STAMP ?= $(shell hg -R $(topsrcdir) parent --template="{node|short}\n" 2>/dev/null)
|
||||
ifdef MOZ_SOURCE_STAMP
|
||||
DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
|
||||
endif
|
||||
|
||||
SOURCE_REPO := $(shell hg -R $(topsrcdir) showconfig paths.default 2>/dev/null | sed -e "s/^ssh:/http:/")
|
||||
ifdef SOURCE_REPO
|
||||
DEFINES += -DMOZ_SOURCE_REPO="$(SOURCE_REPO)"
|
||||
endif
|
||||
|
||||
DEFINES += -DMOZ_APP_BASENAME="$(MOZ_APP_BASENAME)" \
|
||||
-DMOZ_APP_VENDOR="$(MOZ_APP_VENDOR)"
|
||||
|
||||
ifdef MOZ_APP_PROFILE
|
||||
DEFINES += -DMOZ_APP_PROFILE="$(MOZ_APP_PROFILE)"
|
||||
endif
|
||||
|
||||
ifdef LIBXUL_SDK
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
else
|
||||
@ -97,6 +73,7 @@ CPPSRCS = nsBrowserApp.cpp
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
|
||||
LOCAL_INCLUDES += -I$(DEPTH)/build
|
||||
|
||||
DEFINES += -DXPCOM_GLUE
|
||||
STL_FLAGS=
|
||||
@ -187,10 +164,6 @@ endif # LIBXUL_SDK
|
||||
|
||||
DEFINES += -DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\"
|
||||
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DMOZILLA_OFFICIAL
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
libs::
|
||||
$(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(DIST)/bin/icons
|
||||
@ -228,7 +201,7 @@ else
|
||||
APPFILES = MacOS
|
||||
endif
|
||||
|
||||
libs repackage:: $(PROGRAM) application.ini
|
||||
libs repackage:: $(PROGRAM)
|
||||
$(MKDIR) -p $(DIST)/$(APP_NAME).app/Contents/MacOS
|
||||
rsync -a --exclude CVS --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
|
||||
$(MKDIR) -p $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
|
||||
|
@ -36,8 +36,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "application.ini.h"
|
||||
#include "nsXPCOMGlue.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#if defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
@ -140,20 +140,7 @@ static const nsDynamicFunctionLoad kXULFuncs[] = {
|
||||
static int do_main(const char *exePath, int argc, char* argv[])
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> appini;
|
||||
#ifdef XP_WIN
|
||||
// exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
|
||||
// encoded path, so it is safe to convert it
|
||||
nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
|
||||
getter_AddRefs(appini));
|
||||
#else
|
||||
nsresult rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
|
||||
getter_AddRefs(appini));
|
||||
#endif
|
||||
if (NS_FAILED(rv)) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
|
||||
nsresult rv;
|
||||
|
||||
// Allow firefox.exe to launch XULRunner apps via -app <application.ini>
|
||||
// Note that -app must be the *first* argument.
|
||||
@ -188,15 +175,32 @@ static int do_main(const char *exePath, int argc, char* argv[])
|
||||
argc -= 2;
|
||||
}
|
||||
|
||||
nsXREAppData *appData;
|
||||
rv = XRE_CreateAppData(appini, &appData);
|
||||
if (NS_FAILED(rv)) {
|
||||
Output("Couldn't read application.ini");
|
||||
return 255;
|
||||
int result;
|
||||
if (appini) {
|
||||
nsXREAppData *appData;
|
||||
rv = XRE_CreateAppData(appini, &appData);
|
||||
if (NS_FAILED(rv)) {
|
||||
Output("Couldn't read application.ini");
|
||||
return 255;
|
||||
}
|
||||
result = XRE_main(argc, argv, appData);
|
||||
XRE_FreeAppData(appData);
|
||||
} else {
|
||||
#ifdef XP_WIN
|
||||
// exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
|
||||
// encoded path, so it is safe to convert it
|
||||
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), PR_FALSE,
|
||||
getter_AddRefs(appini));
|
||||
#else
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_FALSE,
|
||||
getter_AddRefs(appini));
|
||||
#endif
|
||||
if (NS_FAILED(rv)) {
|
||||
return 255;
|
||||
}
|
||||
result = XRE_main(argc, argv, &sAppData);
|
||||
}
|
||||
|
||||
int result = XRE_main(argc, argv, appData);
|
||||
XRE_FreeAppData(appData);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -240,6 +244,8 @@ int main(int argc, char* argv[])
|
||||
Output("Couldn't load XPCOM.\n");
|
||||
return 255;
|
||||
}
|
||||
// Reset exePath so that it is the directory name and not the xpcom dll name
|
||||
*lastSlash = 0;
|
||||
|
||||
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
ac_add_options --enable-debug
|
||||
ac_add_options --enable-trace-malloc
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -3,5 +3,5 @@ ac_add_options --enable-official-branding
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
|
||||
CC=/tools/gcc-4.3.3/installed/bin/gcc
|
||||
CXX=/tools/gcc-4.3.3/installed/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
|
@ -5,8 +5,8 @@ ac_add_options --enable-codesighs
|
||||
# Nightlies only since this has a cost in performance
|
||||
ac_add_options --enable-js-diagnostics
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-codesighs
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -2,8 +2,8 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -9,8 +9,8 @@ ac_add_options --disable-updater
|
||||
ac_add_options --prefix=$PREFIX
|
||||
ac_add_options --libdir=$LIBDIR
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
ac_add_options --enable-debug
|
||||
ac_add_options --enable-trace-malloc
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -3,5 +3,5 @@ ac_add_options --enable-official-branding
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
|
||||
CC=/tools/gcc/bin/gcc
|
||||
CXX=/tools/gcc/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
|
@ -5,8 +5,8 @@ ac_add_options --enable-codesighs
|
||||
# Nightlies only since this has a cost in performance
|
||||
ac_add_options --enable-js-diagnostics
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -2,8 +2,8 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -9,8 +9,8 @@ ac_add_options --disable-updater
|
||||
ac_add_options --prefix=$PREFIX
|
||||
ac_add_options --libdir=$LIBDIR
|
||||
|
||||
CC=/tools/gcc-4.5/bin/gcc
|
||||
CXX=/tools/gcc-4.5/bin/g++
|
||||
CC=/tools/gcc-4.5-0moz2/bin/gcc
|
||||
CXX=/tools/gcc-4.5-0moz2/bin/g++
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
|
@ -51,3 +51,7 @@ MOZ_EXTENSIONS_DEFAULT=" gnomevfs"
|
||||
# because branding dependencies are broken.
|
||||
MOZ_BRANDING_DIRECTORY=browser/branding/nightly
|
||||
MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
|
||||
MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
MOZ_PROFILE_MIGRATOR=1
|
||||
MOZ_EXTENSION_MANAGER=1
|
||||
MOZ_APP_STATIC_INI=1
|
||||
|
@ -14,6 +14,7 @@
|
||||
@DLL_PREFIX@mozjs@DLL_SUFFIX@
|
||||
#endif
|
||||
LICENSE
|
||||
update.locale
|
||||
browserconfig.properties
|
||||
chrome/US.jar
|
||||
chrome/app-chrome.manifest
|
||||
|
@ -66,6 +66,60 @@ ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_APP_BASENAME
|
||||
DIST_FILES = application.ini
|
||||
|
||||
ifdef LIBXUL_SDK
|
||||
GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
|
||||
APP_INI_DEPS = $(LIBXUL_DIST)/bin/platform.ini
|
||||
else
|
||||
GRE_MILESTONE = $(shell tail -n 1 $(topsrcdir)/config/milestone.txt 2>/dev/null || tail -1 $(topsrcdir)/config/milestone.txt)
|
||||
APP_INI_DEPS = $(topsrcdir)/config/milestone.txt
|
||||
endif
|
||||
|
||||
APP_BUILDID := $(shell cat $(DEPTH)/config/buildid)
|
||||
APP_INI_DEPS += $(DEPTH)/config/buildid
|
||||
|
||||
DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DAPP_BUILDID=$(APP_BUILDID)
|
||||
|
||||
DEFINES += -DMOZ_APP_VERSION="$(MOZ_APP_VERSION)"
|
||||
APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOZ_SOURCE_STAMP ?= $(firstword $(shell hg -R $(topsrcdir) parent --template="{node|short}\n" 2>/dev/null))
|
||||
ifdef MOZ_SOURCE_STAMP
|
||||
DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
|
||||
endif
|
||||
|
||||
_dollar=$$
|
||||
SOURCE_REPO := $(shell cd $(topsrcdir) && hg showconfig paths.default 2>/dev/null | head -n1 | sed -e "s/^ssh:/http:/" -e "s/\/$(_dollar)//" )
|
||||
ifdef SOURCE_REPO
|
||||
DEFINES += -DMOZ_SOURCE_REPO="$(SOURCE_REPO)"
|
||||
endif
|
||||
|
||||
DEFINES += \
|
||||
-DMOZ_APP_BASENAME="$(MOZ_APP_BASENAME)" \
|
||||
-DMOZ_APP_VENDOR="$(MOZ_APP_VENDOR)" \
|
||||
-DMOZ_APP_ID="$(MOZ_APP_ID)" \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_APP_PROFILE
|
||||
DEFINES += -DMOZ_APP_PROFILE="$(MOZ_APP_PROFILE)"
|
||||
endif
|
||||
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DMOZILLA_OFFICIAL
|
||||
endif
|
||||
|
||||
ifdef MOZ_PROFILE_MIGRATOR
|
||||
DEFINES += -DMOZ_PROFILE_MIGRATOR
|
||||
endif
|
||||
|
||||
ifdef MOZ_EXTENSION_MANAGER
|
||||
DEFINES += -DMOZ_EXTENSION_MANAGER
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# we install to _leaktest/
|
||||
@ -100,6 +154,19 @@ leaktest.py: leaktest.py.in
|
||||
chmod +x $@
|
||||
GARBAGE += leaktest.py
|
||||
|
||||
ifdef MOZ_APP_BASENAME
|
||||
application.ini: application.ini.in $(APP_INI_DEPS)
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
|
||||
GARBAGE += application.ini
|
||||
|
||||
ifdef MOZ_APP_STATIC_INI
|
||||
application.ini.h: appini_header.py application.ini
|
||||
$(PYTHON) $^ > $@
|
||||
export:: application.ini.h
|
||||
GARBAGE += application.ini.h
|
||||
endif
|
||||
endif
|
||||
|
||||
libs:: $(_LEAKTEST_FILES)
|
||||
$(INSTALL) $^ $(_LEAKTEST_DIR)
|
||||
|
||||
|
86
build/appini_header.py
Normal file
86
build/appini_header.py
Normal file
@ -0,0 +1,86 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is a build helper for libraries
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Mike Hommey <mh@glandium.org>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
'''Parses a given application.ini file and outputs the corresponding
|
||||
XULAppData structure as a C++ header file'''
|
||||
|
||||
import ConfigParser
|
||||
import sys
|
||||
|
||||
def main(file):
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.read(file)
|
||||
flags = set()
|
||||
try:
|
||||
if config.getint('XRE', 'EnableExtensionManager') == 1:
|
||||
flags.add('NS_XRE_ENABLE_EXTENSION_MANAGER')
|
||||
except: pass
|
||||
try:
|
||||
if config.getint('XRE', 'EnableProfileMigrator') == 1:
|
||||
flags.add('NS_XRE_ENABLE_PROFILE_MIGRATOR')
|
||||
except: pass
|
||||
try:
|
||||
if config.getint('Crash Reporter', 'Enabled') == 1:
|
||||
flags.add('NS_XRE_ENABLE_CRASH_REPORTER')
|
||||
except: pass
|
||||
appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s))
|
||||
appdata['flags'] = ' | '.join(flags) if flags else '0'
|
||||
appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL'
|
||||
|
||||
print '''#include "nsXULAppAPI.h"
|
||||
static const nsXREAppData sAppData = {
|
||||
sizeof(nsXREAppData),
|
||||
NULL, // directory
|
||||
"%(App:vendor)s",
|
||||
"%(App:name)s",
|
||||
"%(App:version)s",
|
||||
"%(App:buildid)s",
|
||||
"%(App:id)s",
|
||||
NULL, // copyright
|
||||
%(flags)s,
|
||||
NULL, // xreDirectory
|
||||
"%(Gecko:minversion)s",
|
||||
"%(Gecko:maxversion)s",
|
||||
"%(Crash Reporter:serverurl)s",
|
||||
%(App:profile)s
|
||||
};''' % appdata
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 1:
|
||||
main(sys.argv[1])
|
||||
else:
|
||||
print >>sys.stderr, "Usage: %s /path/to/application.ini" % sys.argv[0]
|
@ -1,3 +1,9 @@
|
||||
#if MOZ_APP_STATIC_INI
|
||||
; This file is not used. If you modify it and want the application to use
|
||||
; your modifications, start with the "-app /path/to/application.ini"
|
||||
; argument.
|
||||
#endif
|
||||
#if 0
|
||||
; ***** BEGIN LICENSE BLOCK *****
|
||||
; Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
;
|
||||
@ -34,34 +40,38 @@
|
||||
; the terms of any one of the MPL, the GPL or the LGPL.
|
||||
;
|
||||
; ***** END LICENSE BLOCK *****
|
||||
|
||||
#endif
|
||||
#filter substitution
|
||||
[App]
|
||||
Vendor=@MOZ_APP_VENDOR@
|
||||
Name=@MOZ_APP_BASENAME@
|
||||
Version=@APP_VERSION@
|
||||
Version=@MOZ_APP_VERSION@
|
||||
#ifdef MOZ_APP_PROFILE
|
||||
Profile=@MOZ_APP_PROFILE@
|
||||
#endif
|
||||
BuildID=@GRE_BUILDID@
|
||||
BuildID=@APP_BUILDID@
|
||||
#ifdef MOZ_SOURCE_REPO
|
||||
SourceRepository=@MOZ_SOURCE_REPO@
|
||||
#endif
|
||||
#ifdef MOZ_SOURCE_STAMP
|
||||
SourceStamp=@MOZ_SOURCE_STAMP@
|
||||
#endif
|
||||
ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
ID=@MOZ_APP_ID@
|
||||
|
||||
[Gecko]
|
||||
MinVersion=@GRE_MILESTONE@
|
||||
MaxVersion=@GRE_MILESTONE@
|
||||
|
||||
[XRE]
|
||||
#ifdef MOZ_PROFILE_MIGRATOR
|
||||
EnableProfileMigrator=1
|
||||
#endif
|
||||
#ifdef MOZ_EXTENSION_MANAGER
|
||||
EnableExtensionManager=1
|
||||
#endif
|
||||
|
||||
[Crash Reporter]
|
||||
#if MOZILLA_OFFICIAL
|
||||
Enabled=1
|
||||
#endif
|
||||
ServerURL=https://crash-reports.mozilla.com/submit?id=ec8030f7-c20a-464f-9b0e-13a3a9e97384&version=@APP_VERSION@&buildid=@GRE_BUILDID@
|
||||
ServerURL=https://crash-reports.mozilla.com/submit?id=@MOZ_APP_ID@&version=@MOZ_APP_VERSION@&buildid=@APP_BUILDID@
|
@ -340,6 +340,7 @@ user_pref("browser.ui.layout.tablet", 0); // force tablet UI off
|
||||
user_pref("dom.allow_scripts_to_close_windows", true);
|
||||
user_pref("dom.disable_open_during_load", false);
|
||||
user_pref("dom.max_script_run_time", 0); // no slow script dialogs
|
||||
user_pref("hangmonitor.timeout", 0); // no hang monitor
|
||||
user_pref("dom.max_chrome_script_run_time", 0);
|
||||
user_pref("dom.popup_maximum", -1);
|
||||
user_pref("dom.send_after_paint_to_content", true);
|
||||
@ -366,6 +367,9 @@ user_pref("app.update.enabled", false);
|
||||
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
|
||||
user_pref("dom.w3c_touch_events.enabled", true);
|
||||
user_pref("toolkit.telemetry.prompted", 2);
|
||||
// Existing tests assume there is no font size inflation.
|
||||
user_pref("font.size.inflation.emPerLine", 0);
|
||||
user_pref("font.size.inflation.minTwips", 0);
|
||||
|
||||
// Only load extensions from the application and user profile
|
||||
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
|
||||
|
@ -52,9 +52,13 @@ MOZ_APP_DISPLAYNAME = @MOZ_APP_DISPLAYNAME@
|
||||
MOZ_APP_BASENAME = @MOZ_APP_BASENAME@
|
||||
MOZ_APP_VENDOR = @MOZ_APP_VENDOR@
|
||||
MOZ_APP_PROFILE = @MOZ_APP_PROFILE@
|
||||
MOZ_APP_ID = @MOZ_APP_ID@
|
||||
MOZ_PROFILE_MIGRATOR = @MOZ_PROFILE_MIGRATOR@
|
||||
MOZ_EXTENSION_MANAGER = @MOZ_EXTENSION_MANAGER@
|
||||
MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
|
||||
MOZ_APP_VERSION = @MOZ_APP_VERSION@
|
||||
MOZ_UA_BUILDID = @MOZ_UA_BUILDID@
|
||||
MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@
|
||||
|
||||
MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
|
||||
|
||||
|
@ -64,8 +64,6 @@ ifdef SDK_HEADERS
|
||||
EXPORTS += $(SDK_HEADERS)
|
||||
endif
|
||||
|
||||
REPORT_BUILD = @echo $(notdir $<)
|
||||
|
||||
ifeq ($(OS_ARCH),OS2)
|
||||
EXEC =
|
||||
else
|
||||
@ -1150,32 +1148,25 @@ endif # MOZ_AUTO_DEPS
|
||||
|
||||
# Rules for building native targets must come first because of the host_ prefix
|
||||
host_%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
%:: %.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
|
||||
|
||||
%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
@ -1186,7 +1177,6 @@ moc_%.cpp: %.h $(GLOBAL_DEPS)
|
||||
$(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
|
||||
|
||||
moc_%.cc: %.cc $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
|
||||
|
||||
ifdef ASFILES
|
||||
@ -1207,12 +1197,10 @@ endif
|
||||
# Please keep the next two rules in sync.
|
||||
#
|
||||
%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||
echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > t_$*.cc
|
||||
@ -1223,12 +1211,10 @@ else
|
||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||
|
||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
@ -1478,7 +1464,6 @@ XPIDL_DEPS = \
|
||||
$(NULL)
|
||||
|
||||
$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
|
||||
$(REPORT_BUILD)
|
||||
$(PYTHON_PATH) \
|
||||
-I$(topsrcdir)/other-licenses/ply \
|
||||
-I$(topsrcdir)/xpcom/idl-parser \
|
||||
@ -1490,7 +1475,6 @@ ifndef NO_GEN_XPT
|
||||
# generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
|
||||
# into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
|
||||
$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
|
||||
$(REPORT_BUILD)
|
||||
$(PYTHON_PATH) \
|
||||
-I$(topsrcdir)/other-licenses/ply \
|
||||
-I$(topsrcdir)/xpcom/idl-parser \
|
||||
@ -1779,15 +1763,12 @@ define MAKE_DEPS_NOAUTO
|
||||
endef
|
||||
|
||||
$(MDDEPDIR)/%.pp: %.c
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_NOAUTO)
|
||||
|
||||
$(MDDEPDIR)/%.pp: %.cpp
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_NOAUTO)
|
||||
|
||||
$(MDDEPDIR)/%.pp: %.s
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_NOAUTO)
|
||||
|
||||
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
|
||||
|
15
configure.in
15
configure.in
@ -8503,10 +8503,15 @@ AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
|
||||
# - MOZ_APP_DISPLAYNAME: Used in user-visible fields (DLL properties,
|
||||
# Mac Bundle name, Updater, Installer), it is typically used for nightly
|
||||
# builds (e.g. Aurora for Firefox).
|
||||
# - MOZ_APP_VERSION: Defines the application version number.
|
||||
# - MOZ_APP_NAME: Used for e.g. the binary program file name. If not set,
|
||||
# defaults to a lowercase form of MOZ_APP_BASENAME.
|
||||
# - MOZ_APP_PROFILE: When set, used for application.ini's
|
||||
# "Profile" field, which controls profile location.
|
||||
# - MOZ_APP_ID: When set, used for application.ini's "ID" field, and
|
||||
# crash reporter server url.
|
||||
# - MOZ_PROFILE_MIGRATOR: When set, enables profile migrator.
|
||||
# - MOZ_EXTENSION_MANAGER: When set, enabled extension manager.
|
||||
|
||||
if test -z "$MOZ_APP_NAME"; then
|
||||
MOZ_APP_NAME=`echo $MOZ_APP_BASENAME | tr A-Z a-z`
|
||||
@ -8517,6 +8522,9 @@ AC_SUBST(MOZ_APP_DISPLAYNAME)
|
||||
AC_SUBST(MOZ_APP_BASENAME)
|
||||
AC_SUBST(MOZ_APP_VENDOR)
|
||||
AC_SUBST(MOZ_APP_PROFILE)
|
||||
AC_SUBST(MOZ_APP_ID)
|
||||
AC_SUBST(MOZ_PROFILE_MIGRATOR)
|
||||
AC_SUBST(MOZ_EXTENSION_MANAGER)
|
||||
AC_DEFINE_UNQUOTED(MOZ_APP_UA_NAME, "$MOZ_APP_UA_NAME")
|
||||
AC_SUBST(MOZ_APP_UA_NAME)
|
||||
AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION")
|
||||
@ -8527,6 +8535,13 @@ AC_SUBST(FIREFOX_VERSION)
|
||||
AC_DEFINE_UNQUOTED(MOZ_UA_BUILDID, "$MOZ_UA_BUILDID")
|
||||
AC_SUBST(MOZ_UA_BUILDID)
|
||||
|
||||
# We can't use the static application.ini data when building against
|
||||
# a libxul SDK.
|
||||
if test -n "$LIBXUL_SDK"; then
|
||||
MOZ_APP_STATIC_INI=
|
||||
fi
|
||||
AC_SUBST(MOZ_APP_STATIC_INI)
|
||||
|
||||
AC_SUBST(MOZ_PKG_SPECIAL)
|
||||
|
||||
AC_SUBST(MOZILLA_OFFICIAL)
|
||||
|
@ -100,3 +100,4 @@ load 693212.xhtml
|
||||
load 698974-1.html
|
||||
load 700090-1.html
|
||||
load 700090-2.html
|
||||
load xhr_html_nullresponse.html
|
||||
|
5
content/base/crashtests/xhr_html_nullresponse.html
Normal file
5
content/base/crashtests/xhr_html_nullresponse.html
Normal file
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<script>
|
||||
var xhr=new XMLHttpRequest();xhr.open("GET",window.location);xhr.overrideMimeType("text/html");xhr.onprogress=function(){if(xhr.readyState!=3)return;xhr.abort();document.documentElement.removeAttribute('class');};xhr.onabort=function(){xhr.responseText;};xhr.send();
|
||||
</script>
|
@ -124,8 +124,8 @@ class Element;
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0xc3e40e8e, 0x8b91, 0x424c, \
|
||||
{ 0xbe, 0x9c, 0x9c, 0xc1, 0x76, 0xa7, 0xf7, 0x24 } }
|
||||
{ 0x184e0a3c, 0x1899, 0x417d, \
|
||||
{ 0xbf, 0xf4, 0x5a, 0x15, 0xe6, 0xe8, 0xaa, 0x94 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -1562,7 +1562,15 @@ public:
|
||||
virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) = 0;
|
||||
|
||||
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) = 0;
|
||||
|
||||
|
||||
// Called to notify the document that a listener on the "mozaudioavailable"
|
||||
// event has been added. Media elements in the document need to ensure they
|
||||
// fire the event.
|
||||
virtual void NotifyAudioAvailableListener() = 0;
|
||||
|
||||
// Returns true if the document has "mozaudioavailable" event listeners.
|
||||
virtual bool HasAudioAvailableListeners() = 0;
|
||||
|
||||
// Add aLink to the set of links that need their status resolved.
|
||||
void RegisterPendingLinkUpdate(mozilla::dom::Link* aLink);
|
||||
|
||||
|
@ -8237,6 +8237,25 @@ nsDocument::AddImage(imgIRequest* aImage)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
NotifyAudioAvailableListener(nsIContent *aContent, void *aUnused)
|
||||
{
|
||||
#ifdef MOZ_MEDIA
|
||||
nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aContent));
|
||||
if (domMediaElem) {
|
||||
nsHTMLMediaElement* mediaElem = static_cast<nsHTMLMediaElement*>(aContent);
|
||||
mediaElem->NotifyAudioAvailableListener();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::NotifyAudioAvailableListener()
|
||||
{
|
||||
mHasAudioAvailableListener = true;
|
||||
EnumerateFreezableElements(::NotifyAudioAvailableListener, nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::RemoveImage(imgIRequest* aImage)
|
||||
{
|
||||
|
@ -949,6 +949,13 @@ public:
|
||||
|
||||
virtual Element* FindImageMap(const nsAString& aNormalizedMapName);
|
||||
|
||||
virtual void NotifyAudioAvailableListener();
|
||||
|
||||
bool HasAudioAvailableListeners()
|
||||
{
|
||||
return mHasAudioAvailableListener;
|
||||
}
|
||||
|
||||
virtual Element* GetFullScreenElement();
|
||||
virtual void AsyncRequestFullScreen(Element* aElement);
|
||||
virtual void CancelFullScreen();
|
||||
@ -1157,6 +1164,10 @@ protected:
|
||||
// Whether we currently require our images to animate
|
||||
bool mAnimatingImages:1;
|
||||
|
||||
// Whether some node in this document has a listener for the
|
||||
// "mozaudioavailable" event.
|
||||
bool mHasAudioAvailableListener:1;
|
||||
|
||||
// Whether we are currently in full-screen mode, as per the DOM API.
|
||||
bool mIsFullScreen:1;
|
||||
|
||||
|
@ -2167,9 +2167,9 @@ static nsresult GetPartialTextRect(nsLayoutUtils::RectCallback* aCallback,
|
||||
continue;
|
||||
|
||||
// overlapping with the offset we want
|
||||
f->EnsureTextRun();
|
||||
NS_ENSURE_TRUE(f->GetTextRun(), NS_ERROR_OUT_OF_MEMORY);
|
||||
bool rtl = f->GetTextRun()->IsRightToLeft();
|
||||
f->EnsureTextRun(nsTextFrame::eInflated);
|
||||
NS_ENSURE_TRUE(f->GetTextRun(nsTextFrame::eInflated), NS_ERROR_OUT_OF_MEMORY);
|
||||
bool rtl = f->GetTextRun(nsTextFrame::eInflated)->IsRightToLeft();
|
||||
nsRect r(f->GetOffsetTo(relativeTo), f->GetSize());
|
||||
if (fstart < aStartOffset) {
|
||||
// aStartOffset is within this frame
|
||||
|
@ -43,6 +43,8 @@
|
||||
#ifndef nsTextFragment_h___
|
||||
#define nsTextFragment_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
@ -80,7 +82,7 @@ class nsCString;
|
||||
* This class does not have a virtual destructor therefore it is not
|
||||
* meant to be subclassed.
|
||||
*/
|
||||
class NS_FINAL_CLASS nsTextFragment {
|
||||
class nsTextFragment MOZ_FINAL {
|
||||
public:
|
||||
static nsresult Init();
|
||||
static void Shutdown();
|
||||
|
@ -164,7 +164,8 @@ nsWebSocket::CloseConnection()
|
||||
|
||||
if (mReadyState == nsIMozWebSocket::CONNECTING) {
|
||||
SetReadyState(nsIMozWebSocket::CLOSED);
|
||||
mWebSocketChannel->Close(mClientReasonCode, mClientReason);
|
||||
if (mWebSocketChannel)
|
||||
mWebSocketChannel->Close(mClientReasonCode, mClientReason);
|
||||
Disconnect();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1476,7 +1476,7 @@ nsXMLHttpRequest::IsSystemXHR()
|
||||
bool
|
||||
nsXMLHttpRequest::IsWaitingForHTMLCharset()
|
||||
{
|
||||
if (!mIsHtml) {
|
||||
if (!mIsHtml || !mResponseXML) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mResponseXML);
|
||||
|
@ -614,7 +614,8 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
|
||||
PRInt32 status;
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
if (mOptions.antialias &&
|
||||
if (mOptions.antialias &&
|
||||
gfxInfo &&
|
||||
NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_MSAA, &status))) {
|
||||
if (status == nsIGfxInfo::FEATURE_NO_INFO || forceMSAA) {
|
||||
PRUint32 msaaLevel = Preferences::GetUint("webgl.msaa-level", 2);
|
||||
|
@ -2544,7 +2544,8 @@ GetScrollableLineHeight(nsIFrame* aTargetFrame)
|
||||
|
||||
// Fall back to the font height of the target frame.
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aTargetFrame, getter_AddRefs(fm));
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aTargetFrame, getter_AddRefs(fm),
|
||||
nsLayoutUtils::FontSizeInflationFor(aTargetFrame));
|
||||
NS_ASSERTION(fm, "FontMetrics is null!");
|
||||
if (fm)
|
||||
return fm->MaxHeight();
|
||||
|
@ -178,6 +178,13 @@ public:
|
||||
// (no data has arrived for a while).
|
||||
void DownloadStalled();
|
||||
|
||||
// Called when a "MozAudioAvailable" event listener is added. The media
|
||||
// element will then notify its decoder that it needs to make a copy of
|
||||
// the audio data sent to hardware and dispatch it in "mozaudioavailable"
|
||||
// events. This allows us to not perform the copy and thus reduce overhead
|
||||
// in the common case where we don't have a "MozAudioAvailable" listener.
|
||||
void NotifyAudioAvailableListener();
|
||||
|
||||
// Called by the media decoder and the video frame to get the
|
||||
// ImageContainer containing the video data.
|
||||
ImageContainer* GetImageContainer();
|
||||
@ -301,12 +308,6 @@ public:
|
||||
void NotifyAudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength,
|
||||
float aTime);
|
||||
|
||||
/**
|
||||
* Called in order to check whether some node (this window, its document,
|
||||
* or content in that document) has a MozAudioAvailable event listener.
|
||||
*/
|
||||
bool MayHaveAudioAvailableEventListener();
|
||||
|
||||
virtual bool IsNodeOfType(PRUint32 aFlags) const;
|
||||
|
||||
/**
|
||||
|
@ -2008,13 +2008,16 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
// if it was cancelled and a radio button, then set the old
|
||||
// selected btn to TRUE. if it is a checkbox then set it to its
|
||||
// original value
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton =
|
||||
do_QueryInterface(aVisitor.mItemData);
|
||||
if (selectedRadioButton) {
|
||||
selectedRadioButton->SetChecked(true);
|
||||
// If this one is no longer a radio button we must reset it back to
|
||||
// false to cancel the action. See how the web of hack grows?
|
||||
if (mType != NS_FORM_INPUT_RADIO) {
|
||||
if (oldType == NS_FORM_INPUT_RADIO) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton =
|
||||
do_QueryInterface(aVisitor.mItemData);
|
||||
if (selectedRadioButton) {
|
||||
selectedRadioButton->SetChecked(true);
|
||||
}
|
||||
// If there was no checked radio button or this one is no longer a
|
||||
// radio button we must reset it back to false to cancel the action.
|
||||
// See how the web of hack grows?
|
||||
if (!selectedRadioButton || mType != NS_FORM_INPUT_RADIO) {
|
||||
DoSetChecked(false, true, true);
|
||||
}
|
||||
} else if (oldType == NS_FORM_INPUT_CHECKBOX) {
|
||||
|
@ -702,24 +702,6 @@ void nsHTMLMediaElement::NotifyAudioAvailable(float* aFrameBuffer,
|
||||
DispatchAudioAvailableEvent(frameBuffer.forget(), aFrameBufferLength, aTime);
|
||||
}
|
||||
|
||||
bool nsHTMLMediaElement::MayHaveAudioAvailableEventListener()
|
||||
{
|
||||
// Determine if the current element is focused, if it is not focused
|
||||
// then we should not try to blur. Note: we allow for the case of
|
||||
// |var a = new Audio()| with no parent document.
|
||||
nsIDocument *document = GetDocument();
|
||||
if (!document) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsPIDOMWindow *window = document->GetInnerWindow();
|
||||
if (!window) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return window->HasAudioAvailableEventListeners();
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::LoadFromSourceChildren()
|
||||
{
|
||||
NS_ASSERTION(mDelayingLoadEvent,
|
||||
@ -1498,6 +1480,13 @@ nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aPar
|
||||
// The preload action depends on the value of the autoplay attribute.
|
||||
// It's value may have changed, so update it.
|
||||
UpdatePreloadAction();
|
||||
|
||||
if (aDocument->HasAudioAvailableListeners()) {
|
||||
// The document already has listeners for the "MozAudioAvailable"
|
||||
// event, so the decoder must be notified so it initiates
|
||||
// "MozAudioAvailable" event dispatch.
|
||||
NotifyAudioAvailableListener();
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -1914,6 +1903,10 @@ nsresult nsHTMLMediaElement::FinishDecoderSetup(nsMediaDecoder* aDecoder)
|
||||
}
|
||||
}
|
||||
|
||||
if (OwnerDoc()->HasAudioAvailableListeners()) {
|
||||
NotifyAudioAvailableListener();
|
||||
}
|
||||
|
||||
mBegun = true;
|
||||
return rv;
|
||||
}
|
||||
@ -2714,3 +2707,10 @@ NS_IMETHODIMP nsHTMLMediaElement::GetMozFragmentEnd(double *aTime)
|
||||
*aTime = (mFragmentEnd < 0.0 || mFragmentEnd > duration) ? duration : mFragmentEnd;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::NotifyAudioAvailableListener()
|
||||
{
|
||||
if (mDecoder) {
|
||||
mDecoder->NotifyAudioAvailableListener();
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,8 @@ nsAudioAvailableEventManager::nsAudioAvailableEventManager(nsBuiltinDecoder* aDe
|
||||
mSignalBufferLength(mDecoder->GetFrameBufferLength()),
|
||||
mNewSignalBufferLength(mSignalBufferLength),
|
||||
mSignalBufferPosition(0),
|
||||
mReentrantMonitor("media.audioavailableeventmanager")
|
||||
mReentrantMonitor("media.audioavailableeventmanager"),
|
||||
mHasListener(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsAudioAvailableEventManager);
|
||||
}
|
||||
@ -104,6 +105,10 @@ void nsAudioAvailableEventManager::DispatchPendingEvents(PRUint64 aCurrentTime)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
|
||||
if (!mHasListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (mPendingEvents.Length() > 0) {
|
||||
nsAudioAvailableEventRunner* e =
|
||||
(nsAudioAvailableEventRunner*)mPendingEvents[0].get();
|
||||
@ -122,6 +127,10 @@ void nsAudioAvailableEventManager::QueueWrittenAudioData(AudioDataValue* aAudioD
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
|
||||
if (!mHasListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 currentBufferSize = mNewSignalBufferLength;
|
||||
if (currentBufferSize == 0) {
|
||||
NS_WARNING("Decoder framebuffer length not set.");
|
||||
@ -212,6 +221,10 @@ void nsAudioAvailableEventManager::Drain(PRUint64 aEndTime)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
|
||||
if (!mHasListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force all pending events to go now.
|
||||
for (PRUint32 i = 0; i < mPendingEvents.Length(); ++i) {
|
||||
nsCOMPtr<nsIRunnable> event = mPendingEvents[i];
|
||||
@ -245,3 +258,9 @@ void nsAudioAvailableEventManager::SetSignalBufferLength(PRUint32 aLength)
|
||||
mNewSignalBufferLength = aLength;
|
||||
}
|
||||
|
||||
void nsAudioAvailableEventManager::NotifyAudioAvailableListener()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
|
||||
mHasListener = true;
|
||||
}
|
||||
|
@ -80,6 +80,11 @@ public:
|
||||
// Called from the main and the state machine thread.
|
||||
void SetSignalBufferLength(PRUint32 aLength);
|
||||
|
||||
// Called by the media element to notify the manager that there is a
|
||||
// listener on the "MozAudioAvailable" event, and that we need to dispatch
|
||||
// such events. Called from the main thread.
|
||||
void NotifyAudioAvailableListener();
|
||||
|
||||
private:
|
||||
// The decoder associated with the event manager. The event manager shares
|
||||
// the same lifetime as the decoder (the decoder holds a reference to the
|
||||
@ -108,6 +113,11 @@ private:
|
||||
// ReentrantMonitor for shared access to mPendingEvents queue or
|
||||
// buffer length.
|
||||
ReentrantMonitor mReentrantMonitor;
|
||||
|
||||
// True if something in the owning document has a listener on the
|
||||
// "MozAudioAvailable" event. If not, we don't need to bother copying played
|
||||
// audio data and dispatching the event. Synchronized by mReentrantMonitor.
|
||||
bool mHasListener;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -397,14 +397,9 @@ void nsBuiltinDecoder::AudioAvailable(float* aFrameBuffer,
|
||||
// to HTMLMediaElement::NotifyAudioAvailable().
|
||||
nsAutoArrayPtr<float> frameBuffer(aFrameBuffer);
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
if (mShuttingDown) {
|
||||
if (mShuttingDown || !mElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mElement || !mElement->MayHaveAudioAvailableEventListener()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mElement->NotifyAudioAvailable(frameBuffer.forget(), aFrameBufferLength, aTime);
|
||||
}
|
||||
|
||||
@ -1005,6 +1000,16 @@ void nsBuiltinDecoder::UpdatePlaybackOffset(PRInt64 aOffset)
|
||||
mPlaybackPosition = NS_MAX(aOffset, mPlaybackPosition);
|
||||
}
|
||||
|
||||
bool nsBuiltinDecoder::OnStateMachineThread() const {
|
||||
bool nsBuiltinDecoder::OnStateMachineThread() const
|
||||
{
|
||||
return IsCurrentThread(nsBuiltinDecoderStateMachine::GetStateMachineThread());
|
||||
}
|
||||
|
||||
void nsBuiltinDecoder::NotifyAudioAvailableListener()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
if (mDecoderStateMachine) {
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
mDecoderStateMachine->NotifyAudioAvailableListener();
|
||||
}
|
||||
}
|
||||
|
@ -344,6 +344,10 @@ public:
|
||||
// Sets the current size of the framebuffer used in MozAudioAvailable events.
|
||||
// Called on the state machine thread and the main thread.
|
||||
virtual void SetFrameBufferLength(PRUint32 aLength) = 0;
|
||||
|
||||
// Called when a "MozAudioAvailable" event listener is added to the media
|
||||
// element. Called on the main thread.
|
||||
virtual void NotifyAudioAvailableListener() = 0;
|
||||
};
|
||||
|
||||
class nsBuiltinDecoder : public nsMediaDecoder
|
||||
@ -610,6 +614,10 @@ class nsBuiltinDecoder : public nsMediaDecoder
|
||||
// Drop reference to state machine. Only called during shutdown dance.
|
||||
void ReleaseStateMachine() { mDecoderStateMachine = nsnull; }
|
||||
|
||||
// Called when a "MozAudioAvailable" event listener is added to the media
|
||||
// element. Called on the main thread.
|
||||
virtual void NotifyAudioAvailableListener();
|
||||
|
||||
public:
|
||||
// Notifies the element that decoding has failed.
|
||||
void DecodeError();
|
||||
|
@ -2201,4 +2201,8 @@ nsIThread* nsBuiltinDecoderStateMachine::GetStateMachineThread()
|
||||
return StateMachineTracker::Instance().GetGlobalStateMachineThread();
|
||||
}
|
||||
|
||||
|
||||
void nsBuiltinDecoderStateMachine::NotifyAudioAvailableListener()
|
||||
{
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
mEventManager.NotifyAudioAvailableListener();
|
||||
}
|
||||
|
@ -265,6 +265,10 @@ public:
|
||||
// Drop reference to decoder. Only called during shutdown dance.
|
||||
void ReleaseDecoder() { mDecoder = nsnull; }
|
||||
|
||||
// Called when a "MozAudioAvailable" event listener is added to the media
|
||||
// element. Called on the main thread.
|
||||
void NotifyAudioAvailableListener();
|
||||
|
||||
protected:
|
||||
|
||||
// Returns true if we've got less than aAudioUsecs microseconds of decoded
|
||||
|
@ -158,6 +158,11 @@ public:
|
||||
// Call in the main thread only.
|
||||
virtual bool IsEnded() const = 0;
|
||||
|
||||
// Called when a "MozAudioAvailable" event listener is added. This enables
|
||||
// the decoder to only dispatch "MozAudioAvailable" events when a
|
||||
// handler exists, reducing overhead. Called on the main thread.
|
||||
virtual void NotifyAudioAvailableListener() = 0;
|
||||
|
||||
struct Statistics {
|
||||
// Estimate of the current playback rate (bytes/second).
|
||||
double mPlaybackRate;
|
||||
|
@ -766,7 +766,6 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
|
||||
mRunningTimeout(nsnull), mMutationBits(0), mIsDocumentLoaded(false),
|
||||
mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nsnull),
|
||||
mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
|
||||
mMayHaveAudioAvailableEventListener(false),
|
||||
mMayHaveMouseEnterLeaveEventListener(false),
|
||||
mIsModalContentWindow(false),
|
||||
mIsActive(false), mIsBackground(false),
|
||||
@ -10676,6 +10675,14 @@ nsGlobalModalWindow::SetNewDocument(nsIDocument *aDocument,
|
||||
aForceReuseInnerWindow);
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::SetHasAudioAvailableEventListeners()
|
||||
{
|
||||
if (mDoc) {
|
||||
mDoc->NotifyAudioAvailableListener();
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsGlobalWindow: Creator Function (This should go away)
|
||||
//*****************************************************************************
|
||||
|
@ -447,6 +447,8 @@ public:
|
||||
// Prevent further dialogs in this (top level) window
|
||||
void PreventFurtherDialogs();
|
||||
|
||||
virtual void SetHasAudioAvailableEventListeners();
|
||||
|
||||
nsIScriptContext *GetContextInternal()
|
||||
{
|
||||
if (mOuterWindow) {
|
||||
|
@ -927,8 +927,6 @@ static const char js_zeal_option_str[] = JS_OPTIONS_DOT_STR "gczeal";
|
||||
static const char js_zeal_frequency_str[] = JS_OPTIONS_DOT_STR "gczeal.frequency";
|
||||
static const char js_zeal_compartment_str[] = JS_OPTIONS_DOT_STR "gczeal.compartment_gc";
|
||||
#endif
|
||||
static const char js_tracejit_content_str[] = JS_OPTIONS_DOT_STR "tracejit.content";
|
||||
static const char js_tracejit_chrome_str[] = JS_OPTIONS_DOT_STR "tracejit.chrome";
|
||||
static const char js_methodjit_content_str[] = JS_OPTIONS_DOT_STR "methodjit.content";
|
||||
static const char js_methodjit_chrome_str[] = JS_OPTIONS_DOT_STR "methodjit.chrome";
|
||||
static const char js_profiling_content_str[] = JS_OPTIONS_DOT_STR "jitprofiling.content";
|
||||
@ -960,9 +958,6 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
// XXX components be covered by the chrome pref instead of the content one?
|
||||
nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(global));
|
||||
|
||||
bool useTraceJIT = Preferences::GetBool(chromeWindow ?
|
||||
js_tracejit_chrome_str :
|
||||
js_tracejit_content_str);
|
||||
bool useMethodJIT = Preferences::GetBool(chromeWindow ?
|
||||
js_methodjit_chrome_str :
|
||||
js_methodjit_content_str);
|
||||
@ -980,7 +975,6 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
bool safeMode = false;
|
||||
xr->GetInSafeMode(&safeMode);
|
||||
if (safeMode) {
|
||||
useTraceJIT = false;
|
||||
useMethodJIT = false;
|
||||
useProfiling = false;
|
||||
usePCCounts = false;
|
||||
@ -990,11 +984,6 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
if (useTraceJIT)
|
||||
newDefaultJSOptions |= JSOPTION_JIT;
|
||||
else
|
||||
newDefaultJSOptions &= ~JSOPTION_JIT;
|
||||
|
||||
if (useMethodJIT)
|
||||
newDefaultJSOptions |= JSOPTION_METHODJIT;
|
||||
else
|
||||
|
@ -80,8 +80,8 @@ class nsIArray;
|
||||
class nsPIWindowRoot;
|
||||
|
||||
#define NS_PIDOMWINDOW_IID \
|
||||
{ 0x8ce567b5, 0xcc8d, 0x410b, \
|
||||
{ 0xa2, 0x7b, 0x07, 0xaf, 0x31, 0xc0, 0x33, 0xb8 } }
|
||||
{ 0x9db588f7, 0x3472, 0x45d0, \
|
||||
{ 0x9f, 0x9b, 0x95, 0xca, 0xf6, 0x4d, 0x1a, 0xb1 } }
|
||||
|
||||
class nsPIDOMWindow : public nsIDOMWindowInternal
|
||||
{
|
||||
@ -457,23 +457,11 @@ public:
|
||||
return mMayHaveTouchEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to check whether some node (this window, its document,
|
||||
* or content in that document) has a MozAudioAvailable event listener.
|
||||
*/
|
||||
bool HasAudioAvailableEventListeners()
|
||||
{
|
||||
return mMayHaveAudioAvailableEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to indicate that some node (this window, its document,
|
||||
* or content in that document) has a MozAudioAvailable event listener.
|
||||
* or content in that document) has a "MozAudioAvailable" event listener.
|
||||
*/
|
||||
void SetHasAudioAvailableEventListeners()
|
||||
{
|
||||
mMayHaveAudioAvailableEventListener = true;
|
||||
}
|
||||
virtual void SetHasAudioAvailableEventListeners() = 0;
|
||||
|
||||
/**
|
||||
* Call this to check whether some node (this window, its document,
|
||||
@ -657,7 +645,6 @@ protected:
|
||||
bool mIsInnerWindow;
|
||||
bool mMayHavePaintEventListener;
|
||||
bool mMayHaveTouchEventListener;
|
||||
bool mMayHaveAudioAvailableEventListener;
|
||||
bool mMayHaveMouseEnterLeaveEventListener;
|
||||
|
||||
// This variable is used on both inner and outer windows (and they
|
||||
|
@ -408,7 +408,8 @@ AsyncConnectionHelper::Init()
|
||||
already_AddRefed<nsDOMEvent>
|
||||
AsyncConnectionHelper::CreateSuccessEvent()
|
||||
{
|
||||
return CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR));
|
||||
return CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR),
|
||||
eDoesNotBubble, eNotCancelable);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -453,7 +454,8 @@ AsyncConnectionHelper::OnError()
|
||||
|
||||
// Make an error event and fire it at the target.
|
||||
nsRefPtr<nsDOMEvent> event =
|
||||
CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR), true);
|
||||
CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR), eDoesBubble,
|
||||
eCancelable);
|
||||
if (!event) {
|
||||
NS_ERROR("Failed to create event!");
|
||||
return;
|
||||
|
@ -379,12 +379,14 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBDatabase)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnVersionChangeListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnVersionChangeListener)
|
||||
|
||||
@ -725,6 +727,19 @@ IDBDatabase::Close()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::SetOnabort(nsIDOMEventListener* aAbortListener)
|
||||
{
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_EVT_STR),
|
||||
mOnAbortListener, aAbortListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::GetOnabort(nsIDOMEventListener** aAbortListener)
|
||||
{
|
||||
return GetInnerEventListener(mOnAbortListener, aAbortListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::SetOnerror(nsIDOMEventListener* aErrorListener)
|
||||
{
|
||||
@ -764,7 +779,8 @@ IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (type.EqualsLiteral(ERROR_EVT_STR)) {
|
||||
nsRefPtr<nsDOMEvent> duplicateEvent = CreateGenericEvent(type);
|
||||
nsRefPtr<nsDOMEvent> duplicateEvent =
|
||||
CreateGenericEvent(type, eDoesNotBubble, eNotCancelable);
|
||||
NS_ENSURE_STATE(duplicateEvent);
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mOwner));
|
||||
|
@ -161,6 +161,7 @@ private:
|
||||
bool mRunningVersionChange;
|
||||
|
||||
// Only touched on the main thread.
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnVersionChangeListener;
|
||||
};
|
||||
|
@ -78,11 +78,13 @@ private:
|
||||
|
||||
already_AddRefed<nsDOMEvent>
|
||||
mozilla::dom::indexedDB::CreateGenericEvent(const nsAString& aType,
|
||||
bool aBubblesAndCancelable)
|
||||
Bubbles aBubbles,
|
||||
Cancelable aCancelable)
|
||||
{
|
||||
nsRefPtr<nsDOMEvent> event(new nsDOMEvent(nsnull, nsnull));
|
||||
nsresult rv = event->InitEvent(aType, aBubblesAndCancelable,
|
||||
aBubblesAndCancelable);
|
||||
nsresult rv = event->InitEvent(aType,
|
||||
aBubbles == eDoesBubble ? true : false,
|
||||
aCancelable == eCancelable ? true : false);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
rv = event->SetTrusted(true);
|
||||
@ -91,17 +93,6 @@ mozilla::dom::indexedDB::CreateGenericEvent(const nsAString& aType,
|
||||
return event.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIRunnable>
|
||||
mozilla::dom::indexedDB::CreateGenericEventRunnable(const nsAString& aType,
|
||||
nsIDOMEventTarget* aTarget)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEvent> event(CreateGenericEvent(aType));
|
||||
NS_ENSURE_TRUE(event, nsnull);
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
|
||||
return runnable.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsDOMEvent>
|
||||
IDBVersionChangeEvent::CreateInternal(const nsAString& aType,
|
||||
|
@ -59,13 +59,20 @@
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
enum Bubbles {
|
||||
eDoesNotBubble,
|
||||
eDoesBubble
|
||||
};
|
||||
|
||||
enum Cancelable {
|
||||
eNotCancelable,
|
||||
eCancelable
|
||||
};
|
||||
|
||||
already_AddRefed<nsDOMEvent>
|
||||
CreateGenericEvent(const nsAString& aType,
|
||||
bool aBubblesAndCancelable = false);
|
||||
|
||||
already_AddRefed<nsIRunnable>
|
||||
CreateGenericEventRunnable(const nsAString& aType,
|
||||
nsIDOMEventTarget* aTarget);
|
||||
Bubbles aBubbles,
|
||||
Cancelable aCancelable);
|
||||
|
||||
class IDBVersionChangeEvent : public nsDOMEvent,
|
||||
public nsIIDBVersionChangeEvent
|
||||
|
@ -1160,12 +1160,12 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( value = :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ") + keyColumn +
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value >= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ( value > :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" OR ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(" > :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( value > :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value >= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" LIMIT ");
|
||||
break;
|
||||
@ -1178,7 +1178,7 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value > :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value >= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
@ -1190,12 +1190,13 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( value = :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ") + keyColumn +
|
||||
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value <= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" AND ( value < :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" OR ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(" < :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( value < :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" ) ") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value <= :") +
|
||||
currentKey + NS_LITERAL_CSTRING(" LIMIT ");
|
||||
break;
|
||||
@ -1208,7 +1209,7 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND value < :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND value <= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
@ -1251,7 +1252,7 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
if (mIndex->IsAutoIncrement()) {
|
||||
objectTable.AssignLiteral("ai_object_data");
|
||||
objectDataIdColumn.AssignLiteral("ai_object_data_id");
|
||||
keyValueColumn.AssignLiteral("id");
|
||||
keyValueColumn.AssignLiteral("ai_object_data_id");
|
||||
if (mIndex->IsUnique()) {
|
||||
indexTable.AssignLiteral("ai_unique_index_data");
|
||||
}
|
||||
@ -1262,7 +1263,7 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
else {
|
||||
objectTable.AssignLiteral("object_data");
|
||||
objectDataIdColumn.AssignLiteral("object_data_id");
|
||||
keyValueColumn.AssignLiteral("key_value");
|
||||
keyValueColumn.AssignLiteral("object_data_key");
|
||||
if (mIndex->IsUnique()) {
|
||||
indexTable.AssignLiteral("unique_index_data");
|
||||
}
|
||||
@ -1271,11 +1272,8 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(id, "id");
|
||||
|
||||
nsCString value = indexTable + NS_LITERAL_CSTRING(".value");
|
||||
nsCString data = objectTable + NS_LITERAL_CSTRING(".data");
|
||||
nsCString keyValue = objectTable + NS_LITERAL_CSTRING(".") + keyValueColumn;
|
||||
nsCString keyValue = indexTable + NS_LITERAL_CSTRING(".") + keyValueColumn;
|
||||
|
||||
nsCString keyRangeClause;
|
||||
if (mKeyRange) {
|
||||
@ -1304,16 +1302,21 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
NS_NOTREACHED("Unknown direction!");
|
||||
}
|
||||
|
||||
nsCString firstQuery = NS_LITERAL_CSTRING("SELECT ") + value +
|
||||
NS_LITERAL_CSTRING(", ") + keyValue +
|
||||
NS_LITERAL_CSTRING(", ") + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + objectDataIdColumn +
|
||||
NS_LITERAL_CSTRING(" = ") + objectTable +
|
||||
NS_LITERAL_CSTRING(".id WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :id") +
|
||||
NS_NAMED_LITERAL_CSTRING(id, "id");
|
||||
NS_NAMED_LITERAL_CSTRING(dot, ".");
|
||||
NS_NAMED_LITERAL_CSTRING(commaspace, ", ");
|
||||
|
||||
nsCString data = objectTable + NS_LITERAL_CSTRING(".data");
|
||||
|
||||
nsCString firstQuery = NS_LITERAL_CSTRING("SELECT ") + value + commaspace +
|
||||
keyValue + commaspace + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable + dot +
|
||||
objectDataIdColumn + NS_LITERAL_CSTRING(" = ") +
|
||||
objectTable + dot + id +
|
||||
NS_LITERAL_CSTRING(" WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :") + id +
|
||||
keyRangeClause + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
|
||||
@ -1352,20 +1355,29 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
|
||||
// Now we need to make the query to get the next match.
|
||||
nsCAutoString queryStart = NS_LITERAL_CSTRING("SELECT ") + value +
|
||||
NS_LITERAL_CSTRING(", ") + keyValue +
|
||||
NS_LITERAL_CSTRING(", ") + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".") + objectDataIdColumn +
|
||||
NS_LITERAL_CSTRING(" = ") + objectTable +
|
||||
NS_LITERAL_CSTRING(".id WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :id");
|
||||
commaspace + keyValue + commaspace + data +
|
||||
NS_LITERAL_CSTRING(" FROM ") + indexTable +
|
||||
NS_LITERAL_CSTRING(" INNER JOIN ") + objectTable +
|
||||
NS_LITERAL_CSTRING(" ON ") + indexTable + dot +
|
||||
objectDataIdColumn + NS_LITERAL_CSTRING(" = ") +
|
||||
objectTable + dot + id +
|
||||
NS_LITERAL_CSTRING(" WHERE ") + indexTable +
|
||||
NS_LITERAL_CSTRING(".index_id = :") + id;
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(currentKey, "current_key");
|
||||
NS_NAMED_LITERAL_CSTRING(rangeKey, "range_key");
|
||||
NS_NAMED_LITERAL_CSTRING(objectKey, "object_key");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(andStr, " AND ");
|
||||
NS_NAMED_LITERAL_CSTRING(orStr, " OR ");
|
||||
NS_NAMED_LITERAL_CSTRING(ge, " >= :");
|
||||
NS_NAMED_LITERAL_CSTRING(gt, " > :");
|
||||
NS_NAMED_LITERAL_CSTRING(le, " <= :");
|
||||
NS_NAMED_LITERAL_CSTRING(lt, " < :");
|
||||
NS_NAMED_LITERAL_CSTRING(openparen, " ( ");
|
||||
NS_NAMED_LITERAL_CSTRING(closeparen, " ) ");
|
||||
NS_NAMED_LITERAL_CSTRING(limit, " LIMIT ");
|
||||
|
||||
switch (mDirection) {
|
||||
case nsIIDBCursor::NEXT:
|
||||
if (mKeyRange && !mKeyRange->Upper().IsUnset()) {
|
||||
@ -1373,18 +1385,11 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( ") +
|
||||
value + NS_LITERAL_CSTRING(" = :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" AND ") + keyValue +
|
||||
NS_LITERAL_CSTRING(" > :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( ") + value +
|
||||
NS_LITERAL_CSTRING(" > :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" >= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + ge + currentKey + andStr +
|
||||
openparen + value + gt + currentKey + orStr + keyValue +
|
||||
gt + objectKey + closeparen + directionClause + limit;
|
||||
mContinueToQuery = queryStart + andStr + value + ge + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::NEXT_NO_DUPLICATE:
|
||||
@ -1393,12 +1398,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Upper();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" > :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" >= :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + gt + currentKey +
|
||||
directionClause + limit;
|
||||
mContinueToQuery = queryStart + andStr + value + ge + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::PREV:
|
||||
@ -1407,18 +1410,11 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ( ( ") +
|
||||
value + NS_LITERAL_CSTRING(" = :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" AND ") + keyValue +
|
||||
NS_LITERAL_CSTRING(" < :") + objectKey +
|
||||
NS_LITERAL_CSTRING(" ) OR ( ") + value +
|
||||
NS_LITERAL_CSTRING(" < :") + currentKey +
|
||||
NS_LITERAL_CSTRING(" ) )") + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" <= :") +
|
||||
currentKey + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + le + currentKey + andStr +
|
||||
openparen + value + lt + currentKey + orStr + keyValue +
|
||||
lt + objectKey + closeparen + directionClause + limit;
|
||||
mContinueToQuery = queryStart + andStr + value + le + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
case nsIIDBCursor::PREV_NO_DUPLICATE:
|
||||
@ -1427,12 +1423,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
queryStart);
|
||||
mRangeKey = mKeyRange->Lower();
|
||||
}
|
||||
mContinueQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" < :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueToQuery = queryStart + NS_LITERAL_CSTRING(" AND ") + value +
|
||||
NS_LITERAL_CSTRING(" <= :") + currentKey +
|
||||
directionClause + NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
mContinueQuery = queryStart + andStr + value + lt + currentKey +
|
||||
directionClause +limit;
|
||||
mContinueToQuery = queryStart + andStr + value + le + currentKey +
|
||||
directionClause + limit;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -428,7 +428,9 @@ GetKeyFromValue(JSContext* aCx,
|
||||
Key& aKey)
|
||||
{
|
||||
NS_ASSERTION(aCx, "Null pointer!");
|
||||
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(aVal), "Why are we here!?");
|
||||
// aVal can be primitive iff the key path is empty.
|
||||
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(aVal) || aKeyPath.IsEmpty(),
|
||||
"Why are we here!?");
|
||||
NS_ASSERTION(IDBObjectStore::IsValidKeyPath(aCx, aKeyPath),
|
||||
"This will explode!");
|
||||
|
||||
@ -580,7 +582,6 @@ IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
|
||||
{
|
||||
NS_ASSERTION(aData, "Null pointer!");
|
||||
NS_ASSERTION(aDataLength, "Empty data!");
|
||||
NS_ASSERTION(!aKeyPath.IsEmpty(), "Empty keyPath!");
|
||||
NS_ASSERTION(aCx, "Null pointer!");
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
@ -592,7 +593,7 @@ IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(clone)) {
|
||||
if (JSVAL_IS_PRIMITIVE(clone) && !aKeyPath.IsEmpty()) {
|
||||
// This isn't an object, so just leave the key unset.
|
||||
aValue.Unset();
|
||||
return NS_OK;
|
||||
@ -614,7 +615,7 @@ IDBObjectStore::GetIndexUpdateInfo(ObjectStoreInfo* aObjectStoreInfo,
|
||||
JSObject* cloneObj = nsnull;
|
||||
|
||||
PRUint32 count = aObjectStoreInfo->indexes.Length();
|
||||
if (count && !JSVAL_IS_PRIMITIVE(aObject)) {
|
||||
if (count) {
|
||||
if (!aUpdateInfoArray.SetCapacity(count)) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -623,6 +624,10 @@ IDBObjectStore::GetIndexUpdateInfo(ObjectStoreInfo* aObjectStoreInfo,
|
||||
for (PRUint32 indexesIndex = 0; indexesIndex < count; indexesIndex++) {
|
||||
const IndexInfo& indexInfo = aObjectStoreInfo->indexes[indexesIndex];
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(aObject) && !indexInfo.keyPath.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Key value;
|
||||
nsresult rv = GetKeyFromValue(aCx, aObject, indexInfo.keyPath, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -664,7 +669,6 @@ IDBObjectStore::UpdateIndexes(IDBTransaction* aTransaction,
|
||||
#endif
|
||||
|
||||
PRUint32 indexCount = aUpdateInfoArray.Length();
|
||||
NS_ASSERTION(indexCount, "Don't call me!");
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
nsresult rv;
|
||||
@ -702,34 +706,59 @@ IDBObjectStore::UpdateIndexes(IDBTransaction* aTransaction,
|
||||
|
||||
NS_ASSERTION(aObjectDataId != LL_MININT, "Bad objectData id!");
|
||||
|
||||
for (PRUint32 indexIndex = 0; indexIndex < indexCount; indexIndex++) {
|
||||
const IndexUpdateInfo& updateInfo = aUpdateInfoArray[indexIndex];
|
||||
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
|
||||
NS_NAMED_LITERAL_CSTRING(objectDataId, "object_data_id");
|
||||
NS_NAMED_LITERAL_CSTRING(objectDataKey, "object_data_key");
|
||||
NS_NAMED_LITERAL_CSTRING(value, "value");
|
||||
|
||||
stmt = aTransaction->IndexUpdateStatement(updateInfo.info.autoIncrement,
|
||||
updateInfo.info.unique,
|
||||
aOverwrite);
|
||||
if (aOverwrite) {
|
||||
stmt = aTransaction->IndexDataDeleteStatement(aAutoIncrement, false);
|
||||
NS_ENSURE_TRUE(stmt, NS_ERROR_FAILURE);
|
||||
|
||||
mozStorageStatementScoper scoper2(stmt);
|
||||
|
||||
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("index_id"),
|
||||
updateInfo.info.id);
|
||||
rv = stmt->BindInt64ByName(objectDataId, aObjectDataId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("object_data_id"),
|
||||
aObjectDataId);
|
||||
rv = stmt->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
stmt = aTransaction->IndexDataDeleteStatement(aAutoIncrement, true);
|
||||
NS_ENSURE_TRUE(stmt, NS_ERROR_FAILURE);
|
||||
|
||||
mozStorageStatementScoper scoper3(stmt);
|
||||
|
||||
rv = stmt->BindInt64ByName(objectDataId, aObjectDataId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
for (PRUint32 indexIndex = 0; indexIndex < indexCount; indexIndex++) {
|
||||
const IndexUpdateInfo& updateInfo = aUpdateInfoArray[indexIndex];
|
||||
|
||||
NS_ASSERTION(updateInfo.info.autoIncrement == aAutoIncrement, "Huh?!");
|
||||
|
||||
// Insert new values.
|
||||
stmt = aTransaction->IndexDataInsertStatement(aAutoIncrement,
|
||||
updateInfo.info.unique);
|
||||
NS_ENSURE_TRUE(stmt, NS_ERROR_FAILURE);
|
||||
|
||||
mozStorageStatementScoper scoper4(stmt);
|
||||
|
||||
rv = stmt->BindInt64ByName(indexId, updateInfo.info.id);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->BindInt64ByName(objectDataId, aObjectDataId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!updateInfo.info.autoIncrement) {
|
||||
rv =
|
||||
aObjectStoreKey.BindToStatement(stmt,
|
||||
NS_LITERAL_CSTRING("object_data_key"));
|
||||
rv = aObjectStoreKey.BindToStatement(stmt, objectDataKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv =
|
||||
updateInfo.value.BindToStatementAllowUnset(stmt,
|
||||
NS_LITERAL_CSTRING("value"));
|
||||
rv = updateInfo.value.BindToStatement(stmt, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->Execute();
|
||||
@ -1310,10 +1339,6 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (aKeyPath.IsEmpty()) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||
}
|
||||
|
||||
if (!IsValidKeyPath(aCx, aKeyPath)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
@ -1718,7 +1743,7 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
}
|
||||
|
||||
// Update our indexes if needed.
|
||||
if (!mIndexUpdateInfo.IsEmpty()) {
|
||||
if (mOverwrite || !mIndexUpdateInfo.IsEmpty()) {
|
||||
PRInt64 objectDataId = autoIncrement ? mKey.ToInteger() : LL_MININT;
|
||||
rv = IDBObjectStore::UpdateIndexes(mTransaction, osid, mKey,
|
||||
autoIncrement, mOverwrite,
|
||||
@ -1930,7 +1955,8 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
nsCString firstQuery = NS_LITERAL_CSTRING("SELECT ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(", data FROM ") + table +
|
||||
NS_LITERAL_CSTRING(" WHERE object_store_id = :") +
|
||||
id + keyRangeClause + directionClause;
|
||||
id + keyRangeClause + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt =
|
||||
mTransaction->GetCachedStatement(firstQuery);
|
||||
@ -2009,7 +2035,7 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
NS_LITERAL_CSTRING(", data FROM ") + table +
|
||||
NS_LITERAL_CSTRING(" WHERE object_store_id = :") + id +
|
||||
keyRangeClause + directionClause +
|
||||
NS_LITERAL_CSTRING(" LIMIT 1");
|
||||
NS_LITERAL_CSTRING(" LIMIT ");
|
||||
|
||||
mContinueToQuery = NS_LITERAL_CSTRING("SELECT ") + keyColumn +
|
||||
NS_LITERAL_CSTRING(", data FROM ") + table +
|
||||
@ -2215,8 +2241,8 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
|
||||
bool hasResult;
|
||||
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
|
||||
nsCOMPtr<mozIStorageStatement> insertStmt =
|
||||
mTransaction->IndexUpdateStatement(mIndex->IsAutoIncrement(),
|
||||
mIndex->IsUnique(), false);
|
||||
mTransaction->IndexDataInsertStatement(mIndex->IsAutoIncrement(),
|
||||
mIndex->IsUnique());
|
||||
NS_ENSURE_TRUE(insertStmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
mozStorageStatementScoper scoper2(insertStmt);
|
||||
|
@ -394,28 +394,13 @@ IDBTransaction::AddStatement(bool aCreate,
|
||||
}
|
||||
|
||||
already_AddRefed<mozIStorageStatement>
|
||||
IDBTransaction::IndexUpdateStatement(bool aAutoIncrement,
|
||||
bool aUnique,
|
||||
bool aOverwrite)
|
||||
IDBTransaction::IndexDataInsertStatement(bool aAutoIncrement,
|
||||
bool aUnique)
|
||||
{
|
||||
if (aAutoIncrement) {
|
||||
if (aUnique) {
|
||||
if (aOverwrite) {
|
||||
return GetCachedStatement(
|
||||
"INSERT OR REPLACE INTO ai_unique_index_data "
|
||||
"(index_id, ai_object_data_id, value) "
|
||||
"VALUES (:index_id, :object_data_id, :value)"
|
||||
);
|
||||
}
|
||||
return GetCachedStatement(
|
||||
"INSERT INTO ai_unique_index_data "
|
||||
"(index_id, aI_object_data_id, value) "
|
||||
"VALUES (:index_id, :object_data_id, :value)"
|
||||
);
|
||||
}
|
||||
if (aOverwrite) {
|
||||
return GetCachedStatement(
|
||||
"INSERT OR REPLACE INTO ai_index_data "
|
||||
"(index_id, ai_object_data_id, value) "
|
||||
"VALUES (:index_id, :object_data_id, :value)"
|
||||
);
|
||||
@ -427,26 +412,12 @@ IDBTransaction::IndexUpdateStatement(bool aAutoIncrement,
|
||||
);
|
||||
}
|
||||
if (aUnique) {
|
||||
if (aOverwrite) {
|
||||
return GetCachedStatement(
|
||||
"INSERT OR REPLACE INTO unique_index_data "
|
||||
"(index_id, object_data_id, object_data_key, value) "
|
||||
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
|
||||
);
|
||||
}
|
||||
return GetCachedStatement(
|
||||
"INSERT INTO unique_index_data "
|
||||
"(index_id, object_data_id, object_data_key, value) "
|
||||
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
|
||||
);
|
||||
}
|
||||
if (aOverwrite) {
|
||||
return GetCachedStatement(
|
||||
"INSERT INTO index_data ("
|
||||
"index_id, object_data_id, object_data_key, value) "
|
||||
"VALUES (:index_id, :object_data_id, :object_data_key, :value)"
|
||||
);
|
||||
}
|
||||
return GetCachedStatement(
|
||||
"INSERT INTO index_data ("
|
||||
"index_id, object_data_id, object_data_key, value) "
|
||||
@ -454,6 +425,34 @@ IDBTransaction::IndexUpdateStatement(bool aAutoIncrement,
|
||||
);
|
||||
}
|
||||
|
||||
already_AddRefed<mozIStorageStatement>
|
||||
IDBTransaction::IndexDataDeleteStatement(bool aAutoIncrement,
|
||||
bool aUnique)
|
||||
{
|
||||
if (aAutoIncrement) {
|
||||
if (aUnique) {
|
||||
return GetCachedStatement(
|
||||
"DELETE FROM ai_unique_index_data "
|
||||
"WHERE ai_object_data_id = :object_data_id"
|
||||
);
|
||||
}
|
||||
return GetCachedStatement(
|
||||
"DELETE FROM ai_index_data "
|
||||
"WHERE ai_object_data_id = :object_data_id"
|
||||
);
|
||||
}
|
||||
if (aUnique) {
|
||||
return GetCachedStatement(
|
||||
"DELETE FROM unique_index_data "
|
||||
"WHERE object_data_id = :object_data_id"
|
||||
);
|
||||
}
|
||||
return GetCachedStatement(
|
||||
"DELETE FROM index_data "
|
||||
"WHERE object_data_id = :object_data_id"
|
||||
);
|
||||
}
|
||||
|
||||
already_AddRefed<mozIStorageStatement>
|
||||
IDBTransaction::GetCachedStatement(const nsACString& aQuery)
|
||||
{
|
||||
@ -854,10 +853,12 @@ CommitHelper::Run()
|
||||
}
|
||||
}
|
||||
|
||||
event = CreateGenericEvent(NS_LITERAL_STRING(ABORT_EVT_STR));
|
||||
event = CreateGenericEvent(NS_LITERAL_STRING(ABORT_EVT_STR),
|
||||
eDoesBubble, eNotCancelable);
|
||||
}
|
||||
else {
|
||||
event = CreateGenericEvent(NS_LITERAL_STRING(COMPLETE_EVT_STR));
|
||||
event = CreateGenericEvent(NS_LITERAL_STRING(COMPLETE_EVT_STR),
|
||||
eDoesNotBubble, eNotCancelable);
|
||||
}
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
|
@ -118,9 +118,12 @@ public:
|
||||
bool aAutoIncrement);
|
||||
|
||||
already_AddRefed<mozIStorageStatement>
|
||||
IndexUpdateStatement(bool aAutoIncrement,
|
||||
bool aUnique,
|
||||
bool aOverwrite);
|
||||
IndexDataInsertStatement(bool aAutoIncrement,
|
||||
bool aUnique);
|
||||
|
||||
already_AddRefed<mozIStorageStatement>
|
||||
IndexDataDeleteStatement(bool aAutoIncrement,
|
||||
bool aUnique);
|
||||
|
||||
already_AddRefed<mozIStorageStatement>
|
||||
GetCachedStatement(const nsACString& aQuery);
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#define DB_SCHEMA_VERSION 5
|
||||
#define DB_SCHEMA_VERSION 6
|
||||
|
||||
#define BEGIN_INDEXEDDB_NAMESPACE \
|
||||
namespace mozilla { namespace dom { namespace indexedDB {
|
||||
|
@ -248,19 +248,6 @@ public:
|
||||
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsresult BindToStatementAllowUnset(mozIStorageStatement* aStatement,
|
||||
const nsACString& aParamName) const
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (IsUnset()) {
|
||||
rv = aStatement->BindStringByName(aParamName, EmptyString());
|
||||
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
return BindToStatement(aStatement, aParamName);
|
||||
}
|
||||
|
||||
nsresult SetFromStatement(mozIStorageStatement* aStatement,
|
||||
PRUint32 aIndex)
|
||||
{
|
||||
|
@ -121,11 +121,10 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
// Table `object_store`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_store ("
|
||||
"id INTEGER, "
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"name TEXT NOT NULL, "
|
||||
"key_path TEXT NOT NULL, "
|
||||
"auto_increment INTEGER NOT NULL DEFAULT 0, "
|
||||
"PRIMARY KEY (id), "
|
||||
"UNIQUE (name)"
|
||||
");"
|
||||
));
|
||||
@ -134,41 +133,30 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
// Table `object_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_data ("
|
||||
"id INTEGER, "
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"key_value DEFAULT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"key_value DEFAULT NULL, " // NONE affinity
|
||||
"PRIMARY KEY (id), "
|
||||
"UNIQUE (object_store_id, key_value), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE UNIQUE INDEX key_index "
|
||||
"ON object_data (key_value, object_store_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `ai_object_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_object_data ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"UNIQUE (object_store_id, id), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE UNIQUE INDEX ai_key_index "
|
||||
"ON ai_object_data (id, object_store_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `index`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_store_index ("
|
||||
@ -189,12 +177,11 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
// Table `index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"object_data_key NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||
@ -203,21 +190,21 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from object_data and object_store fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX value_index "
|
||||
"ON index_data (index_id, value);"
|
||||
"CREATE INDEX index_data_object_data_id_index "
|
||||
"ON index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `unique_index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE unique_index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"object_data_key NOT NULL, " // NONE affinity
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"UNIQUE (index_id, value), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE "
|
||||
@ -227,14 +214,20 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from object_data and object_store fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX unique_index_data_object_data_id_index "
|
||||
"ON unique_index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `ai_index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
@ -243,21 +236,22 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from ai_object_data and object_store
|
||||
// fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_value_index "
|
||||
"ON ai_index_data (index_id, value);"
|
||||
"CREATE INDEX ai_index_data_ai_object_data_id_index "
|
||||
"ON ai_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Table `ai_unique_index_data`
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_unique_index_data ("
|
||||
"id INTEGER, "
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"PRIMARY KEY (id), "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"UNIQUE (index_id, value), "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
@ -266,6 +260,14 @@ CreateTables(mozIStorageConnection* aDBConn)
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need this to make cascading deletes from ai_object_data and object_store
|
||||
// fast.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_unique_index_data_ai_object_data_id_index "
|
||||
"ON ai_unique_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aDBConn->SetSchemaVersion(DB_SCHEMA_VERSION);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -377,7 +379,372 @@ UpgradeSchemaFrom4To5(mozIStorageConnection* aConnection)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = aConnection->SetSchemaVersion(DB_SCHEMA_VERSION);
|
||||
rv = aConnection->SetSchemaVersion(5);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UpgradeSchemaFrom5To6(mozIStorageConnection* aConnection)
|
||||
{
|
||||
mozStorageTransaction transaction(aConnection, false,
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
// Turn off foreign key constraints before we do anything here.
|
||||
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"PRAGMA foreign_keys = OFF;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// First, drop all the indexes we're no longer going to use.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX key_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX ai_key_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX value_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP INDEX ai_value_index;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now, reorder the columns of object_data to put the blob data last. We do
|
||||
// this by copying into a temporary table, dropping the original, then copying
|
||||
// back into a newly created table.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id, "
|
||||
"key_value, "
|
||||
"data "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT id, object_store_id, key_value, data "
|
||||
"FROM object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE object_data ("
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"key_value DEFAULT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"UNIQUE (object_store_id, key_value), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO object_data "
|
||||
"SELECT id, object_store_id, key_value, data "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We need to add a unique constraint to our ai_object_data table. Copy all
|
||||
// the data out of it using a temporary table as before.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"id INTEGER PRIMARY KEY, "
|
||||
"object_store_id, "
|
||||
"data "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT id, object_store_id, data "
|
||||
"FROM ai_object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE ai_object_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_object_data ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
"object_store_id INTEGER NOT NULL, "
|
||||
"data BLOB NOT NULL, "
|
||||
"UNIQUE (object_store_id, id), "
|
||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO ai_object_data "
|
||||
"SELECT id, object_store_id, data "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the index_data table. We're reordering the columns as well as
|
||||
// changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"object_data_key, "
|
||||
"object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"object_data_key NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT OR IGNORE INTO index_data "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX index_data_object_data_id_index "
|
||||
"ON index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the unique_index_data table. We're reordering the columns as well as
|
||||
// changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"object_data_key, "
|
||||
"object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE unique_index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"object_data_key NOT NULL, "
|
||||
"object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, object_data_key), "
|
||||
"UNIQUE (index_id, value), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE "
|
||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO unique_index_data "
|
||||
"SELECT index_id, value, object_data_key, object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX unique_index_data_object_data_id_index "
|
||||
"ON unique_index_data (object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the ai_index_data table. We're reordering the columns as well as
|
||||
// changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"ai_object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM ai_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE ai_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT OR IGNORE INTO ai_index_data "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_index_data_ai_object_data_id_index "
|
||||
"ON ai_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Fix up the ai_unique_index_data table. We're reordering the columns as well
|
||||
// as changing the primary key from being a simple id to being a composite.
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TEMPORARY TABLE temp_upgrade ("
|
||||
"index_id, "
|
||||
"value, "
|
||||
"ai_object_data_id "
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO temp_upgrade "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM ai_unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE ai_unique_index_data;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE ai_unique_index_data ("
|
||||
"index_id INTEGER NOT NULL, "
|
||||
"value NOT NULL, "
|
||||
"ai_object_data_id INTEGER NOT NULL, "
|
||||
"UNIQUE (index_id, value), "
|
||||
"PRIMARY KEY (index_id, value, ai_object_data_id), "
|
||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||
"CASCADE, "
|
||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||
"CASCADE"
|
||||
");"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO ai_unique_index_data "
|
||||
"SELECT index_id, value, ai_object_data_id "
|
||||
"FROM temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE temp_upgrade;"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX ai_unique_index_data_ai_object_data_id_index "
|
||||
"ON ai_unique_index_data (ai_object_data_id);"
|
||||
));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aConnection->SetSchemaVersion(6);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
@ -393,14 +760,6 @@ CreateDatabaseConnection(const nsAString& aName,
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsCOMPtr<nsIFile> dbDirectory;
|
||||
nsresult rv = aDBFile->GetParent(getter_AddRefs(dbDirectory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool exists;
|
||||
rv = aDBFile->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(quotaVFSName, "quota");
|
||||
|
||||
nsCOMPtr<mozIStorageServiceQuotaManagement> ss =
|
||||
@ -408,15 +767,13 @@ CreateDatabaseConnection(const nsAString& aName,
|
||||
NS_ENSURE_TRUE(ss, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> connection;
|
||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
nsresult rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
// Nuke the database file. The web services can recreate their data.
|
||||
rv = aDBFile->Remove(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
exists = false;
|
||||
|
||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
}
|
||||
@ -427,42 +784,49 @@ CreateDatabaseConnection(const nsAString& aName,
|
||||
rv = connection->GetSchemaVersion(&schemaVersion);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (schemaVersion != DB_SCHEMA_VERSION) {
|
||||
if (!schemaVersion) {
|
||||
// Brand new file, initialize our tables.
|
||||
mozStorageTransaction transaction(connection, false,
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
rv = CreateTables(connection);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = CreateMetaData(connection, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)) &&
|
||||
schemaVersion == DB_SCHEMA_VERSION,
|
||||
"CreateTables set a bad schema version!");
|
||||
}
|
||||
else if (schemaVersion != DB_SCHEMA_VERSION) {
|
||||
// This logic needs to change next time we change the schema!
|
||||
PR_STATIC_ASSERT(DB_SCHEMA_VERSION == 5);
|
||||
if (schemaVersion == 4) {
|
||||
rv = UpgradeSchemaFrom4To5(connection);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
// Nuke it from orbit, it's the only way to be sure.
|
||||
if (exists) {
|
||||
// If the connection is not at the right schema version, nuke it.
|
||||
rv = aDBFile->Remove(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PR_STATIC_ASSERT(DB_SCHEMA_VERSION == 6);
|
||||
|
||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||
getter_AddRefs(connection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mozStorageTransaction transaction(connection, false,
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
rv = CreateTables(connection);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = CreateMetaData(connection, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = transaction.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
#define UPGRADE_SCHEMA_CASE(_from, _to) \
|
||||
if (schemaVersion == _from) { \
|
||||
rv = UpgradeSchemaFrom##_from##To##_to (connection); \
|
||||
NS_ENSURE_SUCCESS(rv, rv); \
|
||||
\
|
||||
rv = connection->GetSchemaVersion(&schemaVersion); \
|
||||
NS_ENSURE_SUCCESS(rv, rv); \
|
||||
\
|
||||
NS_ASSERTION(schemaVersion == _to, "Bad upgrade function!"); \
|
||||
}
|
||||
|
||||
// Check to make sure that the database schema is correct again.
|
||||
NS_ASSERTION(NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)) &&
|
||||
schemaVersion == DB_SCHEMA_VERSION,
|
||||
"CreateTables failed!");
|
||||
UPGRADE_SCHEMA_CASE(4, 5)
|
||||
UPGRADE_SCHEMA_CASE(5, 6)
|
||||
|
||||
#undef UPGRADE_SCHEMA_CASE
|
||||
|
||||
if (schemaVersion != DB_SCHEMA_VERSION) {
|
||||
NS_WARNING("Unable to open IndexedDB database, schema doesn't match");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
// Turn on foreign key constraints.
|
||||
rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
@ -1143,7 +1507,8 @@ void
|
||||
OpenDatabaseHelper::DispatchSuccessEvent()
|
||||
{
|
||||
nsRefPtr<nsDOMEvent> event =
|
||||
CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR));
|
||||
CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR),
|
||||
eDoesNotBubble, eNotCancelable);
|
||||
if (!event) {
|
||||
NS_ERROR("Failed to create event!");
|
||||
return;
|
||||
@ -1157,7 +1522,8 @@ void
|
||||
OpenDatabaseHelper::DispatchErrorEvent()
|
||||
{
|
||||
nsRefPtr<nsDOMEvent> event =
|
||||
CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR));
|
||||
CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR),
|
||||
eDoesBubble, eCancelable);
|
||||
if (!event) {
|
||||
NS_ERROR("Failed to create event!");
|
||||
return;
|
||||
|
@ -50,7 +50,7 @@ interface nsIDOMEventListener;
|
||||
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
|
||||
* for more information.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(7ad626df-3328-476f-ba10-8ccec4924340)]
|
||||
[scriptable, builtinclass, uuid(bb877dff-ab5b-4ebb-9b3c-a7fa97cd4b51)]
|
||||
interface nsIIDBDatabase : nsISupports
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
@ -83,6 +83,8 @@ interface nsIIDBDatabase : nsISupports
|
||||
void
|
||||
close();
|
||||
|
||||
attribute nsIDOMEventListener onabort;
|
||||
|
||||
attribute nsIDOMEventListener onerror;
|
||||
|
||||
attribute nsIDOMEventListener onversionchange;
|
||||
|
@ -75,9 +75,11 @@ TEST_FILES = \
|
||||
test_exceptions_in_success_events.html \
|
||||
test_getAll.html \
|
||||
test_global_data.html \
|
||||
test_index_empty_keyPath.html \
|
||||
test_index_getAll.html \
|
||||
test_index_getAllObjects.html \
|
||||
test_index_object_cursors.html \
|
||||
test_index_update_delete.html \
|
||||
test_indexes.html \
|
||||
test_indexes_bad_values.html \
|
||||
test_key_requirements.html \
|
||||
@ -108,6 +110,7 @@ TEST_FILES = \
|
||||
test_setVersion_abort.html \
|
||||
test_setVersion_events.html \
|
||||
test_setVersion_exclusion.html \
|
||||
test_unique_index_update.html \
|
||||
test_writer_starvation.html \
|
||||
third_party_iframe1.html \
|
||||
third_party_iframe2.html \
|
||||
|
95
dom/indexedDB/test/test_index_empty_keyPath.html
Normal file
95
dom/indexedDB/test/test_index_empty_keyPath.html
Normal file
@ -0,0 +1,95 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
function testSteps()
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "1", value: "foo" },
|
||||
{ key: "2", value: "bar" },
|
||||
{ key: "3", value: "baz" }
|
||||
];
|
||||
|
||||
let request = mozIndexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield; // upgradeneeded
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore("data", { keyPath: null });
|
||||
|
||||
// First, add all our data to the object store.
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
event = yield; // testGenerator.send
|
||||
|
||||
// Now create the index.
|
||||
objectStore.createIndex("set", "", { unique: true });
|
||||
yield; // success
|
||||
|
||||
let trans = db.transaction("data", IDBTransaction.READ_WRITE);
|
||||
objectStore = trans.objectStore("data");
|
||||
index = objectStore.index("set");
|
||||
|
||||
let request = index.get("bar");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield;
|
||||
|
||||
is(event.target.result, "bar", "Got correct result");
|
||||
|
||||
let request = objectStore.add("foopy", 4);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
yield;
|
||||
|
||||
let request = index.get("foopy");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield;
|
||||
|
||||
is(event.target.result, "foopy", "Got correct result");
|
||||
|
||||
let request = objectStore.add("foopy", 5);
|
||||
request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
trans.oncomplete = grabEventAndContinueHandler;
|
||||
|
||||
yield;
|
||||
yield;
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
180
dom/indexedDB/test/test_index_update_delete.html
Normal file
180
dom/indexedDB/test/test_index_update_delete.html
Normal file
@ -0,0 +1,180 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
function testSteps()
|
||||
{
|
||||
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
for each (let autoIncrement in [false, true]) {
|
||||
let objectStore =
|
||||
db.createObjectStore(autoIncrement, { keyPath: "id",
|
||||
autoIncrement: autoIncrement });
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
objectStore.add({ id: i, index: i });
|
||||
}
|
||||
|
||||
for each (let unique in [false, true]) {
|
||||
objectStore.createIndex(unique, "index", { unique: unique });
|
||||
}
|
||||
|
||||
for (let i = 10; i < 20; i++) {
|
||||
objectStore.add({ id: i, index: i });
|
||||
}
|
||||
}
|
||||
|
||||
event = yield;
|
||||
is(event.type, "success", "expect a success event");
|
||||
|
||||
for each (let autoIncrement in [false, true]) {
|
||||
let objectStore = db.transaction(autoIncrement)
|
||||
.objectStore(autoIncrement);
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
||||
is(event.target.result, 20, "Correct number of entries in objectStore");
|
||||
|
||||
let objectStoreCount = event.target.result;
|
||||
let indexCount = event.target.result;
|
||||
|
||||
for each (let unique in [false, true]) {
|
||||
let index = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
|
||||
.objectStore(autoIncrement)
|
||||
.index(unique);
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
|
||||
let modifiedEntry = unique ? 5 : 10;
|
||||
let keyRange = IDBKeyRange.only(modifiedEntry);
|
||||
|
||||
let sawEntry = false;
|
||||
index.openCursor(keyRange).onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
sawEntry = true;
|
||||
is(cursor.key, modifiedEntry, "Correct key");
|
||||
|
||||
cursor.value.index = unique ? 30 : 35;
|
||||
cursor.update(cursor.value).onsuccess = function(event) {
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(sawEntry, true, "Saw entry for key value " + modifiedEntry);
|
||||
|
||||
// Recount index. Shouldn't change.
|
||||
index = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
|
||||
.objectStore(autoIncrement)
|
||||
.index(unique);
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
|
||||
modifiedEntry = unique ? 30 : 35;
|
||||
keyRange = IDBKeyRange.only(modifiedEntry);
|
||||
|
||||
sawEntry = false;
|
||||
index.openCursor(keyRange).onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
sawEntry = true;
|
||||
is(cursor.key, modifiedEntry, "Correct key");
|
||||
|
||||
delete cursor.value.index;
|
||||
cursor.update(cursor.value).onsuccess = function(event) {
|
||||
indexCount--;
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
}
|
||||
yield;
|
||||
|
||||
is(sawEntry, true, "Saw entry for key value " + modifiedEntry);
|
||||
|
||||
// Recount objectStore. Should be unchanged.
|
||||
objectStore = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
|
||||
.objectStore(autoIncrement);
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
is(event.target.result, objectStoreCount,
|
||||
"Correct number of entries in objectStore");
|
||||
|
||||
// Recount index. Should be one item less.
|
||||
index = objectStore.index(unique);
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
|
||||
modifiedEntry = objectStoreCount - 1;
|
||||
|
||||
objectStore.delete(modifiedEntry).onsuccess =
|
||||
grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
objectStoreCount--;
|
||||
indexCount--;
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
is(event.target.result, objectStoreCount,
|
||||
"Correct number of entries in objectStore");
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
}
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
||||
|
||||
</script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
@ -10,6 +10,10 @@
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
var abortFired = false;
|
||||
|
||||
function abortListener() { abortFired = true; }
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const Ci = Components.interfaces;
|
||||
@ -33,6 +37,7 @@
|
||||
let event = yield;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onabort = abortListener;
|
||||
|
||||
let transaction;
|
||||
let objectStore;
|
||||
@ -398,6 +403,8 @@
|
||||
is(event.type, "abort", "transaction should fail");
|
||||
is(event.target, transaction, "transaction should fail");
|
||||
|
||||
ok(abortFired, "Abort should have fired!");
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
||||
|
79
dom/indexedDB/test/test_unique_index_update.html
Normal file
79
dom/indexedDB/test/test_unique_index_update.html
Normal file
@ -0,0 +1,79 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
function testSteps()
|
||||
{
|
||||
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
for each (let autoIncrement in [false, true]) {
|
||||
let objectStore =
|
||||
db.createObjectStore(autoIncrement, { keyPath: "id",
|
||||
autoIncrement: autoIncrement });
|
||||
objectStore.createIndex("", "index", { unique: true });
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
objectStore.add({ id: i, index: i });
|
||||
}
|
||||
}
|
||||
|
||||
event = yield;
|
||||
is(event.type, "success", "expect a success event");
|
||||
|
||||
for each (let autoIncrement in [false, true]) {
|
||||
objectStore = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
|
||||
.objectStore(autoIncrement);
|
||||
|
||||
request = objectStore.put({ id: 5, index: 6 });
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
|
||||
event = yield;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
let keyRange = IDBKeyRange.only(5);
|
||||
|
||||
objectStore.index("").openCursor(keyRange).onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
ok(cursor, "Must have a cursor here");
|
||||
|
||||
is(cursor.value.index, 5, "Still have the right index value");
|
||||
|
||||
cursor.value.index = 6;
|
||||
|
||||
request = cursor.update(cursor.value);
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
request.onerror =
|
||||
new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
|
||||
};
|
||||
|
||||
yield;
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
||||
|
||||
</script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
@ -51,7 +51,7 @@
|
||||
* http://www.w3.org/TR/DOM-Level-2-Style
|
||||
*/
|
||||
|
||||
[builtinclass, scriptable, uuid(519ae4fa-0fee-4aaa-bcb9-34b503236801)]
|
||||
[builtinclass, scriptable, uuid(0a6fc4c6-a62a-4f52-9ab6-3d398b958843)]
|
||||
interface nsIDOMCSS2Properties : nsISupports
|
||||
{
|
||||
attribute DOMString background;
|
||||
@ -764,4 +764,7 @@ interface nsIDOMCSS2Properties : nsISupports
|
||||
|
||||
attribute DOMString MozAnimation;
|
||||
// raises(DOMException) on setting
|
||||
|
||||
attribute DOMString MozTextSizeAdjust;
|
||||
// raises(DOMException) on setting
|
||||
};
|
||||
|
@ -654,9 +654,6 @@ nsresult nsPluginHost::GetURLWithHeaders(nsNPAPIPluginInstance* pluginInst,
|
||||
PRUint32 getHeadersLength,
|
||||
const char* getHeaders)
|
||||
{
|
||||
nsAutoString string;
|
||||
string.AssignWithConversion(url);
|
||||
|
||||
// we can only send a stream back to the plugin (as specified by a
|
||||
// null target) if we also have a nsIPluginStreamListener to talk to
|
||||
if (!target && !streamListener)
|
||||
@ -681,7 +678,8 @@ nsresult nsPluginHost::GetURLWithHeaders(nsNPAPIPluginInstance* pluginInst,
|
||||
}
|
||||
|
||||
if (streamListener)
|
||||
rv = NewPluginURLStream(string, pluginInst, streamListener, nsnull,
|
||||
rv = NewPluginURLStream(NS_ConvertUTF8toUTF16(url), pluginInst,
|
||||
streamListener, nsnull,
|
||||
getHeaders, getHeadersLength);
|
||||
|
||||
return rv;
|
||||
@ -700,11 +698,8 @@ nsresult nsPluginHost::PostURL(nsISupports* pluginInst,
|
||||
PRUint32 postHeadersLength,
|
||||
const char* postHeaders)
|
||||
{
|
||||
nsAutoString string;
|
||||
nsresult rv;
|
||||
|
||||
string.AssignWithConversion(url);
|
||||
|
||||
// we can only send a stream back to the plugin (as specified
|
||||
// by a null target) if we also have a nsIPluginStreamListener
|
||||
// to talk to also
|
||||
@ -775,7 +770,8 @@ nsresult nsPluginHost::PostURL(nsISupports* pluginInst,
|
||||
// if we don't have a target, just create a stream. This does
|
||||
// NS_OpenURI()!
|
||||
if (streamListener)
|
||||
rv = NewPluginURLStream(string, instance, streamListener,
|
||||
rv = NewPluginURLStream(NS_ConvertUTF8toUTF16(url), instance,
|
||||
streamListener,
|
||||
postStream, postHeaders, postHeadersLength);
|
||||
|
||||
return rv;
|
||||
|
@ -150,7 +150,6 @@ enum {
|
||||
PREF_strict = 0,
|
||||
PREF_werror,
|
||||
PREF_relimit,
|
||||
PREF_tracejit,
|
||||
PREF_methodjit,
|
||||
PREF_jitprofiling,
|
||||
PREF_methodjit_always,
|
||||
@ -168,7 +167,6 @@ const char* gPrefsToWatch[] = {
|
||||
JS_OPTIONS_DOT_STR "strict",
|
||||
JS_OPTIONS_DOT_STR "werror",
|
||||
JS_OPTIONS_DOT_STR "relimit",
|
||||
JS_OPTIONS_DOT_STR "tracejit.content",
|
||||
JS_OPTIONS_DOT_STR "methodjit.content",
|
||||
JS_OPTIONS_DOT_STR "jitprofiling.content",
|
||||
JS_OPTIONS_DOT_STR "methodjit_always"
|
||||
@ -201,9 +199,6 @@ PrefCallback(const char* aPrefName, void* aClosure)
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_relimit])) {
|
||||
newOptions |= JSOPTION_RELIMIT;
|
||||
}
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_tracejit])) {
|
||||
newOptions |= JSOPTION_JIT;
|
||||
}
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_methodjit])) {
|
||||
newOptions |= JSOPTION_METHODJIT;
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ abstract public class GeckoApp
|
||||
public Handler mMainHandler;
|
||||
private IntentFilter mConnectivityFilter;
|
||||
private BroadcastReceiver mConnectivityReceiver;
|
||||
private IntentFilter mBatteryFilter;
|
||||
private BroadcastReceiver mBatteryReceiver;
|
||||
|
||||
enum LaunchState {PreLaunch, Launching, WaitForDebugger,
|
||||
@ -409,9 +408,10 @@ abstract public class GeckoApp
|
||||
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
mConnectivityReceiver = new GeckoConnectivityReceiver();
|
||||
|
||||
mBatteryFilter = new IntentFilter();
|
||||
mBatteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
IntentFilter batteryFilter = new IntentFilter();
|
||||
batteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
mBatteryReceiver = new GeckoBatteryManager();
|
||||
registerReceiver(mBatteryReceiver, batteryFilter);
|
||||
|
||||
if (!checkAndSetLaunchState(LaunchState.PreLaunch,
|
||||
LaunchState.Launching))
|
||||
@ -505,7 +505,6 @@ abstract public class GeckoApp
|
||||
super.onPause();
|
||||
|
||||
unregisterReceiver(mConnectivityReceiver);
|
||||
unregisterReceiver(mBatteryReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -524,7 +523,6 @@ abstract public class GeckoApp
|
||||
onNewIntent(getIntent());
|
||||
|
||||
registerReceiver(mConnectivityReceiver, mConnectivityFilter);
|
||||
registerReceiver(mBatteryReceiver, mBatteryFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -573,6 +571,8 @@ abstract public class GeckoApp
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_SHUTDOWN));
|
||||
|
||||
super.onDestroy();
|
||||
|
||||
unregisterReceiver(mBatteryReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -618,10 +618,6 @@ abstract public class GeckoApp
|
||||
// This file may not be there, so just log any errors and move on
|
||||
Log.w(LOG_FILE_NAME, "error removing files", ex);
|
||||
}
|
||||
unpackFile(zip, buf, null, "application.ini");
|
||||
try {
|
||||
unpackFile(zip, buf, null, "update.locale");
|
||||
} catch (Exception e) {/* this is non-fatal */}
|
||||
|
||||
// copy any .xpi file into an extensions/ directory
|
||||
Enumeration<? extends ZipEntry> zipEntries = zip.entries();
|
||||
|
@ -185,16 +185,13 @@ endif # GNU_CC
|
||||
|
||||
# special rule for pixman-mmx to get the right cflags
|
||||
pixman-mmx.$(OBJ_SUFFIX): pixman-mmx.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(MMX_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
pixman-sse2.$(OBJ_SUFFIX): pixman-sse2.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE2_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
pixman-arm-neon.$(OBJ_SUFFIX): pixman-arm-neon.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(ARM_NEON_CFLAGS) $(_VPATH_SRCS)
|
||||
|
@ -621,21 +621,21 @@ struct PairPosFormat1
|
||||
inline bool apply (hb_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY ();
|
||||
unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
|
||||
if (unlikely (c->buffer->i + 2 > end))
|
||||
unsigned int j = c->buffer->i;
|
||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
||||
if (unlikely (j >= end))
|
||||
return false;
|
||||
|
||||
unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoint);
|
||||
unsigned int index = (this+coverage) (c->buffer->info[j].codepoint);
|
||||
if (likely (index == NOT_COVERED))
|
||||
return false;
|
||||
|
||||
unsigned int j = c->buffer->i + 1;
|
||||
while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
|
||||
do
|
||||
{
|
||||
if (unlikely (j == end))
|
||||
return false;
|
||||
j++;
|
||||
}
|
||||
if (unlikely (j == end))
|
||||
return false;
|
||||
} while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL));
|
||||
|
||||
return (this+pairSet[index]).apply (c, &valueFormat1, j);
|
||||
}
|
||||
@ -683,21 +683,21 @@ struct PairPosFormat2
|
||||
inline bool apply (hb_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY ();
|
||||
unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
|
||||
if (unlikely (c->buffer->i + 2 > end))
|
||||
unsigned int j = c->buffer->i;
|
||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
||||
if (unlikely (j >= end))
|
||||
return false;
|
||||
|
||||
unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoint);
|
||||
unsigned int index = (this+coverage) (c->buffer->info[j].codepoint);
|
||||
if (likely (index == NOT_COVERED))
|
||||
return false;
|
||||
|
||||
unsigned int j = c->buffer->i + 1;
|
||||
while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
|
||||
do
|
||||
{
|
||||
j++;
|
||||
if (unlikely (j == end))
|
||||
return false;
|
||||
j++;
|
||||
}
|
||||
} while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL));
|
||||
|
||||
unsigned int len1 = valueFormat1.get_len ();
|
||||
unsigned int len2 = valueFormat2.get_len ();
|
||||
@ -836,21 +836,21 @@ struct CursivePosFormat1
|
||||
if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
|
||||
return false;
|
||||
|
||||
unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
|
||||
if (unlikely (c->buffer->i + 2 > end))
|
||||
unsigned int j = c->buffer->i;
|
||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
||||
if (unlikely (j >= end))
|
||||
return false;
|
||||
|
||||
const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->info[c->buffer->i].codepoint)];
|
||||
const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)];
|
||||
if (!this_record.exitAnchor)
|
||||
return false;
|
||||
|
||||
unsigned int j = c->buffer->i + 1;
|
||||
while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
|
||||
do
|
||||
{
|
||||
j++;
|
||||
if (unlikely (j == end))
|
||||
return false;
|
||||
j++;
|
||||
}
|
||||
} while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL));
|
||||
|
||||
const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)];
|
||||
if (!next_record.entryAnchor)
|
||||
|
@ -342,24 +342,25 @@ struct Ligature
|
||||
inline bool apply (hb_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY ();
|
||||
unsigned int i, j;
|
||||
unsigned int i;
|
||||
unsigned int j = c->buffer->i;
|
||||
unsigned int count = component.len;
|
||||
unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
|
||||
if (unlikely (c->buffer->i + count > end))
|
||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
||||
if (unlikely (j >= end))
|
||||
return false;
|
||||
|
||||
bool first_was_mark = (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
|
||||
bool found_non_mark = false;
|
||||
|
||||
for (i = 1, j = c->buffer->i + 1; i < count; i++, j++)
|
||||
for (i = 1; i < count; i++)
|
||||
{
|
||||
unsigned int property;
|
||||
while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, &property))
|
||||
do
|
||||
{
|
||||
if (unlikely (j + count - i == end))
|
||||
return false;
|
||||
j++;
|
||||
}
|
||||
if (unlikely (j == end))
|
||||
return false;
|
||||
} while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, &property));
|
||||
|
||||
found_non_mark |= !(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
|
||||
|
||||
|
@ -126,25 +126,26 @@ static inline bool match_input (hb_apply_context_t *c,
|
||||
const void *match_data,
|
||||
unsigned int *context_length_out)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
|
||||
if (unlikely (c->buffer->i + count > end))
|
||||
unsigned int i;
|
||||
unsigned int j = c->buffer->i;
|
||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
||||
if (unlikely (j + count > end))
|
||||
return false;
|
||||
|
||||
for (i = 1, j = c->buffer->i + 1; i < count; i++, j++)
|
||||
for (i = 1; i < count; i++)
|
||||
{
|
||||
while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
|
||||
do
|
||||
{
|
||||
if (unlikely (j + count - i == end))
|
||||
return false;
|
||||
j++;
|
||||
}
|
||||
if (unlikely (j >= end))
|
||||
return false;
|
||||
} while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL));
|
||||
|
||||
if (likely (!match_func (c->buffer->info[j].codepoint, input[i - 1], match_data)))
|
||||
return false;
|
||||
}
|
||||
|
||||
*context_length_out = j - c->buffer->i;
|
||||
*context_length_out = j - c->buffer->i + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -155,17 +156,16 @@ static inline bool match_backtrack (hb_apply_context_t *c,
|
||||
match_func_t match_func,
|
||||
const void *match_data)
|
||||
{
|
||||
if (unlikely (c->buffer->backtrack_len () < count))
|
||||
return false;
|
||||
unsigned int j = c->buffer->backtrack_len ();
|
||||
|
||||
for (unsigned int i = 0, j = c->buffer->backtrack_len () - 1; i < count; i++, j--)
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->out_info[j], c->lookup_props, NULL))
|
||||
do
|
||||
{
|
||||
if (unlikely (j + 1 == count - i))
|
||||
if (unlikely (!j))
|
||||
return false;
|
||||
j--;
|
||||
}
|
||||
} while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->out_info[j], c->lookup_props, NULL));
|
||||
|
||||
if (likely (!match_func (c->buffer->out_info[j].codepoint, backtrack[i], match_data)))
|
||||
return false;
|
||||
@ -181,19 +181,18 @@ static inline bool match_lookahead (hb_apply_context_t *c,
|
||||
const void *match_data,
|
||||
unsigned int offset)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int i;
|
||||
unsigned int j = c->buffer->i + offset - 1;
|
||||
unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
|
||||
if (unlikely (c->buffer->i + offset + count > end))
|
||||
return false;
|
||||
|
||||
for (i = 0, j = c->buffer->i + offset; i < count; i++, j++)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
|
||||
do
|
||||
{
|
||||
if (unlikely (j + count - i == end))
|
||||
return false;
|
||||
j++;
|
||||
}
|
||||
if (unlikely (j >= end))
|
||||
return false;
|
||||
} while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL));
|
||||
|
||||
if (likely (!match_func (c->buffer->info[j].codepoint, lookahead[i], match_data)))
|
||||
return false;
|
||||
|
@ -36,6 +36,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "gfxSharedImageSurface.h"
|
||||
|
||||
#include "mozilla/layers/PLayerChild.h"
|
||||
@ -43,8 +45,6 @@
|
||||
#include "mozilla/layers/PLayersParent.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
#include "ipc/ShadowLayerChild.h"
|
||||
|
||||
#include "BasicLayers.h"
|
||||
|
@ -68,11 +68,9 @@ endif # GNU_CC
|
||||
|
||||
# special rules for transform-sse*.c to get the right cflags. (taken from pixman/src/Makefile.in)
|
||||
transform-sse1.$(OBJ_SUFFIX): transform-sse1.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE1_FLAGS) $(_VPATH_SRCS)
|
||||
|
||||
transform-sse2.$(OBJ_SUFFIX): transform-sse2.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE2_FLAGS) $(_VPATH_SRCS)
|
||||
|
@ -66,7 +66,7 @@ CPPSRCS = \
|
||||
SandboxHal.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq (Android,$(OS_TARGET))
|
||||
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += AndroidHal.cpp
|
||||
else ifeq (Linux,$(OS_TARGET))
|
||||
CPPSRCS += LinuxHal.cpp
|
||||
|
@ -384,8 +384,6 @@ UPowerClient::UpdateSavedInfo(GHashTable* aHashTable)
|
||||
{
|
||||
bool isFull = false;
|
||||
|
||||
mLevel = g_value_get_double(static_cast<const GValue*>(g_hash_table_lookup(aHashTable, "Percentage")))*0.01;
|
||||
|
||||
/*
|
||||
* State values are confusing...
|
||||
* First of all, after looking at upower sources (0.9.13), it seems that
|
||||
@ -420,6 +418,17 @@ UPowerClient::UpdateSavedInfo(GHashTable* aHashTable)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The battery level might be very close to 100% (like 99.xxxx%) without
|
||||
* increasing. It seems that upower sets the battery state as 'full' in that
|
||||
* case so we should trust it and not even try to get the value.
|
||||
*/
|
||||
if (isFull) {
|
||||
mLevel = 1.0;
|
||||
} else {
|
||||
mLevel = g_value_get_double(static_cast<const GValue*>(g_hash_table_lookup(aHashTable, "Percentage")))*0.01;
|
||||
}
|
||||
|
||||
if (isFull) {
|
||||
mRemainingTime = 0;
|
||||
} else {
|
||||
|
@ -41,6 +41,8 @@
|
||||
#ifndef mozilla_ipc_Shmem_h
|
||||
#define mozilla_ipc_Shmem_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/process.h"
|
||||
|
||||
@ -87,7 +89,7 @@
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class NS_FINAL_CLASS Shmem
|
||||
class Shmem MOZ_FINAL
|
||||
{
|
||||
friend struct IPC::ParamTraits<mozilla::ipc::Shmem>;
|
||||
|
||||
|
@ -92,6 +92,7 @@ Types = (
|
||||
|
||||
|
||||
Includes = (
|
||||
'mozilla/Attributes.h',
|
||||
'base/basictypes.h',
|
||||
'prtime.h',
|
||||
'nscore.h',
|
||||
|
@ -161,9 +161,9 @@ class CxxCodeGen(CodePrinter, Visitor):
|
||||
if c.abstract:
|
||||
# FIXME/cjones: turn this "on" when we get the analysis
|
||||
self.write(' /*NS_ABSTRACT_CLASS*/')
|
||||
if c.final:
|
||||
self.write(' NS_FINAL_CLASS')
|
||||
self.write(' '+ c.name)
|
||||
if c.final:
|
||||
self.write(' MOZ_FINAL')
|
||||
|
||||
if c.specializes is not None:
|
||||
self.write(' <')
|
||||
|
@ -220,7 +220,6 @@ INSTALLED_HEADERS = \
|
||||
jsreflect.h \
|
||||
jsstdint.h \
|
||||
jsstr.h \
|
||||
jstracer.h \
|
||||
jstypedarray.h \
|
||||
jstypes.h \
|
||||
jsutil.h \
|
||||
@ -283,6 +282,7 @@ VPATH += \
|
||||
EXPORTS_NAMESPACES += mozilla
|
||||
|
||||
EXPORTS_mozilla = \
|
||||
Attributes.h \
|
||||
GuardObjects.h \
|
||||
RangedPtr.h \
|
||||
RefPtr.h \
|
||||
@ -290,53 +290,6 @@ EXPORTS_mozilla = \
|
||||
Util.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TRACEJIT
|
||||
VPATH += \
|
||||
$(srcdir)/tracejit \
|
||||
$(srcdir)/nanojit \
|
||||
|
||||
INSTALLED_HEADERS += \
|
||||
jsbuiltins.h \
|
||||
Assembler.h \
|
||||
Allocator.h \
|
||||
CodeAlloc.h \
|
||||
Containers.h \
|
||||
LIR.h \
|
||||
LIRopcode.tbl \
|
||||
avmplus.h \
|
||||
Fragmento.h \
|
||||
Native.h \
|
||||
NativeCommon.h \
|
||||
Native$(NANOJIT_ARCH).h \
|
||||
njconfig.h \
|
||||
njcpudetect.h \
|
||||
RegAlloc.h \
|
||||
nanojit.h \
|
||||
VMPI.h \
|
||||
Writer.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS += \
|
||||
jstracer.cpp \
|
||||
Assembler.cpp \
|
||||
Allocator.cpp \
|
||||
CodeAlloc.cpp \
|
||||
Containers.cpp \
|
||||
Fragmento.cpp \
|
||||
LIR.cpp \
|
||||
njconfig.cpp \
|
||||
avmplus.cpp \
|
||||
Native$(NANOJIT_ARCH).cpp \
|
||||
jsbuiltins.cpp \
|
||||
VMPI.cpp \
|
||||
Writer.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_DEBUG
|
||||
CPPSRCS += RegAlloc.cpp
|
||||
endif
|
||||
|
||||
endif # ENABLE_TRACEJIT
|
||||
ifdef ENABLE_METHODJIT
|
||||
|
||||
###############################################
|
||||
@ -691,7 +644,7 @@ ifneq ($(OS_ARCH),WINNT) # FIXME: this should be made work on Windows too.
|
||||
#check:: check-malloc-function-usage FIXME: disable on JM until closer to merge time.
|
||||
endif
|
||||
|
||||
JITFLAGS = ,m,j,mj,mjp,am,amj,amjp,amd,n,mn,jn,mjn,mjpn,amn,amjn,amjpn,amdn
|
||||
JITFLAGS = ,m,am,amd,n,mn,amn,amdn,mdn
|
||||
check-jit-test::
|
||||
$(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/jit-test/jit_test.py \
|
||||
--valgrind --no-slow --no-progress --tinderbox --jitflags=$(JITFLAGS) $(DIST)/bin/js$(BIN_SUFFIX)
|
||||
@ -729,9 +682,6 @@ check-jstests:
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
ifdef ENABLE_METHODJIT
|
||||
ifdef ENABLE_TRACEJIT
|
||||
#check:: check-jstests
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifndef HAVE_DTRACE
|
||||
@ -851,7 +801,6 @@ ifdef SOLARIS_SUNPRO_CXX
|
||||
ifeq ($(TARGET_CPU),sparc)
|
||||
# Sun Studio SPARC doesn't work well with gcc inline asm, use lock_SunOS_sparc*.il
|
||||
jslock.o: jslock.cpp Makefile.in lock_sparcv8plus.il lock_sparcv9.il
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
ifeq (sparcv9,$(findstring sparcv9,$(OS_TEST)))
|
||||
$(CXX) -o $@ -c $(COMPILE_CFLAGS) $(srcdir)/lock_sparcv9.il $<
|
||||
@ -865,11 +814,9 @@ endif # SOLARIS_SUNPRO_CXX
|
||||
# This suppresses optimization for this single compilation unit.
|
||||
ifeq ($(OS_ARCH),AIX)
|
||||
jsatom.o: jsatom.cpp Makefile.in
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(CXX) -o $@ -c $(filter-out $(MOZ_OPTIMIZE_FLAGS), $(COMPILE_CFLAGS)) $<
|
||||
jsdtoa.o: jsdtoa.cpp Makefile.in
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(CXX) -o $@ -c $(filter-out $(MOZ_OPTIMIZE_FLAGS), $(COMPILE_CFLAGS)) $<
|
||||
endif
|
||||
@ -975,41 +922,6 @@ $(CURDIR)/javascript-trace.h: $(srcdir)/javascript-trace.d
|
||||
$(addsuffix .$(OBJ_SUFFIX),jsprobes jsinterp jsobj): $(CURDIR)/javascript-trace.h
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TRACEJIT
|
||||
# Imacro compilation.
|
||||
$(CURDIR)/imacros.c.out: $(srcdir)/imacro_asm.py $(srcdir)/imacros.jsasm jsopcode.tbl
|
||||
$(PYTHON) $< $(srcdir)/imacros.jsasm $(CURDIR)/imacros.c.out
|
||||
$(addsuffix .$(OBJ_SUFFIX),jstracer): $(CURDIR)/imacros.c.out
|
||||
|
||||
# Code for importing the nanojit subtree from its repository.
|
||||
NANOJIT_CENTRAL_REV=$(shell cat $(srcdir)/nanojit-import-rev)
|
||||
NANOJIT_CENTRAL_REPO=http://hg.mozilla.org/projects/nanojit-central
|
||||
NANOJIT_CENTRAL_LOCAL=$(CURDIR)/nanojit-central
|
||||
CUR_REPO=$(srcdir)/../..
|
||||
|
||||
update-nanojit:
|
||||
$(RM) -r $(NANOJIT_CENTRAL_LOCAL) import-splicemap import-revmap
|
||||
hg clone $(NANOJIT_CENTRAL_REPO) $(NANOJIT_CENTRAL_LOCAL)
|
||||
python $(srcdir)/find-child.py \
|
||||
--src=$(NANOJIT_CENTRAL_LOCAL) \
|
||||
--dst=$(CUR_REPO) \
|
||||
--start=$(NANOJIT_CENTRAL_REV) \
|
||||
--filemap=$(srcdir)/nanojit-import-filemap \
|
||||
>import-splicemap
|
||||
hg convert --config convert.hg.saverev=True \
|
||||
--config convert.hg.startrev=`cut -d ' ' -f 1 import-splicemap` \
|
||||
--filemap=$(srcdir)/nanojit-import-filemap \
|
||||
--splicemap=import-splicemap \
|
||||
$(NANOJIT_CENTRAL_LOCAL) \
|
||||
$(CUR_REPO) \
|
||||
import-revmap
|
||||
(cd $(srcdir) && hg up)
|
||||
(cd $(NANOJIT_CENTRAL_LOCAL) && hg log -r tip --template "{node}\n") >$(srcdir)/nanojit-import-rev
|
||||
(cd $(srcdir) && hg commit --message="Update nanojit-import-rev stamp." nanojit-import-rev)
|
||||
|
||||
.PHONY: update-nanojit
|
||||
endif
|
||||
|
||||
###############################################
|
||||
# BEGIN kludges for the Nitro assembler
|
||||
#
|
||||
@ -1019,7 +931,7 @@ endif
|
||||
# the code in js/src/assembler.
|
||||
CXXFLAGS += -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1
|
||||
|
||||
ifneq (,$(ENABLE_YARR_JIT)$(ENABLE_TRACEJIT)$(ENABLE_METHODJIT))
|
||||
ifneq (,$(ENABLE_YARR_JIT)$(ENABLE_METHODJIT))
|
||||
CXXFLAGS += -DENABLE_JIT=1
|
||||
endif
|
||||
|
||||
|
@ -331,9 +331,7 @@ HAVE_DTRACE= @HAVE_DTRACE@
|
||||
VISIBILITY_FLAGS = @VISIBILITY_FLAGS@
|
||||
WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@
|
||||
|
||||
ENABLE_TRACEJIT = @ENABLE_TRACEJIT@
|
||||
ENABLE_METHODJIT = @ENABLE_METHODJIT@
|
||||
NANOJIT_ARCH = @NANOJIT_ARCH@
|
||||
HAVE_ARM_SIMD= @HAVE_ARM_SIMD@
|
||||
|
||||
JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
|
||||
|
@ -64,8 +64,6 @@ ifdef SDK_HEADERS
|
||||
EXPORTS += $(SDK_HEADERS)
|
||||
endif
|
||||
|
||||
REPORT_BUILD = @echo $(notdir $<)
|
||||
|
||||
ifeq ($(OS_ARCH),OS2)
|
||||
EXEC =
|
||||
else
|
||||
@ -1150,32 +1148,25 @@ endif # MOZ_AUTO_DEPS
|
||||
|
||||
# Rules for building native targets must come first because of the host_ prefix
|
||||
host_%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
%:: %.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
|
||||
|
||||
%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
@ -1186,7 +1177,6 @@ moc_%.cpp: %.h $(GLOBAL_DEPS)
|
||||
$(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
|
||||
|
||||
moc_%.cc: %.cc $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
|
||||
|
||||
ifdef ASFILES
|
||||
@ -1207,12 +1197,10 @@ endif
|
||||
# Please keep the next two rules in sync.
|
||||
#
|
||||
%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||
echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > t_$*.cc
|
||||
@ -1223,12 +1211,10 @@ else
|
||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||
|
||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
@ -1478,7 +1464,6 @@ XPIDL_DEPS = \
|
||||
$(NULL)
|
||||
|
||||
$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
|
||||
$(REPORT_BUILD)
|
||||
$(PYTHON_PATH) \
|
||||
-I$(topsrcdir)/other-licenses/ply \
|
||||
-I$(topsrcdir)/xpcom/idl-parser \
|
||||
@ -1490,7 +1475,6 @@ ifndef NO_GEN_XPT
|
||||
# generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
|
||||
# into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
|
||||
$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
|
||||
$(REPORT_BUILD)
|
||||
$(PYTHON_PATH) \
|
||||
-I$(topsrcdir)/other-licenses/ply \
|
||||
-I$(topsrcdir)/xpcom/idl-parser \
|
||||
@ -1779,15 +1763,12 @@ define MAKE_DEPS_NOAUTO
|
||||
endef
|
||||
|
||||
$(MDDEPDIR)/%.pp: %.c
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_NOAUTO)
|
||||
|
||||
$(MDDEPDIR)/%.pp: %.cpp
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_NOAUTO)
|
||||
|
||||
$(MDDEPDIR)/%.pp: %.s
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_NOAUTO)
|
||||
|
||||
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
|
||||
|
@ -2790,7 +2790,6 @@ dnl Configure JIT support
|
||||
|
||||
case "$target" in
|
||||
i?86-*)
|
||||
NANOJIT_ARCH=i386
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
@ -2799,7 +2798,6 @@ i?86-*)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
x86_64*-*)
|
||||
NANOJIT_ARCH=X64
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
@ -2808,7 +2806,6 @@ x86_64*-*)
|
||||
AC_DEFINE(JS_PUNBOX64)
|
||||
;;
|
||||
arm*-*)
|
||||
NANOJIT_ARCH=ARM
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
@ -2817,7 +2814,6 @@ arm*-*)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
sparc*-*)
|
||||
NANOJIT_ARCH=Sparc
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
@ -2840,8 +2836,8 @@ MOZ_ARG_DISABLE_BOOL(polyic,
|
||||
ENABLE_POLYIC= )
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(tracejit,
|
||||
[ --enable-tracejit Enable tracing JIT support],
|
||||
ENABLE_TRACEJIT=1,
|
||||
[ --enable-tracejit Deprecated, does nothing],
|
||||
ENABLE_TRACEJIT=,
|
||||
ENABLE_TRACEJIT= )
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(methodjit-spew,
|
||||
@ -2871,62 +2867,6 @@ if test "$ENABLE_METHODJIT_SPEW"; then
|
||||
AC_DEFINE(JS_METHODJIT_SPEW)
|
||||
fi
|
||||
|
||||
if test "$ENABLE_TRACEJIT"; then
|
||||
|
||||
AC_DEFINE(FEATURE_NANOJIT)
|
||||
AC_DEFINE(JS_TRACER)
|
||||
|
||||
case "$target" in
|
||||
i?86-*)
|
||||
AC_DEFINE(AVMPLUS_IA32)
|
||||
;;
|
||||
x86_64*-*)
|
||||
AC_DEFINE(AVMPLUS_AMD64)
|
||||
AC_DEFINE(AVMPLUS_64BIT)
|
||||
;;
|
||||
arm*-*)
|
||||
AC_DEFINE(AVMPLUS_ARM)
|
||||
;;
|
||||
sparc-*)
|
||||
AC_DEFINE(AVMPLUS_SPARC)
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$target" in
|
||||
*-linux*|*-android*|*-linuxandroid*)
|
||||
AC_DEFINE(AVMPLUS_UNIX)
|
||||
AC_DEFINE(AVMPLUS_LINUX)
|
||||
;;
|
||||
*-darwin*)
|
||||
AC_DEFINE(AVMPLUS_UNIX)
|
||||
;;
|
||||
*-solaris*)
|
||||
AC_DEFINE(AVMPLUS_UNIX)
|
||||
;;
|
||||
*-freebsd*|*-kfreebsd*)
|
||||
AC_DEFINE(AVMPLUS_UNIX)
|
||||
;;
|
||||
*-openbsd*)
|
||||
AC_DEFINE(AVMPLUS_UNIX)
|
||||
;;
|
||||
*-gnu*)
|
||||
AC_DEFINE(AVMPLUS_UNIX)
|
||||
;;
|
||||
*-mingw*)
|
||||
AC_DEFINE(AVMPLUS_WIN32)
|
||||
;;
|
||||
*-os2*)
|
||||
AC_DEFINE(AVMPLUS_OS2)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unrecognized nanojit platform. Use --disable-tracejit to build without tracing JIT support.])
|
||||
esac
|
||||
|
||||
fi # ENABLE_TRACEJIT
|
||||
|
||||
AC_SUBST(ENABLE_TRACEJIT)
|
||||
AC_SUBST(NANOJIT_ARCH)
|
||||
|
||||
if test -z "$SKIP_COMPILER_CHECKS"; then
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
dnl ========================================================
|
||||
@ -4503,20 +4443,6 @@ if test -n "$MOZ_TRACE_JSCALLS"; then
|
||||
AC_DEFINE(MOZ_TRACE_JSCALLS)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Use TraceVis
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(tracevis,
|
||||
[ --enable-tracevis Enable TraceVis tracing tool (default=no)],
|
||||
MOZ_TRACEVIS=1,
|
||||
MOZ_TRACEVIS= )
|
||||
if test -n "$MOZ_TRACEVIS"; then
|
||||
AC_DEFINE(MOZ_TRACEVIS)
|
||||
if test -z "$ENABLE_TRACEJIT"; then
|
||||
AC_MSG_ERROR([--enable-tracevis is incompatible with --disable-tracejit])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Use incremental GC
|
||||
dnl ========================================================
|
||||
|
@ -89,10 +89,6 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
using namespace js::frontend;
|
||||
|
||||
#ifdef JS_TRACER
|
||||
extern uint8 js_opcode2extra[];
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, uintN stackDepth,
|
||||
size_t start, size_t end);
|
||||
@ -204,21 +200,15 @@ UpdateDepth(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t target)
|
||||
jsbytecode *pc;
|
||||
JSOp op;
|
||||
const JSCodeSpec *cs;
|
||||
uintN extra, nuses;
|
||||
uintN nuses;
|
||||
intN ndefs;
|
||||
|
||||
pc = bce->code(target);
|
||||
op = (JSOp) *pc;
|
||||
cs = &js_CodeSpec[op];
|
||||
#ifdef JS_TRACER
|
||||
extra = js_opcode2extra[op];
|
||||
#else
|
||||
extra = 0;
|
||||
#endif
|
||||
if ((cs->format & JOF_TMPSLOT_MASK) || extra) {
|
||||
if ((cs->format & JOF_TMPSLOT_MASK)) {
|
||||
uintN depth = (uintN) bce->stackDepth +
|
||||
((cs->format & JOF_TMPSLOT_MASK) >> JOF_TMPSLOT_SHIFT) +
|
||||
extra;
|
||||
((cs->format & JOF_TMPSLOT_MASK) >> JOF_TMPSLOT_SHIFT);
|
||||
if (depth > bce->maxStackDepth)
|
||||
bce->maxStackDepth = depth;
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ class HeapValue
|
||||
bool toBoolean() const { return value.toBoolean(); }
|
||||
double toNumber() const { return value.toNumber(); }
|
||||
|
||||
unsigned gcKind() const { return value.gcKind(); }
|
||||
JSGCTraceKind gcKind() const { return value.gcKind(); }
|
||||
|
||||
inline void boxNonDoubleFrom(JSValueType type, uint64 *out);
|
||||
|
||||
|
@ -1,467 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil -*-
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the TraceMonkey IMacro Assembler.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Brendan Eich <brendan@mozilla.org>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2008
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# An imacro (interpreter-macro) assembler in Python.
|
||||
#
|
||||
# Filename suffix conventions, used by Makefile.in rules:
|
||||
# .jsasm SpiderMonkey JS assembly source, which could be input to other
|
||||
# assemblers than imacro_asm.js, hence the generic suffix!
|
||||
# .c.out C source output by imacro_asm.js
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
class Op:
|
||||
def __init__(self, jsop, opcode, opname, opsrc, oplen, pops, pushes, precedence, flags):
|
||||
self.jsop = jsop
|
||||
self.opcode = opcode
|
||||
self.opname = opname
|
||||
self.opsrc = opsrc
|
||||
self.oplen = oplen
|
||||
self.pops = pops
|
||||
self.pushes = pushes
|
||||
self.precedence = precedence
|
||||
self.flags = flags
|
||||
|
||||
def readFileLines(filename):
|
||||
f = open(filename)
|
||||
try:
|
||||
return f.readlines()
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def load_ops(filename):
|
||||
opdef_regexp = re.compile(r'''(?x)
|
||||
^ OPDEF \( (JSOP_\w+), \s* # op
|
||||
([0-9]+), \s* # val
|
||||
("[^"]+" | [\w_]+), \s* # name
|
||||
("[^"]+" | [\w_]+), \s* # image
|
||||
(-1|[0-9]+), \s* # len
|
||||
(-1|[0-9]+), \s* # uses
|
||||
(-1|[0-9]+), \s* # defs
|
||||
([0-9]+), \s* # prec
|
||||
([\w_| ]+) \s* # format
|
||||
\) \s* $''')
|
||||
|
||||
def decode_string_expr(expr):
|
||||
if expr == 'NULL':
|
||||
return None
|
||||
if expr[0] == '"':
|
||||
assert expr[-1] == '"'
|
||||
return expr[1:-1]
|
||||
assert expr.startswith('js_') and expr.endswith('_str')
|
||||
return expr[3:-4]
|
||||
|
||||
opinfo = []
|
||||
for lineno, line in enumerate(readFileLines(filename)):
|
||||
if line.startswith('OPDEF'):
|
||||
m = opdef_regexp.match(line)
|
||||
if m is None:
|
||||
raise ValueError("OPDEF line of wrong format in jsopcode.tbl at line %d" % (lineno + 1))
|
||||
jsop, opcode, opname, opsrc, oplen, pops, pushes, precedence, flags = m.groups()
|
||||
assert int(opcode) == len(opinfo)
|
||||
opinfo.append(Op(jsop, int(opcode), decode_string_expr(opname),
|
||||
decode_string_expr(opsrc), int(oplen), int(pops), int(pushes),
|
||||
int(precedence), flags.replace(' ', '').split('|')))
|
||||
return opinfo
|
||||
|
||||
opinfo = load_ops(os.path.join(os.path.dirname(__file__), "jsopcode.tbl"))
|
||||
opname2info = dict((info.opname, info) for info in opinfo)
|
||||
jsop2opcode = dict((info.jsop, info.opcode) for info in opinfo)
|
||||
|
||||
def to_uint8(s):
|
||||
try:
|
||||
n = int(s)
|
||||
except ValueError:
|
||||
n = -1
|
||||
if 0 <= n < (1<<8):
|
||||
return n
|
||||
raise ValueError("invalid 8-bit operand: " + s)
|
||||
|
||||
def to_uint16(s):
|
||||
try:
|
||||
n = int(s)
|
||||
except ValueError:
|
||||
n = -1
|
||||
if 0 <= n < (1<<16):
|
||||
return n
|
||||
raise ValueError("invalid 16-bit operand: " + s)
|
||||
|
||||
def immediate(op):
|
||||
info = op.info
|
||||
imm1Expr = op.imm1.startswith('(')
|
||||
if 'JOF_ATOM' in info.flags:
|
||||
if op.imm1 in ('void', 'object', 'function', 'string', 'number', 'boolean'):
|
||||
return "0, COMMON_TYPE_ATOM_INDEX(JSTYPE_%s)" % op.imm1.upper()
|
||||
return "0, COMMON_ATOM_INDEX(%s)" % op.imm1
|
||||
if 'JOF_JUMP' in info.flags:
|
||||
assert not imm1Expr
|
||||
return "%d, %d" % ((op.target >> 8) & 0xff, op.target & 0xff)
|
||||
if 'JOF_UINT8' in info.flags or 'JOF_INT8' in info.flags:
|
||||
if imm1Expr:
|
||||
return op.imm1
|
||||
return str(to_uint8(op.imm1))
|
||||
if 'JOF_UINT16' in info.flags:
|
||||
if imm1Expr:
|
||||
return '(%s & 0xff00) >> 8, (%s & 0xff)' % (op.imm1, op.imm1)
|
||||
v = to_uint16(op.imm1)
|
||||
return "%d, %d" % ((v & 0xff00) >> 8, v & 0xff)
|
||||
raise NotImplementedError(info.jsop + " format not yet implemented")
|
||||
|
||||
def simulate_cfg(igroup, imacro, depth, i):
|
||||
any_group_opcode = None
|
||||
expected_depth = None
|
||||
for opcode in igroup.ops:
|
||||
opi = opinfo[opcode]
|
||||
if any_group_opcode is None:
|
||||
any_group_opcode = opcode
|
||||
if opi.pops < 0:
|
||||
expected_depth = None
|
||||
else:
|
||||
expected_depth = opi.pushes - opi.pops
|
||||
elif expected_depth is None:
|
||||
if opi.pops >= 0:
|
||||
raise ValueError("imacro shared by constant- and variable-stack-defs/uses instructions")
|
||||
else:
|
||||
if opi.pops < 0:
|
||||
raise ValueError("imacro shared by constant- and variable-stack-defs/uses instructions")
|
||||
if opi.pushes - opi.pops != expected_depth:
|
||||
raise ValueError("imacro shared by instructions with different stack depths")
|
||||
|
||||
for i in range(i, len(imacro.code)):
|
||||
op = imacro.code[i]
|
||||
opi = op.info
|
||||
if opi.opname == 'imacop':
|
||||
opi = opinfo[any_group_opcode]
|
||||
|
||||
if opi.pops < 0:
|
||||
depth -= 2 + int(op.imm1)
|
||||
else:
|
||||
depth -= opi.pops
|
||||
depth += opi.pushes
|
||||
|
||||
if i in imacro.depths and imacro.depths[i] != depth:
|
||||
raise ValueError("Mismatched depth at %s:%d" % (imacro.filename, op.line))
|
||||
|
||||
# Underflowing depth isn't necessarily fatal; most of the imacros
|
||||
# assume they are called with N>0 args so some assume it's ok to go
|
||||
# to some depth <N. We simulate starting from 0, as we've no idea
|
||||
# what else to do.
|
||||
#
|
||||
# if depth < 0:
|
||||
# raise ValueError("Negative static-stack depth at %s:%d" % (imacro.filename, op.line))
|
||||
if depth > imacro.maxdepth:
|
||||
imacro.maxdepth = depth
|
||||
imacro.depths[i] = depth
|
||||
|
||||
if hasattr(op, "target_index"):
|
||||
if op.target_index <= i:
|
||||
raise ValueError("Backward jump at %s:%d" % (imacro.filename, op.line))
|
||||
simulate_cfg(igroup, imacro, depth, op.target_index)
|
||||
if op.info.opname in ('goto', 'gotox'):
|
||||
return
|
||||
|
||||
if expected_depth is not None and depth != expected_depth:
|
||||
raise ValueError("Expected depth %d, got %d" % (expected_depth, depth))
|
||||
|
||||
|
||||
# Syntax (spaces are significant only to delimit tokens):
|
||||
#
|
||||
# Assembly ::= (Directive? '\n')*
|
||||
# Directive ::= (name ':')? Operation
|
||||
# Operation ::= opname Operands?
|
||||
# Operands ::= Operand (',' Operand)*
|
||||
# Operand ::= name | number | '(' Expr ')'
|
||||
# Expr ::= a constant-expression in the C++ language
|
||||
# containing no parentheses
|
||||
#
|
||||
# We simplify given line structure and the maximum of one immediate operand,
|
||||
# by parsing using split and regexps. For ease of parsing, parentheses are
|
||||
# banned in an Expr for now, even in quotes or a C++ comment.
|
||||
#
|
||||
# Pseudo-ops start with . and include .igroup and .imacro, terminated by .end.
|
||||
# .imacro must nest in .igroup, neither nests in itself. See imacros.jsasm for
|
||||
# examples.
|
||||
#
|
||||
line_regexp = re.compile(r'''(?x)
|
||||
^
|
||||
(?: (\w+): )? # optional label at start of line
|
||||
\s* (\.?\w+) # optional spaces, (pseudo-)opcode
|
||||
(?: \s+ ([+-]?\w+ | \([^)]*\)) )? # optional first immediate operand
|
||||
(?: \s+ ([\w,-]+ | \([^)]*\)) )? # optional second immediate operand
|
||||
(?: \s* (?:\#.*) )? # optional spaces and comment
|
||||
$''')
|
||||
|
||||
oprange_regexp = re.compile(r'^\w+(?:-\w+)?(?:,\w+(?:-\w+)?)*$')
|
||||
|
||||
class IGroup(object):
|
||||
def __init__(self, name, ops):
|
||||
self.name = name
|
||||
self.ops = ops
|
||||
self.imacros = []
|
||||
|
||||
class IMacro(object):
|
||||
def __init__(self, name, filename):
|
||||
self.name = name
|
||||
self.offset = 0
|
||||
self.code = []
|
||||
self.labeldefs = {}
|
||||
self.labeldef_indexes = {}
|
||||
self.labelrefs = {}
|
||||
self.filename = filename
|
||||
self.depths = {}
|
||||
self.initdepth = 0
|
||||
|
||||
class Instruction(object):
|
||||
def __init__(self, offset, info, imm1, imm2, lineno):
|
||||
self.offset = offset
|
||||
self.info = info
|
||||
self.imm1 = imm1
|
||||
self.imm2 = imm2
|
||||
self.lineno = lineno
|
||||
|
||||
def assemble(filename, outfile):
|
||||
write = outfile.write
|
||||
igroup = None
|
||||
imacro = None
|
||||
opcode2extra = {}
|
||||
igroups = []
|
||||
|
||||
write("/* GENERATED BY imacro_asm.js -- DO NOT EDIT!!! */\n")
|
||||
|
||||
def fail(msg, *args):
|
||||
raise ValueError("%s at %s:%d" % (msg % args, filename, lineno + 1))
|
||||
|
||||
for lineno, line in enumerate(readFileLines(filename)):
|
||||
# strip comments
|
||||
line = re.sub(r'#.*', '', line).rstrip()
|
||||
if line == "":
|
||||
continue
|
||||
m = line_regexp.match(line)
|
||||
if m is None:
|
||||
fail(line)
|
||||
|
||||
label, opname, imm1, imm2 = m.groups()
|
||||
|
||||
if opname.startswith('.'):
|
||||
if label is not None:
|
||||
fail("invalid label %s before %s" % (label, opname))
|
||||
|
||||
if opname == '.igroup':
|
||||
if imm1 is None:
|
||||
fail("missing .igroup name")
|
||||
if igroup is not None:
|
||||
fail("nested .igroup " + imm1)
|
||||
if oprange_regexp.match(imm2) is None:
|
||||
fail("invalid igroup operator range " + imm2)
|
||||
|
||||
ops = set()
|
||||
for current in imm2.split(","):
|
||||
split = current.split('-')
|
||||
opcode = jsop2opcode[split[0]]
|
||||
if len(split) == 1:
|
||||
lastopcode = opcode
|
||||
else:
|
||||
assert len(split) == 2
|
||||
lastopcode = jsop2opcode[split[1]]
|
||||
if opcode >= lastopcode:
|
||||
fail("invalid opcode range: " + current)
|
||||
|
||||
for opcode in range(opcode, lastopcode + 1):
|
||||
if opcode in ops:
|
||||
fail("repeated opcode " + opinfo[opcode].jsop)
|
||||
ops.add(opcode)
|
||||
|
||||
igroup = IGroup(imm1, ops)
|
||||
|
||||
elif opname == '.imacro':
|
||||
if igroup is None:
|
||||
fail(".imacro outside of .igroup")
|
||||
if imm1 is None:
|
||||
fail("missing .imacro name")
|
||||
if imacro:
|
||||
fail("nested .imacro " + imm1)
|
||||
imacro = IMacro(imm1, filename)
|
||||
|
||||
elif opname == '.fixup':
|
||||
if imacro is None:
|
||||
fail(".fixup outside of .imacro")
|
||||
if len(imacro.code) != 0:
|
||||
fail(".fixup must be first item in .imacro")
|
||||
if imm1 is None:
|
||||
fail("missing .fixup argument")
|
||||
try:
|
||||
fixup = int(imm1)
|
||||
except ValueError:
|
||||
fail(".fixup argument must be a nonzero integer")
|
||||
if fixup == 0:
|
||||
fail(".fixup argument must be a nonzero integer")
|
||||
if imacro.initdepth != 0:
|
||||
fail("more than one .fixup in .imacro")
|
||||
imacro.initdepth = fixup
|
||||
|
||||
elif opname == '.end':
|
||||
if imacro is None:
|
||||
if igroup is None:
|
||||
fail(".end without prior .igroup or .imacro")
|
||||
if imm1 is not None and (imm1 != igroup.name or imm2 is not None):
|
||||
fail(".igroup/.end name mismatch")
|
||||
|
||||
maxdepth = 0
|
||||
|
||||
write("static struct {\n")
|
||||
for imacro in igroup.imacros:
|
||||
write(" jsbytecode %s[%d];\n" % (imacro.name, imacro.offset))
|
||||
write("} %s_imacros = {\n" % igroup.name)
|
||||
|
||||
for imacro in igroup.imacros:
|
||||
depth = 0
|
||||
write(" {\n")
|
||||
for op in imacro.code:
|
||||
operand = ""
|
||||
if op.imm1 is not None:
|
||||
operand = ", " + immediate(op)
|
||||
write("/*%2d*/ %s%s,\n" % (op.offset, op.info.jsop, operand))
|
||||
|
||||
imacro.maxdepth = imacro.initdepth
|
||||
simulate_cfg(igroup, imacro, imacro.initdepth, 0)
|
||||
if imacro.maxdepth > maxdepth:
|
||||
maxdepth = imacro.maxdepth
|
||||
|
||||
write(" },\n")
|
||||
write("};\n")
|
||||
|
||||
for opcode in igroup.ops:
|
||||
opcode2extra[opcode] = maxdepth
|
||||
igroups.append(igroup)
|
||||
igroup = None
|
||||
else:
|
||||
assert igroup is not None
|
||||
|
||||
if imm1 is not None and imm1 != imacro.name:
|
||||
fail(".imacro/.end name mismatch")
|
||||
|
||||
# Backpatch the forward references to labels that must now be defined.
|
||||
for label in imacro.labelrefs:
|
||||
if label not in imacro.labeldefs:
|
||||
fail("label " + label + " used but not defined")
|
||||
link = imacro.labelrefs[label]
|
||||
assert link >= 0
|
||||
while True:
|
||||
op = imacro.code[link]
|
||||
next = op.target
|
||||
op.target = imacro.labeldefs[label] - op.offset
|
||||
op.target_index = imacro.labeldef_indexes[label]
|
||||
if next < 0:
|
||||
break
|
||||
link = next
|
||||
|
||||
igroup.imacros.append(imacro)
|
||||
imacro = None
|
||||
|
||||
else:
|
||||
fail("unknown pseudo-op " + opname)
|
||||
continue
|
||||
|
||||
if opname not in opname2info:
|
||||
fail("unknown opcode " + opname)
|
||||
|
||||
info = opname2info[opname]
|
||||
if info.oplen == -1:
|
||||
fail("unimplemented opcode " + opname)
|
||||
|
||||
if imacro is None:
|
||||
fail("opcode %s outside of .imacro", opname)
|
||||
|
||||
# Blacklist ops that may or must use an atomized double immediate.
|
||||
if info.opname in ('double', 'lookupswitch', 'lookupswitchx'):
|
||||
fail(op.opname + " opcode not yet supported")
|
||||
|
||||
if label:
|
||||
imacro.labeldefs[label] = imacro.offset
|
||||
imacro.labeldef_indexes[label] = len(imacro.code)
|
||||
|
||||
op = Instruction(imacro.offset, info, imm1, imm2, lineno + 1)
|
||||
if 'JOF_JUMP' in info.flags:
|
||||
if imm1 in imacro.labeldefs:
|
||||
# Backward reference can be resolved right away, no backpatching needed.
|
||||
op.target = imacro.labeldefs[imm1] - op.offset
|
||||
op.target_index = imacro.labeldef_indexes[imm1]
|
||||
else:
|
||||
# Link op into the .target-linked backpatch chain at labelrefs[imm1].
|
||||
# The linked list terminates with a -1 sentinel.
|
||||
if imm1 in imacro.labelrefs:
|
||||
op.target = imacro.labelrefs[imm1]
|
||||
else:
|
||||
op.target = -1
|
||||
imacro.labelrefs[imm1] = len(imacro.code)
|
||||
|
||||
imacro.code.append(op)
|
||||
imacro.offset += info.oplen
|
||||
|
||||
write("uint8 js_opcode2extra[JSOP_LIMIT] = {\n")
|
||||
for i in range(len(opinfo)):
|
||||
write(" %d, /* %s */\n" % (opcode2extra.get(i, 0), opinfo[i].jsop))
|
||||
write("};\n")
|
||||
|
||||
write("#define JSOP_IS_IMACOP(x) (0 \\\n")
|
||||
for i in sorted(opcode2extra):
|
||||
write(" || x == %s \\\n" % opinfo[i].jsop)
|
||||
write(")\n")
|
||||
|
||||
write("jsbytecode*\njs_GetImacroStart(jsbytecode* pc) {\n")
|
||||
for g in igroups:
|
||||
for m in g.imacros:
|
||||
start = g.name + "_imacros." + m.name
|
||||
write(" if (size_t(pc - %s) < %d) return %s;\n" % (start, m.offset, start))
|
||||
|
||||
write(" return NULL;\n")
|
||||
write("}\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if len(sys.argv) != 3:
|
||||
print "usage: python imacro_asm.py infile.jsasm outfile.c.out"
|
||||
sys.exit(1)
|
||||
|
||||
f = open(sys.argv[2], 'w')
|
||||
try:
|
||||
assemble(sys.argv[1], f)
|
||||
finally:
|
||||
f.close()
|
||||
|
@ -1,697 +0,0 @@
|
||||
# -*- indent-tabs-mode: nil; -*-
|
||||
# vim: set sw=4 ts=8 et tw=78 ft=asm:
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the TraceMonkey IMacro Assembler.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Brendan Eich <brendan@mozilla.org>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2008
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
.igroup equality JSOP_EQ-JSOP_NE
|
||||
|
||||
.imacro any_obj # any obj
|
||||
dup # any obj obj
|
||||
dup # any obj obj obj
|
||||
getprop valueOf # any obj obj valueOf
|
||||
ifcantcalltop 1 # any obj obj valueOf
|
||||
swap # any obj valueOf obj
|
||||
call 0 # any obj rval
|
||||
ifcantcalltop 3 # any obj rval
|
||||
pop # any obj
|
||||
dup # any obj obj
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj rval
|
||||
primtop (JSTYPE_NUMBER) # any obj rval
|
||||
3: swap # any rval obj
|
||||
pop # any rval
|
||||
imacop # eqval
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro obj_any # obj any
|
||||
swap # any obj
|
||||
dup # any obj obj
|
||||
dup # any obj obj obj
|
||||
getprop valueOf # any obj obj valueOf
|
||||
ifcantcalltop 1 # any obj obj valueOf
|
||||
swap # any obj valueOf obj
|
||||
call 0 # any obj lval
|
||||
ifcantcalltop 3 # any obj lval
|
||||
pop # any obj
|
||||
dup # any obj obj
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj lval
|
||||
primtop (JSTYPE_NUMBER) # any obj rval
|
||||
3: swap # any lval obj
|
||||
pop # any lval
|
||||
swap # lval any
|
||||
imacop # eqval
|
||||
stop
|
||||
.end
|
||||
|
||||
.end equality
|
||||
|
||||
# A single range, split up like so to test groups over multiple ranges of ops
|
||||
.igroup binary JSOP_BITOR-JSOP_BITAND,JSOP_EQ-JSOP_DIV,JSOP_MOD
|
||||
|
||||
.imacro any_obj # any obj
|
||||
dup # any obj obj
|
||||
dup # any obj obj obj
|
||||
getprop valueOf # any obj obj valueOf
|
||||
ifcantcalltop 1 # any obj obj valueOf
|
||||
swap # any obj valueOf obj
|
||||
call 0 # any obj rval
|
||||
ifcantcalltop 3 # any obj rval
|
||||
pop # any obj
|
||||
dup # any obj obj
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj rval
|
||||
primtop (JSTYPE_NUMBER) # any obj rval
|
||||
3: swap # any rval obj
|
||||
pop # any rval
|
||||
imacop # bval
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro obj_any # obj any
|
||||
swap # any obj
|
||||
dup # any obj obj
|
||||
dup # any obj obj obj
|
||||
getprop valueOf # any obj obj valueOf
|
||||
ifcantcalltop 1 # any obj obj valueOf
|
||||
swap # any obj valueOf obj
|
||||
call 0 # any obj lval
|
||||
ifcantcalltop 3 # any obj lval
|
||||
pop # any obj
|
||||
dup # any obj obj
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj lval
|
||||
primtop (JSTYPE_NUMBER) # any obj lval
|
||||
3: swap # any lval obj
|
||||
pop # any lval
|
||||
swap # lval any
|
||||
imacop # bval
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro obj_obj # obj1 obj2
|
||||
swap # obj2 obj1
|
||||
dup # obj2 obj1 obj1
|
||||
dup # obj2 obj1 obj1 obj1
|
||||
getprop valueOf # obj2 obj1 obj1 valueOf
|
||||
ifcantcalltop 1 # obj2 obj1 obj1 valueOf
|
||||
swap # obj2 obj1 valueOf obj1
|
||||
call 0 # obj2 obj1 lval
|
||||
ifcantcalltop 3 # obj2 obj1 lval
|
||||
pop # obj2 obj1
|
||||
dup # obj2 obj1 obj1
|
||||
goto 2
|
||||
1: pop # obj2 obj1 obj1
|
||||
2: callprop toString # obj2 obj1 toString obj1
|
||||
call 0 # obj2 obj1 lval
|
||||
primtop (JSTYPE_NUMBER) # obj2 obj1 lval
|
||||
3: swap # obj2 lval obj1
|
||||
pop # obj2 lval
|
||||
swap # lval obj2
|
||||
dup # lval obj1 obj1
|
||||
dup # lval obj obj obj
|
||||
getprop valueOf # lval obj obj valueOf
|
||||
ifcantcalltop 4 # lval obj obj valueOf
|
||||
swap # lval obj valueOf obj
|
||||
call 0 # lval obj rval
|
||||
ifcantcalltop 6 # lval obj rval
|
||||
pop # lval obj
|
||||
dup # lval obj obj
|
||||
goto 5
|
||||
4: pop # lval obj obj
|
||||
5: callprop toString # lval obj toString obj
|
||||
call 0 # lval obj rval
|
||||
primtop (JSTYPE_NUMBER) # lval obj rval
|
||||
6: swap # lval rval obj
|
||||
pop # lval rval
|
||||
imacop # bval
|
||||
stop
|
||||
.end
|
||||
|
||||
.end binary
|
||||
|
||||
.igroup add JSOP_ADD
|
||||
|
||||
.imacro any_obj # any obj
|
||||
dup # any obj obj
|
||||
dup # any obj obj obj
|
||||
getprop valueOf # any obj obj valueOf
|
||||
ifcantcalltop 1 # any obj obj valueOf
|
||||
swap # any obj valueOf obj
|
||||
call 0 # any obj rval
|
||||
ifcantcalltop 3 # any obj rval
|
||||
pop # any obj
|
||||
dup # any obj obj
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj rval
|
||||
primtop (JSTYPE_VOID) # any obj rval
|
||||
3: swap # any rval obj
|
||||
pop # any rval
|
||||
add # aval
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro obj_any # obj any
|
||||
swap # any obj
|
||||
dup # any obj obj
|
||||
dup # any obj obj obj
|
||||
getprop valueOf # any obj obj valueOf
|
||||
ifcantcalltop 1 # any obj obj valueOf
|
||||
swap # any obj valueOf obj
|
||||
call 0 # any obj lval
|
||||
ifcantcalltop 3 # any obj lval
|
||||
pop # any obj
|
||||
dup # any obj obj
|
||||
goto 2
|
||||
1: pop # any obj obj
|
||||
2: callprop toString # any obj toString obj
|
||||
call 0 # any obj lval
|
||||
primtop (JSTYPE_VOID) # any obj lval
|
||||
3: swap # any lval obj
|
||||
pop # any lval
|
||||
swap # lval any
|
||||
add # aval
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro obj_obj # obj1 obj2
|
||||
swap # obj2 obj1
|
||||
dup # obj2 obj1 obj1
|
||||
dup # obj2 obj1 obj1 obj1
|
||||
getprop valueOf # obj2 obj1 obj1 valueOf
|
||||
ifcantcalltop 1 # obj2 obj1 obj1 valueOf
|
||||
swap # obj2 obj1 valueOf obj1
|
||||
call 0 # obj2 obj1 lval
|
||||
ifcantcalltop 3 # obj2 obj1 lval
|
||||
pop # obj2 obj1
|
||||
dup # obj2 obj1 obj1
|
||||
goto 2
|
||||
1: pop # obj2 obj1 obj1
|
||||
2: callprop toString # obj2 obj1 toString obj1
|
||||
call 0 # obj2 obj1 lval
|
||||
primtop (JSTYPE_VOID) # obj2 obj1 lval
|
||||
3: swap # obj2 lval obj1
|
||||
pop # obj2 lval
|
||||
swap # lval obj2
|
||||
dup # lval obj obj
|
||||
dup # lval obj obj obj
|
||||
getprop valueOf # lval obj obj valueOf
|
||||
ifcantcalltop 4 # lval obj obj valueOf
|
||||
swap # lval obj valueOf obj
|
||||
call 0 # lval obj rval
|
||||
ifcantcalltop 6 # lval obj rval
|
||||
pop # lval obj
|
||||
dup # lval obj obj
|
||||
goto 5
|
||||
4: pop # lval obj obj
|
||||
5: callprop toString # lval obj toString obj
|
||||
call 0 # lval obj rval
|
||||
primtop (JSTYPE_VOID) # lval obj rval
|
||||
6: swap # lval rval obj
|
||||
pop # lval rval
|
||||
add # aval
|
||||
stop
|
||||
.end
|
||||
|
||||
.end add
|
||||
|
||||
.igroup unary JSOP_NEG-JSOP_POS
|
||||
|
||||
.imacro sign # obj
|
||||
dup # obj obj
|
||||
dup # obj obj obj
|
||||
getprop valueOf # obj obj valueOf
|
||||
ifcantcalltop 2 # obj obj valueOf
|
||||
swap # obj valueOf obj
|
||||
call 0 # obj lval
|
||||
ifcantcalltop 1 # obj lval
|
||||
pop # obj
|
||||
dup # obj obj
|
||||
goto 3
|
||||
1: swap # lval obj
|
||||
pop # lval
|
||||
goto 4
|
||||
2: pop # obj obj
|
||||
3: callprop toString # obj toString obj
|
||||
call 0 # obj lval
|
||||
primtop (JSTYPE_NUMBER) # obj lval
|
||||
swap # lval obj
|
||||
pop # lval
|
||||
4: imacop # aval
|
||||
stop
|
||||
.end
|
||||
|
||||
.end unary
|
||||
|
||||
.igroup incelem JSOP_INCELEM,JSOP_ELEMINC
|
||||
.imacro incelem # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
one # obj id n 1
|
||||
add # obj id m
|
||||
setelem # m
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro eleminc # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
dup # obj id n n
|
||||
one # obj id n n 1
|
||||
add # obj id n m
|
||||
pick 3 # id n m obj
|
||||
pick 3 # n m obj id
|
||||
pick 2 # n obj id m
|
||||
setelem # n m
|
||||
pop # n
|
||||
stop
|
||||
.end
|
||||
.end incelem
|
||||
|
||||
.igroup decelem JSOP_DECELEM,JSOP_ELEMDEC
|
||||
.imacro decelem # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
one # obj id n 1
|
||||
sub # obj id m
|
||||
setelem # m
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro elemdec # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
dup # obj id n n
|
||||
one # obj id n n 1
|
||||
sub # obj id n m
|
||||
pick 3 # id n m obj
|
||||
pick 3 # n m obj id
|
||||
pick 2 # n obj id m
|
||||
setelem # n m
|
||||
pop # n
|
||||
stop
|
||||
.end
|
||||
.end decelem
|
||||
|
||||
.igroup call JSOP_CALL
|
||||
|
||||
.imacro String # String this obj
|
||||
dup # String this obj obj
|
||||
dup # String this obj obj obj
|
||||
getprop toString # String this obj obj toString
|
||||
ifcantcalltop 1 # String this obj obj toString
|
||||
swap # String this obj toString obj
|
||||
call 0 # String this obj rval
|
||||
ifcantcalltop 3 # String this obj rval
|
||||
pop # String this obj
|
||||
dup # String this obj obj
|
||||
goto 2
|
||||
1: pop # String this obj obj
|
||||
2: callprop valueOf # String this obj valueOf obj
|
||||
call 0 # String this obj rval
|
||||
primtop (JSTYPE_STRING) # String this obj rval
|
||||
3: swap # String this rval obj
|
||||
pop # String this rval
|
||||
call 1 # str
|
||||
stop # str
|
||||
.end
|
||||
|
||||
.end call
|
||||
|
||||
.igroup new JSOP_NEW
|
||||
|
||||
.imacro String # String this obj
|
||||
dup # String this obj obj
|
||||
dup # String this obj obj obj
|
||||
getprop toString # String this obj obj toString
|
||||
ifcantcalltop 1 # String this obj obj toString
|
||||
swap # String this obj toString obj
|
||||
call 0 # String this obj rval
|
||||
ifcantcalltop 3 # String this obj rval
|
||||
pop # String this obj
|
||||
dup # String this obj obj
|
||||
goto 2
|
||||
1: pop # String this obj obj
|
||||
2: callprop valueOf # String this obj valueOf obj
|
||||
call 0 # String this obj rval
|
||||
primtop (JSTYPE_STRING) # String this obj rval
|
||||
3: swap # String this rval obj
|
||||
pop # String this rval
|
||||
new 1 # strobj
|
||||
stop # strobj
|
||||
.end
|
||||
|
||||
.end new
|
||||
|
||||
.igroup funapply JSOP_FUNAPPLY
|
||||
|
||||
.imacro apply0 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
pop # fun this
|
||||
call 0 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply1 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
pop # fun this arg0
|
||||
call 1 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply2 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
dup # fun this arg0 arr arr
|
||||
one # fun this arg0 arr arr 1
|
||||
getelem # fun this arg0 arr arg1
|
||||
swap # fun this arg0 arg1 arr
|
||||
pop # fun this arg0 arg1
|
||||
call 2 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply3 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
dup # fun this arg0 arr arr
|
||||
one # fun this arg0 arr arr 1
|
||||
getelem # fun this arg0 arr arg1
|
||||
swap # fun this arg0 arg1 arr
|
||||
dup # fun this arg0 arg1 arr arr
|
||||
int8 2 # fun this arg0 arg1 arr arr 2
|
||||
getelem # fun this arg0 arg1 arr arg2
|
||||
swap # fun this arg0 arg1 arg2 arr
|
||||
pop # fun this arg0 arg1 arg2
|
||||
call 3 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply4 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
dup # fun this arg0 arr arr
|
||||
one # fun this arg0 arr arr 1
|
||||
getelem # fun this arg0 arr arg1
|
||||
swap # fun this arg0 arg1 arr
|
||||
dup # fun this arg0 arg1 arr arr
|
||||
int8 2 # fun this arg0 arg1 arr arr 2
|
||||
getelem # fun this arg0 arg1 arr arg2
|
||||
swap # fun this arg0 arg1 arg2 arr
|
||||
dup # fun this arg0 arg1 arg2 arr arr
|
||||
int8 3 # fun this arg0 arg1 arg2 arr arr 3
|
||||
getelem # fun this arg0 arg1 arg2 arr arg3
|
||||
swap # fun this arg0 arg1 arg2 arg3 arr
|
||||
pop # fun this arg0 arg1 arg2 arg3
|
||||
call 4 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply5 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
dup # fun this arg0 arr arr
|
||||
one # fun this arg0 arr arr 1
|
||||
getelem # fun this arg0 arr arg1
|
||||
swap # fun this arg0 arg1 arr
|
||||
dup # fun this arg0 arg1 arr arr
|
||||
int8 2 # fun this arg0 arg1 arr arr 2
|
||||
getelem # fun this arg0 arg1 arr arg2
|
||||
swap # fun this arg0 arg1 arg2 arr
|
||||
dup # fun this arg0 arg1 arg2 arr arr
|
||||
int8 3 # fun this arg0 arg1 arg2 arr arr 3
|
||||
getelem # fun this arg0 arg1 arg2 arr arg3
|
||||
swap # fun this arg0 arg1 arg2 arg3 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arr arr
|
||||
int8 4 # fun this arg0 arg1 arg2 arg3 arr arr 4
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arr arg4
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arr
|
||||
pop # fun this arg0 arg1 arg2 arg3 arg4
|
||||
call 5 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply6 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
dup # fun this arg0 arr arr
|
||||
one # fun this arg0 arr arr 1
|
||||
getelem # fun this arg0 arr arg1
|
||||
swap # fun this arg0 arg1 arr
|
||||
dup # fun this arg0 arg1 arr arr
|
||||
int8 2 # fun this arg0 arg1 arr arr 2
|
||||
getelem # fun this arg0 arg1 arr arg2
|
||||
swap # fun this arg0 arg1 arg2 arr
|
||||
dup # fun this arg0 arg1 arg2 arr arr
|
||||
int8 3 # fun this arg0 arg1 arg2 arr arr 3
|
||||
getelem # fun this arg0 arg1 arg2 arr arg3
|
||||
swap # fun this arg0 arg1 arg2 arg3 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arr arr
|
||||
int8 4 # fun this arg0 arg1 arg2 arg3 arr arr 4
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arr arg4
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arg4 arr arr
|
||||
int8 5 # fun this arg0 arg1 arg2 arg3 arg4 arr arr 5
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arg4 arr arg5
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr
|
||||
pop # fun this arg0 arg1 arg2 arg3 arg4 arg5
|
||||
call 6 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply7 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
dup # fun this arg0 arr arr
|
||||
one # fun this arg0 arr arr 1
|
||||
getelem # fun this arg0 arr arg1
|
||||
swap # fun this arg0 arg1 arr
|
||||
dup # fun this arg0 arg1 arr arr
|
||||
int8 2 # fun this arg0 arg1 arr arr 2
|
||||
getelem # fun this arg0 arg1 arr arg2
|
||||
swap # fun this arg0 arg1 arg2 arr
|
||||
dup # fun this arg0 arg1 arg2 arr arr
|
||||
int8 3 # fun this arg0 arg1 arg2 arr arr 3
|
||||
getelem # fun this arg0 arg1 arg2 arr arg3
|
||||
swap # fun this arg0 arg1 arg2 arg3 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arr arr
|
||||
int8 4 # fun this arg0 arg1 arg2 arg3 arr arr 4
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arr arg4
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arg4 arr arr
|
||||
int8 5 # fun this arg0 arg1 arg2 arg3 arg4 arr arr 5
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arg4 arr arg5
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr
|
||||
int8 6 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr 6
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arg6
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr
|
||||
pop # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6
|
||||
call 7 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro apply8 # apply fun this arr
|
||||
pick 3 # fun this arr apply
|
||||
pop # fun this arr
|
||||
dup # fun this arr arr
|
||||
zero # fun this arr arr 0
|
||||
getelem # fun this arr arg0
|
||||
swap # fun this arg0 arr
|
||||
dup # fun this arg0 arr arr
|
||||
one # fun this arg0 arr arr 1
|
||||
getelem # fun this arg0 arr arg1
|
||||
swap # fun this arg0 arg1 arr
|
||||
dup # fun this arg0 arg1 arr arr
|
||||
int8 2 # fun this arg0 arg1 arr arr 2
|
||||
getelem # fun this arg0 arg1 arr arg2
|
||||
swap # fun this arg0 arg1 arg2 arr
|
||||
dup # fun this arg0 arg1 arg2 arr arr
|
||||
int8 3 # fun this arg0 arg1 arg2 arr arr 3
|
||||
getelem # fun this arg0 arg1 arg2 arr arg3
|
||||
swap # fun this arg0 arg1 arg2 arg3 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arr arr
|
||||
int8 4 # fun this arg0 arg1 arg2 arg3 arr arr 4
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arr arg4
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arg4 arr arr
|
||||
int8 5 # fun this arg0 arg1 arg2 arg3 arg4 arr arr 5
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arg4 arr arg5
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr
|
||||
int8 6 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr 6
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arg6
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr
|
||||
dup # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr arr
|
||||
int8 7 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr arr 7
|
||||
getelem # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr arg7
|
||||
swap # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arr
|
||||
pop # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7
|
||||
call 8 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.end funapply
|
||||
|
||||
.igroup funcall JSOP_FUNCALL
|
||||
|
||||
.imacro call0 # call fun
|
||||
swap # fun call
|
||||
pop # fun
|
||||
null # fun this
|
||||
call 0 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call1 # call fun this
|
||||
pick 2 # fun this call
|
||||
pop # fun this
|
||||
call 0 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call2 # call fun this arg0
|
||||
pick 3 # fun this arg0 call
|
||||
pop # fun this arg0
|
||||
call 1 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call3 # call fun this arg0 arg1
|
||||
pick 4 # fun this arg0 arg1 call
|
||||
pop # fun this arg0 arg1
|
||||
call 2 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call4 # call fun this arg0 arg1 arg2
|
||||
pick 5 # fun this arg0 arg1 arg2 call
|
||||
pop # fun this arg0 arg1 arg2
|
||||
call 3 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call5 # call fun this arg0 arg1 arg2 arg3
|
||||
pick 6 # fun this arg0 arg1 arg2 arg3 call
|
||||
pop # fun this arg0 arg1 arg2 arg3
|
||||
call 4 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call6 # call fun this arg0 arg1 arg2 arg3 arg4
|
||||
pick 7 # fun this arg0 arg1 arg2 arg3 arg4 call
|
||||
pop # fun this arg0 arg1 arg2 arg3 arg4
|
||||
call 5 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call7 # call fun this arg0 arg1 arg2 arg3 arg4 arg5
|
||||
pick 8 # fun this arg0 arg1 arg2 arg3 arg4 arg5 call
|
||||
pop # fun this arg0 arg1 arg2 arg3 arg4 arg5
|
||||
call 6 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.imacro call8 # call fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6
|
||||
pick 9 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 call
|
||||
pop # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6
|
||||
call 7 #
|
||||
stop #
|
||||
.end #
|
||||
|
||||
.end funcall
|
||||
|
||||
.igroup getprop JSOP_GETPROP
|
||||
.imacro scriptgetter # obj
|
||||
.fixup +1 # getter obj
|
||||
call 0 # val
|
||||
stop
|
||||
.end
|
||||
.end getprop
|
||||
|
||||
.igroup callprop JSOP_CALLPROP
|
||||
.imacro scriptgetter # obj
|
||||
.fixup +2 # obj getter obj
|
||||
call 0 # obj method
|
||||
swap # method obj
|
||||
stop
|
||||
.end
|
||||
.end callprop
|
@ -356,7 +356,7 @@ def parse_jitflags():
|
||||
for flags in OPTIONS.jitflags.split(',') ]
|
||||
for flags in jitflags:
|
||||
for flag in flags:
|
||||
if flag not in ('-j', '-m', '-a', '-p', '-d', '-n'):
|
||||
if flag not in ('-m', '-a', '-p', '-d', '-n'):
|
||||
print('Invalid jit flag: "%s"'%flag)
|
||||
sys.exit(1)
|
||||
return jitflags
|
||||
@ -420,8 +420,8 @@ def main(argv):
|
||||
help='Enable the |valgrind| flag, if valgrind is in $PATH.')
|
||||
op.add_option('--valgrind-all', dest='valgrind_all', action='store_true',
|
||||
help='Run all tests with valgrind, if valgrind is in $PATH.')
|
||||
op.add_option('--jitflags', dest='jitflags', default='mjp',
|
||||
help='Example: --jitflags=j,mj,mjp to run each test with -j, -m -j, -m -j -p [default=%default]')
|
||||
op.add_option('--jitflags', dest='jitflags', default='m,mn',
|
||||
help='Example: --jitflags=m,mn to run each test with -m, -m -n [default=%default]')
|
||||
op.add_option('--avoid-stdio', dest='avoid_stdio', action='store_true',
|
||||
help='Use js-shell file indirection instead of piping stdio.')
|
||||
op.add_option('--write-failure-output', dest='write_failure_output', action='store_true',
|
||||
|
@ -91,9 +91,8 @@
|
||||
#undef JS_INTPTR_TYPE
|
||||
#undef JS_BYTES_PER_WORD
|
||||
|
||||
/* Some mozilla code uses JS-friend APIs that depend on JS_TRACER and
|
||||
JS_METHODJIT being correct. */
|
||||
#undef JS_TRACER
|
||||
/* Some mozilla code uses JS-friend APIs that depend on JS_METHODJIT being
|
||||
correct. */
|
||||
#undef JS_METHODJIT
|
||||
|
||||
#endif /* js_config_h___ */
|
||||
|
@ -2,8 +2,6 @@
|
||||
#include "jsfun.h"
|
||||
#include "jscntxt.h"
|
||||
|
||||
// For TRACING_ENABLED
|
||||
#include "jstracer.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
@ -103,15 +101,6 @@ BEGIN_TEST(testFuncCallback_bug507012)
|
||||
CHECK_EQUAL(leaves, 1+50);
|
||||
CHECK_EQUAL(depth, 0);
|
||||
|
||||
// If this fails, it means that the code was interpreted rather
|
||||
// than trace-JITted, and so is not testing what it's supposed to
|
||||
// be testing. Which doesn't necessarily imply that the
|
||||
// functionality is broken.
|
||||
#ifdef JS_TRACER
|
||||
if (TRACING_ENABLED(cx))
|
||||
CHECK(interpreted < enters);
|
||||
#endif
|
||||
|
||||
// Test nesting callbacks via JS_GetFunctionCallback()
|
||||
JS_SetFunctionCallback(cx, funcTransition);
|
||||
innerCallback = JS_GetFunctionCallback(cx);
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include "jsarray.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsbool.h"
|
||||
#include "jsbuiltins.h"
|
||||
#include "jsclone.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
@ -78,7 +77,6 @@
|
||||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstracer.h"
|
||||
#include "prmjtime.h"
|
||||
#include "jsweakmap.h"
|
||||
#include "jswrapper.h"
|
||||
@ -657,6 +655,7 @@ JSRuntime::JSRuntime()
|
||||
gcMaxBytes(0),
|
||||
gcMaxMallocBytes(0),
|
||||
gcEmptyArenaPoolLifespan(0),
|
||||
gcNumFreeArenas(0),
|
||||
gcNumber(0),
|
||||
gcIncrementalTracer(NULL),
|
||||
gcVerifyData(NULL),
|
||||
@ -751,10 +750,6 @@ JSRuntime::init(uint32 maxbytes)
|
||||
JMCheckLogging();
|
||||
#endif
|
||||
|
||||
#ifdef JS_TRACER
|
||||
InitJIT();
|
||||
#endif
|
||||
|
||||
if (!js_InitGC(this, maxbytes))
|
||||
return false;
|
||||
|
||||
@ -813,10 +808,6 @@ JSRuntime::~JSRuntime()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_TRACER
|
||||
FinishJIT();
|
||||
#endif
|
||||
|
||||
FinishRuntimeNumberState(this);
|
||||
js_FinishThreads(this);
|
||||
js_FinishAtomState(this);
|
||||
@ -917,10 +908,6 @@ JS_ShutDown(void)
|
||||
{
|
||||
Probes::shutdown();
|
||||
|
||||
#ifdef MOZ_TRACEVIS
|
||||
StopTraceVis();
|
||||
#endif
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
js_CleanupLocks();
|
||||
#endif
|
||||
@ -983,8 +970,6 @@ StopRequest(JSContext *cx)
|
||||
if (t->data.requestDepth != 1) {
|
||||
t->data.requestDepth--;
|
||||
} else {
|
||||
LeaveTrace(cx); /* for GC safety */
|
||||
|
||||
t->data.conservativeGC.updateForRequestEnd(t->suspendCount);
|
||||
|
||||
/* Lock before clearing to interlock with ClaimScope, in jslock.c. */
|
||||
@ -2747,8 +2732,6 @@ JS_CompartmentGC(JSContext *cx, JSCompartment *comp)
|
||||
/* We cannot GC the atoms compartment alone; use a full GC instead. */
|
||||
JS_ASSERT(comp != cx->runtime->atomsCompartment);
|
||||
|
||||
LeaveTrace(cx);
|
||||
|
||||
js::gc::VerifyBarriers(cx, true);
|
||||
js_GC(cx, comp, GC_NORMAL, gcstats::PUBLIC_API);
|
||||
}
|
||||
@ -2762,8 +2745,6 @@ JS_GC(JSContext *cx)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_MaybeGC(JSContext *cx)
|
||||
{
|
||||
LeaveTrace(cx);
|
||||
|
||||
MaybeGC(cx);
|
||||
}
|
||||
|
||||
@ -2842,29 +2823,18 @@ JS_PUBLIC_API(void)
|
||||
JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32 value)
|
||||
{
|
||||
JS_ASSERT(key == JSGC_MAX_CODE_CACHE_BYTES);
|
||||
#ifdef JS_TRACER
|
||||
SetMaxCodeCacheBytes(cx, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(uint32)
|
||||
JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key)
|
||||
{
|
||||
JS_ASSERT(key == JSGC_MAX_CODE_CACHE_BYTES);
|
||||
#ifdef JS_TRACER
|
||||
return JS_THREAD_DATA(cx)->maxCodeCacheBytes;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_FlushCaches(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_TRACER
|
||||
if (cx->compartment->hasTraceMonitor())
|
||||
FlushJITCache(cx, cx->compartment->traceMonitor());
|
||||
#endif
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(intN)
|
||||
@ -4527,14 +4497,7 @@ js_generic_native_method_dispatcher(JSContext *cx, uintN argc, Value *vp)
|
||||
/* Clear the last parameter in case too few arguments were passed. */
|
||||
vp[2 + --argc].setUndefined();
|
||||
|
||||
Native native =
|
||||
#ifdef JS_TRACER
|
||||
(fs->flags & JSFUN_TRCINFO)
|
||||
? JS_FUNC_TO_DATA_PTR(JSNativeTraceInfo *, fs->call)->native
|
||||
:
|
||||
#endif
|
||||
fs->call;
|
||||
return native(cx, argc, vp);
|
||||
return fs->call(cx, argc, vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
@ -4570,7 +4533,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
|
||||
fun = js_DefineFunction(cx, ctor, ATOM_TO_JSID(atom),
|
||||
js_generic_native_method_dispatcher,
|
||||
fs->nargs + 1,
|
||||
flags & ~JSFUN_TRCINFO);
|
||||
flags);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -5325,10 +5288,6 @@ JS_IsRunning(JSContext *cx)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#ifdef JS_TRACER
|
||||
JS_ASSERT_IF(JS_ON_TRACE(cx) && JS_TRACE_MONITOR_ON_TRACE(cx)->tracecx == cx, cx->hasfp());
|
||||
#endif
|
||||
|
||||
StackFrame *fp = cx->maybefp();
|
||||
while (fp && fp->isDummyFrame())
|
||||
fp = fp->prev();
|
||||
@ -5339,7 +5298,6 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_SaveFrameChain(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
LeaveTrace(cx);
|
||||
return cx->stack.saveFrameChain();
|
||||
}
|
||||
|
||||
@ -5347,7 +5305,6 @@ JS_PUBLIC_API(void)
|
||||
JS_RestoreFrameChain(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
JS_ASSERT_NOT_ON_TRACE(cx);
|
||||
cx->stack.restoreFrameChain();
|
||||
}
|
||||
|
||||
|
@ -2157,7 +2157,7 @@ JS_StringToVersion(const char *string);
|
||||
of the input string */
|
||||
/* JS_BIT(10) is currently unused. */
|
||||
|
||||
#define JSOPTION_JIT JS_BIT(11) /* Enable JIT compilation. */
|
||||
#define JSOPTION_JIT JS_BIT(11) /* Deprecated; does nothing */
|
||||
|
||||
#define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) /* A promise to the compiler
|
||||
that a null rval out-param
|
||||
|
@ -110,7 +110,6 @@
|
||||
#include "jsarray.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsbool.h"
|
||||
#include "jsbuiltins.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsfun.h"
|
||||
@ -123,7 +122,6 @@
|
||||
#include "jsobj.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstracer.h"
|
||||
#include "jswrapper.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/StubCalls.h"
|
||||
@ -507,25 +505,6 @@ SetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, const Value &v)
|
||||
return obj->setGeneric(cx, idr.id(), &tmp, true);
|
||||
}
|
||||
|
||||
#ifdef JS_TRACER
|
||||
JSBool JS_FASTCALL
|
||||
js_EnsureDenseArrayCapacity(JSContext *cx, JSObject *obj, jsint i)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Class *origObjClasp = obj->getClass();
|
||||
#endif
|
||||
jsuint u = jsuint(i);
|
||||
JSBool ret = (obj->ensureDenseArrayElements(cx, u, 1) == JSObject::ED_OK);
|
||||
|
||||
/* Partially check the CallInfo's storeAccSet is correct. */
|
||||
JS_ASSERT(obj->getClass() == origObjClasp);
|
||||
return ret;
|
||||
}
|
||||
/* This function and its callees do not touch any object's .clasp field. */
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_EnsureDenseArrayCapacity, CONTEXT, OBJECT, INT32,
|
||||
0, nanojit::ACCSET_STORE_ANY & ~tjit::ACCSET_OBJ_CLASP)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Delete the element |index| from |obj|. If |strict|, do a strict
|
||||
* deletion: throw if the property is not configurable.
|
||||
@ -1718,7 +1697,6 @@ array_toString(JSContext *cx, uintN argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
LeaveTrace(cx);
|
||||
InvokeArgsGuard ag;
|
||||
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
|
||||
return false;
|
||||
@ -1770,16 +1748,22 @@ InitArrayTypes(JSContext *cx, TypeObject *type, const Value *vector, unsigned co
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, const Value *vector, bool updateTypes)
|
||||
enum ShouldUpdateTypes
|
||||
{
|
||||
UpdateTypes = true,
|
||||
DontUpdateTypes = false
|
||||
};
|
||||
|
||||
static bool
|
||||
InitArrayElements(JSContext *cx, JSObject *obj, uint32 start, uint32 count, const Value *vector, ShouldUpdateTypes updateTypes)
|
||||
{
|
||||
JS_ASSERT(count <= MAX_ARRAY_INDEX);
|
||||
|
||||
if (count == 0)
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
|
||||
if (updateTypes && !InitArrayTypes(cx, obj->getType(cx), vector, count))
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Optimize for dense arrays so long as adding the given set of elements
|
||||
@ -1812,16 +1796,16 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, cons
|
||||
while (vector < end && start <= MAX_ARRAY_INDEX) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!SetArrayElement(cx, obj, start++, *vector++)) {
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (vector == end)
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
|
||||
/* Finish out any remaining elements past the max array index. */
|
||||
if (obj->isDenseArray() && !obj->makeDenseArraySlow(cx))
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
|
||||
JS_ASSERT(start == MAX_ARRAY_INDEX + 1);
|
||||
AutoValueRooter tvr(cx);
|
||||
@ -1831,12 +1815,12 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, cons
|
||||
*tvr.addr() = *vector++;
|
||||
if (!js_ValueToStringId(cx, idval, idr.addr()) ||
|
||||
!obj->setGeneric(cx, idr.id(), tvr.addr(), true)) {
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
}
|
||||
idval.getDoubleRef() += 1;
|
||||
} while (vector != end);
|
||||
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -2240,7 +2224,7 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
|
||||
* InitArrayElements easier.
|
||||
*/
|
||||
vec.resize(n);
|
||||
if (!InitArrayElements(cx, obj, 0, jsuint(n), vec.begin(), false))
|
||||
if (!InitArrayElements(cx, obj, 0, jsuint(n), vec.begin(), DontUpdateTypes))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2270,7 +2254,7 @@ array_push_slowly(JSContext *cx, JSObject *obj, CallArgs &args)
|
||||
|
||||
if (!js_GetLengthProperty(cx, obj, &length))
|
||||
return false;
|
||||
if (!InitArrayElements(cx, obj, length, args.length(), args.array(), true))
|
||||
if (!InitArrayElements(cx, obj, length, args.length(), args.array(), UpdateTypes))
|
||||
return false;
|
||||
|
||||
/* Per ECMA-262, return the new array length. */
|
||||
@ -2333,23 +2317,6 @@ js_NewbornArrayPush(JSContext *cx, JSObject *obj, const Value &vp)
|
||||
return NewbornArrayPushImpl(cx, obj, vp);
|
||||
}
|
||||
|
||||
#ifdef JS_TRACER
|
||||
JSBool JS_FASTCALL
|
||||
js_NewbornArrayPush_tn(JSContext *cx, JSObject *obj, ValueArgType v)
|
||||
{
|
||||
TraceMonitor *tm = JS_TRACE_MONITOR_ON_TRACE(cx);
|
||||
|
||||
if (!NewbornArrayPushImpl(cx, obj, ValueArgToConstRef(v))) {
|
||||
SetBuiltinError(tm);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return WasBuiltinSuccessful(tm);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL_FAIL, js_NewbornArrayPush_tn, CONTEXT, OBJECT,
|
||||
VALUE, 0, nanojit::ACCSET_STORE_ANY)
|
||||
#endif
|
||||
|
||||
JSBool
|
||||
js::array_push(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
@ -2436,7 +2403,6 @@ mjit::stubs::ArrayShift(VMFrame &f)
|
||||
{
|
||||
JSObject *obj = &f.regs.sp[-1].toObject();
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
JS_ASSERT(!js_PrototypeHasIndexedProperties(f.cx, obj));
|
||||
|
||||
/*
|
||||
* At this point the length and initialized length have already been
|
||||
@ -2555,7 +2521,7 @@ array_unshift(JSContext *cx, uintN argc, Value *vp)
|
||||
}
|
||||
|
||||
/* Copy from args to the bottom of the array. */
|
||||
if (!InitArrayElements(cx, obj, 0, args.length(), args.array(), true))
|
||||
if (!InitArrayElements(cx, obj, 0, args.length(), args.array(), UpdateTypes))
|
||||
return JS_FALSE;
|
||||
|
||||
newlen += args.length();
|
||||
@ -3753,19 +3719,6 @@ NewDenseCopiedArray(JSContext *cx, uint32 length, const Value *vp, JSObject *pro
|
||||
return obj;
|
||||
}
|
||||
|
||||
#ifdef JS_TRACER
|
||||
JS_DEFINE_CALLINFO_2(extern, OBJECT, NewDenseEmptyArray, CONTEXT, OBJECT, 0,
|
||||
nanojit::ACCSET_STORE_ANY)
|
||||
JS_DEFINE_CALLINFO_3(extern, OBJECT, NewDenseAllocatedArray, CONTEXT, UINT32, OBJECT, 0,
|
||||
nanojit::ACCSET_STORE_ANY)
|
||||
JS_DEFINE_CALLINFO_3(extern, OBJECT, NewDenseAllocatedEmptyArray, CONTEXT, UINT32, OBJECT, 0,
|
||||
nanojit::ACCSET_STORE_ANY)
|
||||
JS_DEFINE_CALLINFO_3(extern, OBJECT, NewDenseUnallocatedArray, CONTEXT, UINT32, OBJECT, 0,
|
||||
nanojit::ACCSET_STORE_ANY)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
JSObject *
|
||||
NewSlowEmptyArray(JSContext *cx)
|
||||
{
|
||||
|
@ -1,330 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; -*-
|
||||
* vim: set ts=4 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
|
||||
* May 28, 2008.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brendan Eich <brendan@mozilla.org>
|
||||
* Mike Shaver <shaver@mozilla.org>
|
||||
* David Anderson <danderson@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsarray.h"
|
||||
#include "jsbool.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsiter.h"
|
||||
#include "jsnum.h"
|
||||
#include "jslibmath.h"
|
||||
#include "jsmath.h"
|
||||
#include "jsnum.h"
|
||||
#include "prmjtime.h"
|
||||
#include "jsdate.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsstr.h"
|
||||
#include "jsbuiltins.h"
|
||||
#include "jstracer.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jscntxtinlines.h"
|
||||
#include "jsnuminlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsscopeinlines.h"
|
||||
|
||||
using namespace avmplus;
|
||||
using namespace nanojit;
|
||||
using namespace js;
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_SetTraceableNativeFailed(JSContext *cx)
|
||||
{
|
||||
/*
|
||||
* We might not be on trace (we might have deep bailed) so we hope
|
||||
* cx->compartment is correct.
|
||||
*/
|
||||
SetBuiltinError(JS_TRACE_MONITOR_FROM_CONTEXT(cx));
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: bool FASTCALL is not compatible with Nanojit's calling convention usage.
|
||||
* Do not use bool FASTCALL, use JSBool only!
|
||||
*/
|
||||
|
||||
jsdouble FASTCALL
|
||||
js_dmod(jsdouble a, jsdouble b)
|
||||
{
|
||||
if (b == 0.0) {
|
||||
jsdpun u;
|
||||
u.s.hi = JSDOUBLE_HI32_NAN;
|
||||
u.s.lo = JSDOUBLE_LO32_NAN;
|
||||
return u.d;
|
||||
}
|
||||
return js_fmod(a, b);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_2(extern, DOUBLE, js_dmod, DOUBLE, DOUBLE, 1, ACCSET_NONE)
|
||||
|
||||
int32 FASTCALL
|
||||
js_imod(int32 a, int32 b)
|
||||
{
|
||||
if (a < 0 || b <= 0)
|
||||
return -1;
|
||||
int r = a % b;
|
||||
return r;
|
||||
}
|
||||
JS_DEFINE_CALLINFO_2(extern, INT32, js_imod, INT32, INT32, 1, ACCSET_NONE)
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
|
||||
jsdouble FASTCALL
|
||||
js_UnboxNumberAsDouble(uint32 tag, uint32 payload)
|
||||
{
|
||||
if (tag == JSVAL_TAG_INT32)
|
||||
return (double)(int32)payload;
|
||||
|
||||
JS_ASSERT(tag <= JSVAL_TAG_CLEAR);
|
||||
jsval_layout l;
|
||||
l.s.tag = (JSValueTag)tag;
|
||||
l.s.payload.u32 = payload;
|
||||
return l.asDouble;
|
||||
}
|
||||
JS_DEFINE_CALLINFO_2(extern, DOUBLE, js_UnboxNumberAsDouble, UINT32, UINT32, 1, ACCSET_NONE)
|
||||
|
||||
int32 FASTCALL
|
||||
js_UnboxNumberAsInt32(uint32 tag, uint32 payload)
|
||||
{
|
||||
if (tag == JSVAL_TAG_INT32)
|
||||
return (int32)payload;
|
||||
|
||||
JS_ASSERT(tag <= JSVAL_TAG_CLEAR);
|
||||
jsval_layout l;
|
||||
l.s.tag = (JSValueTag)tag;
|
||||
l.s.payload.u32 = payload;
|
||||
return js_DoubleToECMAInt32(l.asDouble);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_2(extern, INT32, js_UnboxNumberAsInt32, UINT32, UINT32, 1, ACCSET_NONE)
|
||||
|
||||
#elif JS_BITS_PER_WORD == 64
|
||||
|
||||
jsdouble FASTCALL
|
||||
js_UnboxNumberAsDouble(Value v)
|
||||
{
|
||||
if (v.isInt32())
|
||||
return (jsdouble)v.toInt32();
|
||||
JS_ASSERT(v.isDouble());
|
||||
return v.toDouble();
|
||||
}
|
||||
JS_DEFINE_CALLINFO_1(extern, DOUBLE, js_UnboxNumberAsDouble, JSVAL, 1, ACCSET_NONE)
|
||||
|
||||
int32 FASTCALL
|
||||
js_UnboxNumberAsInt32(Value v)
|
||||
{
|
||||
if (v.isInt32())
|
||||
return v.toInt32();
|
||||
JS_ASSERT(v.isDouble());
|
||||
return js_DoubleToECMAInt32(v.toDouble());
|
||||
}
|
||||
JS_DEFINE_CALLINFO_1(extern, INT32, js_UnboxNumberAsInt32, VALUE, 1, ACCSET_NONE)
|
||||
|
||||
#endif
|
||||
|
||||
int32 FASTCALL
|
||||
js_DoubleToInt32(jsdouble d)
|
||||
{
|
||||
return js_DoubleToECMAInt32(d);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_1(extern, INT32, js_DoubleToInt32, DOUBLE, 1, ACCSET_NONE)
|
||||
|
||||
uint32 FASTCALL
|
||||
js_DoubleToUint32(jsdouble d)
|
||||
{
|
||||
return js_DoubleToECMAUint32(d);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_1(extern, UINT32, js_DoubleToUint32, DOUBLE, 1, ACCSET_NONE)
|
||||
|
||||
/*
|
||||
* js_StringToNumber and js_StringToInt32 store into their second argument, so
|
||||
* they need to be annotated accordingly. To be future-proof, we use
|
||||
* ACCSET_STORE_ANY so that new callers don't have to remember to update the
|
||||
* annotation.
|
||||
*/
|
||||
jsdouble FASTCALL
|
||||
js_StringToNumber(JSContext* cx, JSString* str, JSBool *ok)
|
||||
{
|
||||
double out = 0; /* silence warnings. */
|
||||
*ok = StringToNumberType<jsdouble>(cx, str, &out);
|
||||
return out;
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, DOUBLE, js_StringToNumber, CONTEXT, STRING, BOOLPTR,
|
||||
0, ACCSET_STORE_ANY)
|
||||
|
||||
int32 FASTCALL
|
||||
js_StringToInt32(JSContext* cx, JSString* str, JSBool *ok)
|
||||
{
|
||||
int32 out = 0; /* silence warnings. */
|
||||
*ok = StringToNumberType<int32>(cx, str, &out);
|
||||
return out;
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, INT32, js_StringToInt32, CONTEXT, STRING, BOOLPTR,
|
||||
0, ACCSET_STORE_ANY)
|
||||
|
||||
/* Nb: it's always safe to set isDefinitelyAtom to false if you're unsure or don't know. */
|
||||
static inline JSBool
|
||||
AddPropertyHelper(JSContext* cx, JSObject* obj, Shape* shape, bool isDefinitelyAtom)
|
||||
{
|
||||
JS_ASSERT(shape->previous() == obj->lastProperty());
|
||||
|
||||
if (obj->nativeEmpty()) {
|
||||
if (!obj->ensureClassReservedSlotsForEmptyObject(cx))
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 slot;
|
||||
slot = shape->slot;
|
||||
JS_ASSERT(slot == obj->slotSpan());
|
||||
|
||||
if (slot < obj->numSlots()) {
|
||||
JS_ASSERT(obj->getSlot(slot).isUndefined());
|
||||
} else {
|
||||
if (!obj->allocSlot(cx, &slot))
|
||||
return false;
|
||||
JS_ASSERT(slot == shape->slot);
|
||||
}
|
||||
|
||||
obj->extend(cx, shape, isDefinitelyAtom);
|
||||
return !js_IsPropertyCacheDisabled(cx);
|
||||
}
|
||||
|
||||
JSBool FASTCALL
|
||||
js_AddProperty(JSContext* cx, JSObject* obj, Shape* shape)
|
||||
{
|
||||
return AddPropertyHelper(cx, obj, shape, /* isDefinitelyAtom = */false);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_AddProperty, CONTEXT, OBJECT, SHAPE, 0, ACCSET_STORE_ANY)
|
||||
|
||||
JSBool FASTCALL
|
||||
js_AddAtomProperty(JSContext* cx, JSObject* obj, Shape* shape)
|
||||
{
|
||||
return AddPropertyHelper(cx, obj, shape, /* isDefinitelyAtom = */true);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_AddAtomProperty, CONTEXT, OBJECT, SHAPE, 0, ACCSET_STORE_ANY)
|
||||
|
||||
static JSBool
|
||||
HasProperty(JSContext* cx, JSObject* obj, jsid id)
|
||||
{
|
||||
// Check that we know how the lookup op will behave.
|
||||
for (JSObject* pobj = obj; pobj; pobj = pobj->getProto()) {
|
||||
if (pobj->getOps()->lookupProperty)
|
||||
return JS_NEITHER;
|
||||
Class* clasp = pobj->getClass();
|
||||
if (clasp->resolve != JS_ResolveStub && clasp != &StringClass)
|
||||
return JS_NEITHER;
|
||||
}
|
||||
|
||||
JSObject* obj2;
|
||||
JSProperty* prop;
|
||||
if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
|
||||
return JS_NEITHER;
|
||||
return prop != NULL;
|
||||
}
|
||||
|
||||
JSBool FASTCALL
|
||||
js_HasNamedProperty(JSContext* cx, JSObject* obj, JSString* idstr)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeString(cx, idstr);
|
||||
if (!atom)
|
||||
return JS_NEITHER;
|
||||
|
||||
return HasProperty(cx, obj, ATOM_TO_JSID(atom));
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_HasNamedProperty, CONTEXT, OBJECT, STRING,
|
||||
0, ACCSET_STORE_ANY)
|
||||
|
||||
JSBool FASTCALL
|
||||
js_HasNamedPropertyInt32(JSContext* cx, JSObject* obj, int32 index)
|
||||
{
|
||||
jsid id;
|
||||
if (!js_Int32ToId(cx, index, &id))
|
||||
return JS_NEITHER;
|
||||
|
||||
return HasProperty(cx, obj, id);
|
||||
}
|
||||
JS_DEFINE_CALLINFO_3(extern, BOOL, js_HasNamedPropertyInt32, CONTEXT, OBJECT, INT32,
|
||||
0, ACCSET_STORE_ANY)
|
||||
|
||||
JSString* FASTCALL
|
||||
js_TypeOfObject(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
JS_ASSERT(obj);
|
||||
return cx->runtime->atomState.typeAtoms[obj->typeOf(cx)];
|
||||
}
|
||||
JS_DEFINE_CALLINFO_2(extern, STRING, js_TypeOfObject, CONTEXT, OBJECT, 1, ACCSET_NONE)
|
||||
|
||||
JSString* FASTCALL
|
||||
js_BooleanIntToString(JSContext *cx, int32 unboxed)
|
||||
{
|
||||
JS_ASSERT(uint32(unboxed) <= 1);
|
||||
return cx->runtime->atomState.booleanAtoms[unboxed];
|
||||
}
|
||||
JS_DEFINE_CALLINFO_2(extern, STRING, js_BooleanIntToString, CONTEXT, INT32, 1, ACCSET_NONE)
|
||||
|
||||
JSObject* FASTCALL
|
||||
js_NewNullClosure(JSContext* cx, JSObject* funobj, JSObject* proto, JSObject* parent)
|
||||
{
|
||||
JS_ASSERT(funobj->isFunction());
|
||||
JS_ASSERT(proto->isFunction());
|
||||
JS_ASSERT(JS_ON_TRACE(cx));
|
||||
|
||||
JSFunction *fun = (JSFunction*) funobj;
|
||||
JS_ASSERT(funobj->getFunctionPrivate() == fun);
|
||||
|
||||
types::TypeObject *type = proto->getNewType(cx);
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
JSObject* closure = js_NewGCObject(cx, gc::FINALIZE_OBJECT2);
|
||||
if (!closure)
|
||||
return NULL;
|
||||
|
||||
if (!closure->initSharingEmptyShape(cx, &FunctionClass, type, parent,
|
||||
fun, gc::FINALIZE_OBJECT2)) {
|
||||
return NULL;
|
||||
}
|
||||
return closure;
|
||||
}
|
||||
JS_DEFINE_CALLINFO_4(extern, OBJECT, js_NewNullClosure, CONTEXT, OBJECT, OBJECT, OBJECT,
|
||||
0, ACCSET_STORE_ANY)
|
||||
|
@ -1,653 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
|
||||
* May 28, 2008.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Orendorff <jorendorff@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef jsbuiltins_h___
|
||||
#define jsbuiltins_h___
|
||||
|
||||
#ifdef JS_TRACER
|
||||
|
||||
// nanojit.h includes windows.h, so undo the obnoxious #defines, if needed
|
||||
#include "nanojit/nanojit.h"
|
||||
#include "jswin.h"
|
||||
#include "jsprvtd.h"
|
||||
|
||||
enum JSTNErrType { INFALLIBLE, FAIL_STATUS, FAIL_NULL, FAIL_NEG, FAIL_NEITHER };
|
||||
enum {
|
||||
JSTN_ERRTYPE_MASK = 0x07,
|
||||
JSTN_UNBOX_AFTER = 0x08,
|
||||
JSTN_MORE = 0x10,
|
||||
JSTN_CONSTRUCTOR = 0x20,
|
||||
JSTN_RETURN_NULLABLE_STR = 0x40,
|
||||
JSTN_RETURN_NULLABLE_OBJ = 0x80
|
||||
};
|
||||
|
||||
#define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK)
|
||||
|
||||
/*
|
||||
* Type describing a type specialization of a js::Native.
|
||||
*
|
||||
* |prefix| and |argtypes| declare what arguments should be passed to the
|
||||
* native function. |prefix| can contain the following characters:
|
||||
*
|
||||
* 'C': a JSContext* argument
|
||||
* 'T': |this| as a JSObject* argument (bails if |this| is not an object)
|
||||
* 'S': |this| as a JSString* argument (bails if |this| is not a string)
|
||||
* 'R': a JSRuntime* argument
|
||||
* 'P': the pc as a jsbytecode*
|
||||
* 'D': |this| as a number (jsdouble)
|
||||
* 'f': the function being called, as a JSObject*
|
||||
* 'p': the .prototype of the function, as a JSObject*
|
||||
*
|
||||
* The corresponding things will get passed as arguments to the builtin in
|
||||
* reverse order (so TC means JSContext* as the first arg, and the
|
||||
* JSObject* for |this| as the second arg).
|
||||
*
|
||||
* |argtypes| can contain the following characters:
|
||||
* 'd': a number (double) argument
|
||||
* 'i': an integer argument
|
||||
* 's': a JSString* argument
|
||||
* 'o': a JSObject* argument
|
||||
* 'r': a JSObject* argument that is of class RegExpClass
|
||||
* 'f': a JSObject* argument that is of class FunctionClass
|
||||
* 'v': a value argument: on 32-bit, a Value*, on 64-bit, a jsval
|
||||
*/
|
||||
struct JSSpecializedNative {
|
||||
const nanojit::CallInfo *builtin;
|
||||
const char *prefix;
|
||||
const char *argtypes;
|
||||
uintN flags; /* JSTNErrType | JSTN_UNBOX_AFTER | JSTN_MORE |
|
||||
JSTN_CONSTRUCTOR */
|
||||
};
|
||||
|
||||
/*
|
||||
* Type holding extra trace-specific information about a fast native.
|
||||
*
|
||||
* 'specializations' points to a static array of available specializations
|
||||
* terminated by the lack of having the JSTN_MORE flag set.
|
||||
*/
|
||||
struct JSNativeTraceInfo {
|
||||
js::Native native;
|
||||
JSSpecializedNative *specializations;
|
||||
};
|
||||
|
||||
/* Macros used by JS_DEFINE_CALLINFOn. */
|
||||
#ifdef DEBUG
|
||||
#define _JS_CI_NAME(op) ,#op
|
||||
#else
|
||||
#define _JS_CI_NAME(op)
|
||||
#endif
|
||||
|
||||
#define _JS_I32_ARGTYPE nanojit::ARGTYPE_I
|
||||
#define _JS_I32_RETTYPE nanojit::ARGTYPE_I
|
||||
#define _JS_U64_ARGTYPE nanojit::ARGTYPE_Q
|
||||
#define _JS_U64_RETTYPE nanojit::ARGTYPE_Q
|
||||
#define _JS_F64_ARGTYPE nanojit::ARGTYPE_D
|
||||
#define _JS_F64_RETTYPE nanojit::ARGTYPE_D
|
||||
#define _JS_PTR_ARGTYPE nanojit::ARGTYPE_P
|
||||
#define _JS_PTR_RETTYPE nanojit::ARGTYPE_P
|
||||
|
||||
struct ClosureVarInfo;
|
||||
|
||||
/*
|
||||
* Supported types for builtin functions.
|
||||
*
|
||||
* Types with -- for the two string fields are not permitted as argument types
|
||||
* in JS_DEFINE_TRCINFO.
|
||||
*
|
||||
* There are three kinds of traceable-native error handling.
|
||||
*
|
||||
* - If a traceable native's return type ends with _FAIL, it always runs to
|
||||
* completion. It can either succeed or fail with an error or exception;
|
||||
* on success, it may or may not stay on trace. There may be side effects
|
||||
* in any case. If the call succeeds but bails off trace, we resume in the
|
||||
* interpreter at the next opcode.
|
||||
*
|
||||
* _FAIL builtins indicate failure or bailing off trace by setting bits in
|
||||
* cx->interpState->builtinStatus.
|
||||
*
|
||||
* - If a traceable native's return type contains _RETRY, it can either
|
||||
* succeed, fail with a JS exception, or tell the caller to bail off trace
|
||||
* and retry the call from the interpreter. The last case happens if the
|
||||
* builtin discovers that it can't do its job without examining the JS
|
||||
* stack, reentering the interpreter, accessing properties of the global
|
||||
* object, etc.
|
||||
*
|
||||
* The builtin must detect the need to retry before committing any side
|
||||
* effects. If a builtin can't do this, it must use a _FAIL return type
|
||||
* instead of _RETRY.
|
||||
*
|
||||
* _RETRY builtins indicate failure with a special return value that
|
||||
* depends on the return type:
|
||||
*
|
||||
* BOOL_RETRY: JS_NEITHER
|
||||
* INT32_RETRY: any negative value
|
||||
* STRING_RETRY: NULL
|
||||
* OBJECT_RETRY_NULL: NULL
|
||||
*
|
||||
* _RETRY function calls are faster than _FAIL calls. Each _RETRY call
|
||||
* saves two writes to tm->bailExit and a read from state->builtinStatus.
|
||||
*
|
||||
* - All other traceable natives are infallible (e.g. Date.now, Math.log).
|
||||
*
|
||||
* Special builtins known to the tracer can have their own idiosyncratic
|
||||
* error codes.
|
||||
*
|
||||
* When a traceable native returns a value indicating failure, we fall off
|
||||
* trace. If an exception is pending, it is thrown; otherwise, we assume the
|
||||
* builtin had no side effects and retry the current bytecode in the
|
||||
* interpreter.
|
||||
*
|
||||
* So a builtin must not return a value indicating failure after causing side
|
||||
* effects (such as reporting an error), without setting an exception pending.
|
||||
* The operation would be retried, despite the first attempt's observable
|
||||
* effects.
|
||||
*/
|
||||
#define _JS_CTYPE(ctype, size, pch, ach, flags) (ctype, size, pch, ach, flags)
|
||||
|
||||
#define _JS_CTYPE_CONTEXT _JS_CTYPE(JSContext *, _JS_PTR,"C", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_RUNTIME _JS_CTYPE(JSRuntime *, _JS_PTR,"R", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_MATHCACHE _JS_CTYPE(js::MathCache *, _JS_PTR,"M", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_THIS _JS_CTYPE(JSObject *, _JS_PTR,"T", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_THIS_DOUBLE _JS_CTYPE(jsdouble, _JS_F64,"D", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_THIS_STRING _JS_CTYPE(JSString *, _JS_PTR,"S", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_CALLEE _JS_CTYPE(JSObject *, _JS_PTR,"f", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_CALLEE_PROTOTYPE _JS_CTYPE(JSObject *, _JS_PTR,"p", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_FUNCTION _JS_CTYPE(JSFunction *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_PC _JS_CTYPE(jsbytecode *, _JS_PTR,"P", "", INFALLIBLE)
|
||||
#define _JS_CTYPE_VALUEPTR _JS_CTYPE(js::Value *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CVALUEPTR _JS_CTYPE(const js::Value *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_JSID _JS_CTYPE(jsid, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_JSVAL _JS_CTYPE(js::Value, _JS_U64, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_BOOL _JS_CTYPE(JSBool, _JS_I32, "","i", INFALLIBLE)
|
||||
#define _JS_CTYPE_BOOL_RETRY _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_NEITHER)
|
||||
#define _JS_CTYPE_BOOL_FAIL _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_STATUS)
|
||||
#define _JS_CTYPE_BOOLPTR _JS_CTYPE(JSBool *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_INT32 _JS_CTYPE(int32, _JS_I32, "","i", INFALLIBLE)
|
||||
#define _JS_CTYPE_INT32_RETRY _JS_CTYPE(int32, _JS_I32, --, --, FAIL_NEG)
|
||||
#define _JS_CTYPE_INT32_FAIL _JS_CTYPE(int32, _JS_I32, --, --, FAIL_STATUS)
|
||||
#define _JS_CTYPE_INT32PTR _JS_CTYPE(int32 *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_UINT32 _JS_CTYPE(uint32, _JS_I32, "","i", INFALLIBLE)
|
||||
#define _JS_CTYPE_UINT32_RETRY _JS_CTYPE(uint32, _JS_I32, --, --, FAIL_NEG)
|
||||
#define _JS_CTYPE_UINT32_FAIL _JS_CTYPE(uint32, _JS_I32, --, --, FAIL_STATUS)
|
||||
#define _JS_CTYPE_DOUBLE _JS_CTYPE(jsdouble, _JS_F64, "","d", INFALLIBLE)
|
||||
#define _JS_CTYPE_DOUBLE_FAIL _JS_CTYPE(jsdouble, _JS_F64, --, --, FAIL_STATUS)
|
||||
#define _JS_CTYPE_STRING _JS_CTYPE(JSString *, _JS_PTR, "","s", INFALLIBLE)
|
||||
#define _JS_CTYPE_STRING_RETRY _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_NULL)
|
||||
#define _JS_CTYPE_STRING_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS)
|
||||
#define _JS_CTYPE_STRING_OR_NULL_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS | \
|
||||
JSTN_RETURN_NULLABLE_STR)
|
||||
#define _JS_CTYPE_STRINGPTR _JS_CTYPE(JSString **, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_OBJECT _JS_CTYPE(JSObject *, _JS_PTR, "","o", INFALLIBLE)
|
||||
#define _JS_CTYPE_OBJECT_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL)
|
||||
#define _JS_CTYPE_OBJECT_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS)
|
||||
#define _JS_CTYPE_OBJECT_OR_NULL_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS | \
|
||||
JSTN_RETURN_NULLABLE_OBJ)
|
||||
#define _JS_CTYPE_OBJECTPTR _JS_CTYPE(JSObject **, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CONSTRUCTOR_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL | \
|
||||
JSTN_CONSTRUCTOR)
|
||||
#define _JS_CTYPE_REGEXP _JS_CTYPE(JSObject *, _JS_PTR, "","r", INFALLIBLE)
|
||||
#define _JS_CTYPE_SHAPE _JS_CTYPE(js::Shape *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_TRACERSTATE _JS_CTYPE(TracerState *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_FRAGMENT _JS_CTYPE(nanojit::Fragment *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CLASS _JS_CTYPE(js::Class *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_DOUBLEPTR _JS_CTYPE(double *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CHARPTR _JS_CTYPE(char *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CVIPTR _JS_CTYPE(const ClosureVarInfo *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_FRAMEINFO _JS_CTYPE(FrameInfo *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_UINTN _JS_CTYPE(uintN, _JS_PTR, --, --, INFALLIBLE)
|
||||
|
||||
/*
|
||||
* The "VALUE" type is used to indicate that a native takes a js::Value
|
||||
* parameter by value. Unfortunately, for technical reasons, we can't simply
|
||||
* have the parameter type be js::Value. Furthermore, the right thing to pass
|
||||
* differs based on word size. Thus, a native that declares a parameter of type
|
||||
* VALUE should have the corresponding argument type be:
|
||||
* - on 32-bit: const Value*
|
||||
* - on 64-bit: jsval (which is a uint64)
|
||||
*
|
||||
* To write code that just does the right thing, use the pattern:
|
||||
* void foo(js::ValueArgType arg) {
|
||||
* const js::Value &v = js::ValueArgToConstRef(arg);
|
||||
*/
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
# define _JS_CTYPE_VALUE _JS_CTYPE(js::ValueArgType, _JS_PTR, "","v", INFALLIBLE)
|
||||
#elif JS_BITS_PER_WORD == 64
|
||||
# define _JS_CTYPE_VALUE _JS_CTYPE(js::ValueArgType, _JS_U64, "","v", INFALLIBLE)
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
typedef const js::Value *ValueArgType;
|
||||
|
||||
static JS_ALWAYS_INLINE const js::Value &
|
||||
ValueArgToConstRef(const js::Value *arg)
|
||||
{
|
||||
return *arg;
|
||||
}
|
||||
#elif JS_BITS_PER_WORD == 64
|
||||
typedef js::Value ValueArgType;
|
||||
|
||||
static JS_ALWAYS_INLINE const Value &
|
||||
ValueArgToConstRef(const Value &v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
} /* namespace js */
|
||||
|
||||
#define _JS_EXPAND(tokens) tokens
|
||||
|
||||
#define _JS_CTYPE_TYPE2(t,s,p,a,f) t
|
||||
#define _JS_CTYPE_TYPE(tyname) _JS_EXPAND(_JS_CTYPE_TYPE2 _JS_CTYPE_##tyname)
|
||||
#define _JS_CTYPE_RETTYPE2(t,s,p,a,f) s##_RETTYPE
|
||||
#define _JS_CTYPE_RETTYPE(tyname) _JS_EXPAND(_JS_CTYPE_RETTYPE2 _JS_CTYPE_##tyname)
|
||||
#define _JS_CTYPE_ARGTYPE2(t,s,p,a,f) s##_ARGTYPE
|
||||
#define _JS_CTYPE_ARGTYPE(tyname) _JS_EXPAND(_JS_CTYPE_ARGTYPE2 _JS_CTYPE_##tyname)
|
||||
#define _JS_CTYPE_PCH2(t,s,p,a,f) p
|
||||
#define _JS_CTYPE_PCH(tyname) _JS_EXPAND(_JS_CTYPE_PCH2 _JS_CTYPE_##tyname)
|
||||
#define _JS_CTYPE_ACH2(t,s,p,a,f) a
|
||||
#define _JS_CTYPE_ACH(tyname) _JS_EXPAND(_JS_CTYPE_ACH2 _JS_CTYPE_##tyname)
|
||||
#define _JS_CTYPE_FLAGS2(t,s,p,a,f) f
|
||||
#define _JS_CTYPE_FLAGS(tyname) _JS_EXPAND(_JS_CTYPE_FLAGS2 _JS_CTYPE_##tyname)
|
||||
|
||||
#define _JS_static_TN(t) static t
|
||||
#define _JS_static_CI static
|
||||
#define _JS_extern_TN(t) extern t
|
||||
#define _JS_extern_CI
|
||||
#define _JS_FRIEND_TN(t) extern JS_FRIEND_API(t)
|
||||
#define _JS_FRIEND_CI
|
||||
#define _JS_TN_LINKAGE(linkage, t) _JS_##linkage##_TN(t)
|
||||
#define _JS_CI_LINKAGE(linkage) _JS_##linkage##_CI
|
||||
|
||||
#define _JS_CALLINFO(name) name##_ci
|
||||
|
||||
#if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32)
|
||||
#define _JS_DEFINE_CALLINFO(linkage, name, crtype, cargtypes, argtypes, isPure, storeAccSet) \
|
||||
_JS_TN_LINKAGE(linkage, crtype) name cargtypes; \
|
||||
_JS_CI_LINKAGE(linkage) const nanojit::CallInfo _JS_CALLINFO(name) = \
|
||||
{ (intptr_t) &name, argtypes, nanojit::ABI_CDECL, isPure, storeAccSet _JS_CI_NAME(name) };\
|
||||
JS_STATIC_ASSERT_IF(isPure, (storeAccSet) == nanojit::ACCSET_NONE);
|
||||
|
||||
#else
|
||||
#define _JS_DEFINE_CALLINFO(linkage, name, crtype, cargtypes, argtypes, isPure, storeAccSet) \
|
||||
_JS_TN_LINKAGE(linkage, crtype) FASTCALL name cargtypes; \
|
||||
_JS_CI_LINKAGE(linkage) const nanojit::CallInfo _JS_CALLINFO(name) = \
|
||||
{ (uintptr_t) &name, argtypes, nanojit::ABI_FASTCALL, isPure, storeAccSet _JS_CI_NAME(name) }; \
|
||||
JS_STATIC_ASSERT_IF(isPure, (storeAccSet) == nanojit::ACCSET_NONE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This macro is used for builtin functions that can be called from JITted
|
||||
* code. It declares a C function named <op> and a CallInfo struct named
|
||||
* <op>_ci so the tracer can call it. The <N> in JS_DEFINE_CALLINFO_<N> is
|
||||
* the number of arguments the builtin takes. Builtins with no arguments
|
||||
* are not supported. Using a macro is clunky but ensures that the types
|
||||
* for each C function matches those for the corresponding CallInfo struct;
|
||||
* mismatched types can cause subtle problems.
|
||||
*
|
||||
* The macro arguments are:
|
||||
*
|
||||
* - The linkage for the function and the associated CallInfo global. It
|
||||
* can be extern, static, or FRIEND, which specifies JS_FRIEND_API linkage
|
||||
* for the function.
|
||||
*
|
||||
* - The return type. This identifier must name one of the _JS_TYPEINFO_*
|
||||
* macros defined in jsbuiltins.h.
|
||||
*
|
||||
* - The builtin name.
|
||||
*
|
||||
* - The parameter types.
|
||||
*
|
||||
* - The isPure flag. Set to 1 if:
|
||||
* (a) the function's return value is determined solely by its arguments
|
||||
* (ie. no hidden state, no implicit inputs used such as global
|
||||
* variables or the result of an I/O operation); and
|
||||
* (b) the function causes no observable side-effects (ie. no writes to
|
||||
* global variables, no I/O output).
|
||||
* Multiple calls to a pure function can be merged during CSE.
|
||||
*
|
||||
* - The storeAccSet. This indicates which memory access regions the function
|
||||
* accesses. It must be ACCSET_NONE if the function is pure; use
|
||||
* ACCSET_STORE_ANY if you're not sure. Used to determine if each call site
|
||||
* of the function aliases any loads.
|
||||
*/
|
||||
#define JS_DEFINE_CALLINFO_1(linkage, rt, op, at0, isPure, storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0)), \
|
||||
nanojit::CallInfo::typeSig1(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0)), \
|
||||
isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_2(linkage, rt, op, at0, at1, isPure, storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0), \
|
||||
_JS_CTYPE_TYPE(at1)), \
|
||||
nanojit::CallInfo::typeSig2(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0), \
|
||||
_JS_CTYPE_ARGTYPE(at1)), \
|
||||
isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_3(linkage, rt, op, at0, at1, at2, isPure, storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0), \
|
||||
_JS_CTYPE_TYPE(at1), \
|
||||
_JS_CTYPE_TYPE(at2)), \
|
||||
nanojit::CallInfo::typeSig3(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0), \
|
||||
_JS_CTYPE_ARGTYPE(at1), \
|
||||
_JS_CTYPE_ARGTYPE(at2)), \
|
||||
isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_4(linkage, rt, op, at0, at1, at2, at3, isPure, storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0), \
|
||||
_JS_CTYPE_TYPE(at1), \
|
||||
_JS_CTYPE_TYPE(at2), \
|
||||
_JS_CTYPE_TYPE(at3)), \
|
||||
nanojit::CallInfo::typeSig4(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0), \
|
||||
_JS_CTYPE_ARGTYPE(at1), \
|
||||
_JS_CTYPE_ARGTYPE(at2), \
|
||||
_JS_CTYPE_ARGTYPE(at3)), \
|
||||
isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_5(linkage, rt, op, at0, at1, at2, at3, at4, isPure, storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0), \
|
||||
_JS_CTYPE_TYPE(at1), \
|
||||
_JS_CTYPE_TYPE(at2), \
|
||||
_JS_CTYPE_TYPE(at3), \
|
||||
_JS_CTYPE_TYPE(at4)), \
|
||||
nanojit::CallInfo::typeSig5(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0), \
|
||||
_JS_CTYPE_ARGTYPE(at1), \
|
||||
_JS_CTYPE_ARGTYPE(at2), \
|
||||
_JS_CTYPE_ARGTYPE(at3), \
|
||||
_JS_CTYPE_ARGTYPE(at4)), \
|
||||
isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, isPure, storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0), \
|
||||
_JS_CTYPE_TYPE(at1), \
|
||||
_JS_CTYPE_TYPE(at2), \
|
||||
_JS_CTYPE_TYPE(at3), \
|
||||
_JS_CTYPE_TYPE(at4), \
|
||||
_JS_CTYPE_TYPE(at5)), \
|
||||
nanojit::CallInfo::typeSig6(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0), \
|
||||
_JS_CTYPE_ARGTYPE(at1), \
|
||||
_JS_CTYPE_ARGTYPE(at2), \
|
||||
_JS_CTYPE_ARGTYPE(at3), \
|
||||
_JS_CTYPE_ARGTYPE(at4), \
|
||||
_JS_CTYPE_ARGTYPE(at5)), \
|
||||
isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_7(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, isPure, \
|
||||
storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0), \
|
||||
_JS_CTYPE_TYPE(at1), \
|
||||
_JS_CTYPE_TYPE(at2), \
|
||||
_JS_CTYPE_TYPE(at3), \
|
||||
_JS_CTYPE_TYPE(at4), \
|
||||
_JS_CTYPE_TYPE(at5), \
|
||||
_JS_CTYPE_TYPE(at6)), \
|
||||
nanojit::CallInfo::typeSig7(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0), \
|
||||
_JS_CTYPE_ARGTYPE(at1), \
|
||||
_JS_CTYPE_ARGTYPE(at2), \
|
||||
_JS_CTYPE_ARGTYPE(at3), \
|
||||
_JS_CTYPE_ARGTYPE(at4), \
|
||||
_JS_CTYPE_ARGTYPE(at5), \
|
||||
_JS_CTYPE_ARGTYPE(at6)), \
|
||||
isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_8(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, at7, isPure, \
|
||||
storeAccSet) \
|
||||
_JS_DEFINE_CALLINFO(linkage, op, \
|
||||
_JS_CTYPE_TYPE(rt), \
|
||||
(_JS_CTYPE_TYPE(at0), \
|
||||
_JS_CTYPE_TYPE(at1), \
|
||||
_JS_CTYPE_TYPE(at2), \
|
||||
_JS_CTYPE_TYPE(at3), \
|
||||
_JS_CTYPE_TYPE(at4), \
|
||||
_JS_CTYPE_TYPE(at5), \
|
||||
_JS_CTYPE_TYPE(at6), \
|
||||
_JS_CTYPE_TYPE(at7)), \
|
||||
nanojit::CallInfo::typeSig8(_JS_CTYPE_RETTYPE(rt), \
|
||||
_JS_CTYPE_ARGTYPE(at0), \
|
||||
_JS_CTYPE_ARGTYPE(at1), \
|
||||
_JS_CTYPE_ARGTYPE(at2), \
|
||||
_JS_CTYPE_ARGTYPE(at3), \
|
||||
_JS_CTYPE_ARGTYPE(at4), \
|
||||
_JS_CTYPE_ARGTYPE(at5), \
|
||||
_JS_CTYPE_ARGTYPE(at6), \
|
||||
_JS_CTYPE_ARGTYPE(at7)), \
|
||||
isPure, storeAccSet)
|
||||
|
||||
#define JS_DECLARE_CALLINFO(name) extern const nanojit::CallInfo _JS_CALLINFO(name);
|
||||
|
||||
#define _JS_TN_INIT_HELPER_n(n, args) _JS_TN_INIT_HELPER_##n args
|
||||
|
||||
#define _JS_TN_INIT_HELPER_1(linkage, rt, op, at0, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define _JS_TN_INIT_HELPER_2(linkage, rt, op, at0, at1, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define _JS_TN_INIT_HELPER_3(linkage, rt, op, at0, at1, at2, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define _JS_TN_INIT_HELPER_4(linkage, rt, op, at0, at1, at2, at3, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define _JS_TN_INIT_HELPER_5(linkage, rt, op, at0, at1, at2, at3, at4, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) \
|
||||
_JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) \
|
||||
_JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define _JS_TN_INIT_HELPER_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at5) _JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) \
|
||||
_JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at5) _JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) \
|
||||
_JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define _JS_TN_INIT_HELPER_7(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at6) _JS_CTYPE_PCH(at5) _JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) \
|
||||
_JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at6) _JS_CTYPE_ACH(at5) _JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) \
|
||||
_JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define _JS_TN_INIT_HELPER_8(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, at7, isPure, storeAccSet) \
|
||||
&_JS_CALLINFO(op), \
|
||||
_JS_CTYPE_PCH(at7) _JS_CTYPE_PCH(at6) _JS_CTYPE_PCH(at5) _JS_CTYPE_PCH(at4) \
|
||||
_JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \
|
||||
_JS_CTYPE_ACH(at7) _JS_CTYPE_ACH(at6) _JS_CTYPE_ACH(at5) _JS_CTYPE_ACH(at4) \
|
||||
_JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \
|
||||
_JS_CTYPE_FLAGS(rt)
|
||||
|
||||
#define JS_DEFINE_TRCINFO_1(name, tn0) \
|
||||
_JS_DEFINE_CALLINFO_n tn0 \
|
||||
JSSpecializedNative name##_sns[] = { \
|
||||
{ _JS_TN_INIT_HELPER_n tn0 } \
|
||||
}; \
|
||||
JSNativeTraceInfo name##_trcinfo = { name, name##_sns };
|
||||
|
||||
#define JS_DEFINE_TRCINFO_2(name, tn0, tn1) \
|
||||
_JS_DEFINE_CALLINFO_n tn0 \
|
||||
_JS_DEFINE_CALLINFO_n tn1 \
|
||||
JSSpecializedNative name##_sns[] = { \
|
||||
{ _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \
|
||||
{ _JS_TN_INIT_HELPER_n tn1 } \
|
||||
}; \
|
||||
JSNativeTraceInfo name##_trcinfo = { name, name##_sns };
|
||||
|
||||
#define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2) \
|
||||
_JS_DEFINE_CALLINFO_n tn0 \
|
||||
_JS_DEFINE_CALLINFO_n tn1 \
|
||||
_JS_DEFINE_CALLINFO_n tn2 \
|
||||
JSSpecializedNative name##_sns[] = { \
|
||||
{ _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \
|
||||
{ _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \
|
||||
{ _JS_TN_INIT_HELPER_n tn2 } \
|
||||
}; \
|
||||
JSNativeTraceInfo name##_trcinfo = { name, name##_sns };
|
||||
|
||||
#define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3) \
|
||||
_JS_DEFINE_CALLINFO_n tn0 \
|
||||
_JS_DEFINE_CALLINFO_n tn1 \
|
||||
_JS_DEFINE_CALLINFO_n tn2 \
|
||||
_JS_DEFINE_CALLINFO_n tn3 \
|
||||
JSSpecializedNative name##_sns[] = { \
|
||||
{ _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \
|
||||
{ _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \
|
||||
{ _JS_TN_INIT_HELPER_n tn2 | JSTN_MORE }, \
|
||||
{ _JS_TN_INIT_HELPER_n tn3 } \
|
||||
}; \
|
||||
JSNativeTraceInfo name##_trcinfo = { name, name##_sns };
|
||||
|
||||
#define _JS_DEFINE_CALLINFO_n(n, args) JS_DEFINE_CALLINFO_##n args
|
||||
|
||||
jsdouble FASTCALL
|
||||
js_StringToNumber(JSContext* cx, JSString* str, JSBool *ok);
|
||||
|
||||
/* Extern version of SetBuiltinError. */
|
||||
extern JS_FRIEND_API(void)
|
||||
js_SetTraceableNativeFailed(JSContext *cx);
|
||||
|
||||
extern jsdouble FASTCALL
|
||||
js_dmod(jsdouble a, jsdouble b);
|
||||
|
||||
#else
|
||||
|
||||
#define JS_DEFINE_CALLINFO_1(linkage, rt, op, at0, isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_2(linkage, rt, op, at0, at1, isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_3(linkage, rt, op, at0, at1, at2, isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_4(linkage, rt, op, at0, at1, at2, at3, isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_5(linkage, rt, op, at0, at1, at2, at3, at4, isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_7(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, isPure, storeAccSet)
|
||||
#define JS_DEFINE_CALLINFO_8(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, at7, isPure, storeAccSet)
|
||||
#define JS_DECLARE_CALLINFO(name)
|
||||
#define JS_DEFINE_TRCINFO_1(name, tn0)
|
||||
#define JS_DEFINE_TRCINFO_2(name, tn0, tn1)
|
||||
#define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2)
|
||||
#define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3)
|
||||
|
||||
#endif /* !JS_TRACER */
|
||||
|
||||
/* Defined in jsarray.cpp. */
|
||||
namespace js {
|
||||
JS_DECLARE_CALLINFO(NewDenseEmptyArray)
|
||||
JS_DECLARE_CALLINFO(NewDenseAllocatedArray)
|
||||
JS_DECLARE_CALLINFO(NewDenseUnallocatedArray)
|
||||
JS_DECLARE_CALLINFO(NewDenseAllocatedEmptyArray)
|
||||
}
|
||||
JS_DECLARE_CALLINFO(js_NewbornArrayPush_tn)
|
||||
JS_DECLARE_CALLINFO(js_EnsureDenseArrayCapacity)
|
||||
|
||||
/* Defined in jsbuiltins.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_UnboxNumberAsDouble)
|
||||
JS_DECLARE_CALLINFO(js_UnboxNumberAsInt32)
|
||||
JS_DECLARE_CALLINFO(js_dmod)
|
||||
JS_DECLARE_CALLINFO(js_imod)
|
||||
JS_DECLARE_CALLINFO(js_DoubleToInt32)
|
||||
JS_DECLARE_CALLINFO(js_DoubleToUint32)
|
||||
JS_DECLARE_CALLINFO(js_StringToNumber)
|
||||
JS_DECLARE_CALLINFO(js_StringToInt32)
|
||||
JS_DECLARE_CALLINFO(js_AddProperty)
|
||||
JS_DECLARE_CALLINFO(js_AddAtomProperty)
|
||||
JS_DECLARE_CALLINFO(js_HasNamedProperty)
|
||||
JS_DECLARE_CALLINFO(js_HasNamedPropertyInt32)
|
||||
JS_DECLARE_CALLINFO(js_TypeOfObject)
|
||||
JS_DECLARE_CALLINFO(js_BooleanIntToString)
|
||||
JS_DECLARE_CALLINFO(js_NewNullClosure)
|
||||
|
||||
/* Defined in jsfun.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_AllocFlatClosure)
|
||||
JS_DECLARE_CALLINFO(js_PutArgumentsOnTrace)
|
||||
JS_DECLARE_CALLINFO(js_PutCallObjectOnTrace)
|
||||
JS_DECLARE_CALLINFO(js_SetCallVar)
|
||||
JS_DECLARE_CALLINFO(js_SetCallArg)
|
||||
JS_DECLARE_CALLINFO(js_CloneFunctionObject)
|
||||
JS_DECLARE_CALLINFO(js_CreateCallObjectOnTrace)
|
||||
JS_DECLARE_CALLINFO(js_NewArgumentsOnTrace)
|
||||
|
||||
/* Defined in jsnum.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_NumberToString)
|
||||
|
||||
/* Defined in jsobj.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_Object_tn)
|
||||
JS_DECLARE_CALLINFO(js_CreateThisFromTrace)
|
||||
JS_DECLARE_CALLINFO(js_InitializerObject)
|
||||
|
||||
/* Defined in vm/RegExpObject.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_CloneRegExpObject)
|
||||
|
||||
/* Defined in jsstr.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_String_tn)
|
||||
JS_DECLARE_CALLINFO(js_CompareStringsOnTrace)
|
||||
JS_DECLARE_CALLINFO(js_ConcatStrings)
|
||||
JS_DECLARE_CALLINFO(js_EqualStringsOnTrace)
|
||||
JS_DECLARE_CALLINFO(js_FlattenOnTrace)
|
||||
|
||||
/* Defined in jstypedarray.cpp. */
|
||||
JS_DECLARE_CALLINFO(js_TypedArray_uint8_clamp_double)
|
||||
|
||||
#endif /* jsbuiltins_h___ */
|
@ -80,7 +80,6 @@
|
||||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstracer.h"
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
# include "assembler/assembler/MacroAssembler.h"
|
||||
@ -104,12 +103,6 @@ ThreadData::ThreadData(JSRuntime *rt)
|
||||
interruptFlags(0),
|
||||
#ifdef JS_THREADSAFE
|
||||
requestDepth(0),
|
||||
#endif
|
||||
#ifdef JS_TRACER
|
||||
onTraceCompartment(NULL),
|
||||
recordingCompartment(NULL),
|
||||
profilingCompartment(NULL),
|
||||
maxCodeCacheBytes(DEFAULT_JIT_CACHE_SIZE),
|
||||
#endif
|
||||
waiveGCQuota(false),
|
||||
tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
@ -220,13 +213,6 @@ ThreadData::purgeRegExpPrivateCache()
|
||||
JSScript *
|
||||
js_GetCurrentScript(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_TRACER
|
||||
VOUCH_DOES_NOT_REQUIRE_STACK();
|
||||
if (JS_ON_TRACE(cx)) {
|
||||
VMSideExit *bailExit = JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit;
|
||||
return bailExit ? bailExit->script : NULL;
|
||||
}
|
||||
#endif
|
||||
return cx->hasfp() ? cx->fp()->maybeScript() : NULL;
|
||||
}
|
||||
|
||||
@ -749,15 +735,6 @@ PopulateReportBlame(JSContext *cx, JSErrorReport *report)
|
||||
void
|
||||
js_ReportOutOfMemory(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_TRACER
|
||||
/*
|
||||
* If we are in a builtin called directly from trace, don't report an
|
||||
* error. We will retry in the interpreter instead.
|
||||
*/
|
||||
if (JS_ON_TRACE(cx) && !JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit)
|
||||
return;
|
||||
#endif
|
||||
|
||||
cx->runtime->hadOutOfMemory = true;
|
||||
|
||||
JSErrorReport report;
|
||||
@ -1347,41 +1324,7 @@ js_GetScriptedCaller(JSContext *cx, StackFrame *fp)
|
||||
jsbytecode*
|
||||
js_GetCurrentBytecodePC(JSContext* cx)
|
||||
{
|
||||
jsbytecode *pc, *imacpc;
|
||||
|
||||
#ifdef JS_TRACER
|
||||
if (JS_ON_TRACE(cx)) {
|
||||
pc = JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit->pc;
|
||||
imacpc = JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit->imacpc;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
JS_ASSERT_NOT_ON_TRACE(cx); /* for static analysis */
|
||||
pc = cx->hasfp() ? cx->regs().pc : NULL;
|
||||
if (!pc)
|
||||
return NULL;
|
||||
imacpc = cx->fp()->maybeImacropc();
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are inside GetProperty_tn or similar, return a pointer to the
|
||||
* current instruction in the script, not the CALL instruction in the
|
||||
* imacro, for the benefit of callers doing bytecode inspection.
|
||||
*/
|
||||
return (*pc == JSOP_CALL && imacpc) ? imacpc : pc;
|
||||
}
|
||||
|
||||
bool
|
||||
js_CurrentPCIsInImacro(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_TRACER
|
||||
VOUCH_DOES_NOT_REQUIRE_STACK();
|
||||
if (JS_ON_TRACE(cx))
|
||||
return JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit->imacpc != NULL;
|
||||
return cx->fp()->hasImacropc();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return cx->hasfp() ? cx->regs().pc : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1449,12 +1392,8 @@ JSContext::JSContext(JSRuntime *rt)
|
||||
resolveFlags(0),
|
||||
rngSeed(0),
|
||||
iterValue(MagicValue(JS_NO_ITER_VALUE)),
|
||||
#ifdef JS_TRACER
|
||||
traceJitEnabled(false),
|
||||
#endif
|
||||
#ifdef JS_METHODJIT
|
||||
methodJitEnabled(false),
|
||||
profilingEnabled(false),
|
||||
#endif
|
||||
inferenceEnabled(false),
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
@ -1629,7 +1568,7 @@ JSContext::purge()
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(JS_TRACER) || defined(JS_METHODJIT)
|
||||
#if defined(JS_METHODJIT)
|
||||
static bool
|
||||
ComputeIsJITBroken()
|
||||
{
|
||||
@ -1705,15 +1644,6 @@ IsJITBrokenHere()
|
||||
void
|
||||
JSContext::updateJITEnabled()
|
||||
{
|
||||
#ifdef JS_TRACER
|
||||
traceJitEnabled = ((runOptions & JSOPTION_JIT) &&
|
||||
!IsJITBrokenHere() &&
|
||||
compartment &&
|
||||
!compartment->debugMode() &&
|
||||
(debugHooks == &js_NullDebugHooks ||
|
||||
(debugHooks == &runtime->globalDebugHooks &&
|
||||
!runtime->debuggerInhibitsJIT())));
|
||||
#endif
|
||||
#ifdef JS_METHODJIT
|
||||
methodJitEnabled = (runOptions & JSOPTION_METHODJIT) &&
|
||||
!IsJITBrokenHere()
|
||||
@ -1722,34 +1652,11 @@ JSContext::updateJITEnabled()
|
||||
JSC::MacroAssemblerX86Common::HasSSE2
|
||||
# endif
|
||||
;
|
||||
#ifdef JS_TRACER
|
||||
profilingEnabled = (runOptions & JSOPTION_PROFILING) && traceJitEnabled && methodJitEnabled;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
JS_FORCES_STACK JS_FRIEND_API(void)
|
||||
LeaveTrace(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_TRACER
|
||||
if (JS_ON_TRACE(cx))
|
||||
DeepBail(cx);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
CanLeaveTrace(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(JS_ON_TRACE(cx));
|
||||
#ifdef JS_TRACER
|
||||
return JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit != NULL;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
AutoEnumStateRooter::~AutoEnumStateRooter()
|
||||
{
|
||||
if (!stateValue.isNull()) {
|
||||
|
@ -70,18 +70,6 @@
|
||||
#pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
|
||||
#endif
|
||||
|
||||
/* Forward declarations of nanojit types. */
|
||||
namespace nanojit {
|
||||
|
||||
class Assembler;
|
||||
class CodeAlloc;
|
||||
class Fragment;
|
||||
template<typename K> struct DefaultHash;
|
||||
template<typename K, typename V, typename H> class HashMap;
|
||||
template<typename T> class Seq;
|
||||
|
||||
} /* namespace nanojit */
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
struct DtoaState;
|
||||
JS_END_EXTERN_C
|
||||
@ -94,35 +82,12 @@ struct JSSharpObjectMap {
|
||||
|
||||
namespace js {
|
||||
|
||||
/* Tracer constants. */
|
||||
static const size_t MONITOR_N_GLOBAL_STATES = 4;
|
||||
static const size_t FRAGMENT_TABLE_SIZE = 512;
|
||||
static const size_t MAX_GLOBAL_SLOTS = 4096;
|
||||
static const size_t GLOBAL_SLOTS_BUFFER_SIZE = MAX_GLOBAL_SLOTS + 1;
|
||||
|
||||
/* Forward declarations of tracer types. */
|
||||
class VMAllocator;
|
||||
class FrameInfoCache;
|
||||
struct FrameInfo;
|
||||
struct VMSideExit;
|
||||
struct TreeFragment;
|
||||
struct TracerState;
|
||||
template<typename T> class Queue;
|
||||
typedef Queue<uint16> SlotList;
|
||||
class TypeMap;
|
||||
class LoopProfile;
|
||||
class InterpreterFrames;
|
||||
|
||||
#if defined(JS_JIT_SPEW) || defined(DEBUG)
|
||||
struct FragPI;
|
||||
typedef nanojit::HashMap<uint32, FragPI, nanojit::DefaultHash<uint32> > FragStatsMap;
|
||||
#endif
|
||||
|
||||
namespace mjit {
|
||||
class JaegerCompartment;
|
||||
}
|
||||
|
||||
class WeakMapBase;
|
||||
class InterpreterFrames;
|
||||
|
||||
/*
|
||||
* GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
|
||||
@ -167,25 +132,6 @@ struct ThreadData {
|
||||
unsigned requestDepth;
|
||||
#endif
|
||||
|
||||
#ifdef JS_TRACER
|
||||
/*
|
||||
* During trace execution (or during trace recording or
|
||||
* profiling), these fields point to the compartment doing the
|
||||
* execution on this thread. At other times, they are NULL. If a
|
||||
* thread tries to execute/record/profile one trace while another
|
||||
* is still running, the initial one will abort. Therefore, we
|
||||
* only need to track one at a time.
|
||||
*/
|
||||
JSCompartment *onTraceCompartment;
|
||||
JSCompartment *recordingCompartment;
|
||||
JSCompartment *profilingCompartment;
|
||||
|
||||
/* Maximum size of the tracer's code cache before we start flushing. */
|
||||
uint32 maxCodeCacheBytes;
|
||||
|
||||
static const uint32 DEFAULT_JIT_CACHE_SIZE = 16 * 1024 * 1024;
|
||||
#endif
|
||||
|
||||
/* Keeper of the contiguous stack used by all contexts in this thread. */
|
||||
StackSpace stackSpace;
|
||||
|
||||
@ -615,14 +561,6 @@ struct JSRuntime
|
||||
/* Had an out-of-memory error which did not populate an exception. */
|
||||
JSBool hadOutOfMemory;
|
||||
|
||||
#ifdef JS_TRACER
|
||||
/* True if any debug hooks not supported by the JIT are enabled. */
|
||||
bool debuggerInhibitsJIT() const {
|
||||
return (globalDebugHooks.interruptHook ||
|
||||
globalDebugHooks.callHook);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Linked list of all js::Debugger objects. This may be accessed by the GC
|
||||
* thread, if any, or a thread that is in a request and holds gcLock.
|
||||
@ -1188,23 +1126,8 @@ struct JSContext
|
||||
/* Location to stash the iteration value between JSOP_MOREITER and JSOP_ITERNEXT. */
|
||||
js::Value iterValue;
|
||||
|
||||
#ifdef JS_TRACER
|
||||
/*
|
||||
* True if traces may be executed. Invariant: The value of traceJitenabled
|
||||
* is always equal to the expression in updateJITEnabled below.
|
||||
*
|
||||
* This flag and the fields accessed by updateJITEnabled are written only
|
||||
* in runtime->gcLock, to avoid race conditions that would leave the wrong
|
||||
* value in traceJitEnabled. (But the interpreter reads this without
|
||||
* locking. That can race against another thread setting debug hooks, but
|
||||
* we always read cx->debugHooks without locking anyway.)
|
||||
*/
|
||||
bool traceJitEnabled;
|
||||
#endif
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
bool methodJitEnabled;
|
||||
bool profilingEnabled;
|
||||
|
||||
inline js::mjit::JaegerCompartment *jaegerCompartment();
|
||||
#endif
|
||||
@ -2185,17 +2108,8 @@ js_GetCurrentBytecodePC(JSContext* cx);
|
||||
extern JSScript *
|
||||
js_GetCurrentScript(JSContext* cx);
|
||||
|
||||
extern bool
|
||||
js_CurrentPCIsInImacro(JSContext *cx);
|
||||
|
||||
namespace js {
|
||||
|
||||
extern JS_FORCES_STACK JS_FRIEND_API(void)
|
||||
LeaveTrace(JSContext *cx);
|
||||
|
||||
extern bool
|
||||
CanLeaveTrace(JSContext *cx);
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
namespace mjit {
|
||||
void ExpandInlineFrames(JSCompartment *compartment);
|
||||
|
@ -373,38 +373,10 @@ CallSetter(JSContext *cx, JSObject *obj, jsid id, StrictPropertyOp op, uintN att
|
||||
return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp);
|
||||
}
|
||||
|
||||
#ifdef JS_TRACER
|
||||
/*
|
||||
* Reconstruct the JS stack and clear cx->tracecx. We must be currently in a
|
||||
* _FAIL builtin from trace on cx or another context on the same thread. The
|
||||
* machine code for the trace remains on the C stack when js_DeepBail returns.
|
||||
*
|
||||
* Implemented in jstracer.cpp.
|
||||
*/
|
||||
JS_FORCES_STACK JS_FRIEND_API(void)
|
||||
DeepBail(JSContext *cx);
|
||||
#endif
|
||||
|
||||
static JS_INLINE void
|
||||
LeaveTraceIfGlobalObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
if (!obj->getParent())
|
||||
LeaveTrace(cx);
|
||||
}
|
||||
|
||||
static JS_INLINE void
|
||||
LeaveTraceIfArgumentsObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
if (obj->isArguments())
|
||||
LeaveTrace(cx);
|
||||
}
|
||||
|
||||
static inline JSAtom **
|
||||
FrameAtomBase(JSContext *cx, js::StackFrame *fp)
|
||||
{
|
||||
return fp->hasImacropc()
|
||||
? cx->runtime->atomState.commonAtomsStart()
|
||||
: fp->script()->atoms;
|
||||
return fp->script()->atoms;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
@ -525,14 +497,10 @@ JSContext::ensureParseMapPool()
|
||||
/*
|
||||
* Get the current frame, first lazily instantiating stack frames if needed.
|
||||
* (Do not access cx->fp() directly except in JS_REQUIRES_STACK code.)
|
||||
*
|
||||
* LeaveTrace is defined in jstracer.cpp if JS_TRACER is defined.
|
||||
*/
|
||||
static JS_FORCES_STACK JS_INLINE js::StackFrame *
|
||||
js_GetTopStackFrame(JSContext *cx, FrameExpandKind expand)
|
||||
{
|
||||
js::LeaveTrace(cx);
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
if (expand)
|
||||
js::mjit::ExpandInlineFrames(cx->compartment);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user