Merge from mozilla-central.

--HG--
rename : js/xpconnect/src/XPCThreadContext.cpp => js/xpconnect/src/XPCJSContextStack.cpp
This commit is contained in:
David Anderson 2012-06-22 14:26:15 -07:00
commit 2e039591ee
3415 changed files with 788056 additions and 2277 deletions

View File

@ -280,6 +280,9 @@ LogShellLoadType(nsIDocShell* aDocShell)
case LOAD_PUSHSTATE:
printf("load pushstate; ");
break;
case LOAD_REPLACE_BYPASS_CACHE:
printf("replace bypass cache; ");
break;
case LOAD_ERROR_PAGE:
printf("error page;");
break;

View File

@ -22,7 +22,7 @@ DirectoryProvider.prototype = {
getFile: function dp_getFile(prop, persistent) {
#ifdef MOZ_WIDGET_GONK
let localProps = ["cachePDir", "webappsDir", "PrefD"];
let localProps = ["cachePDir", "webappsDir", "PrefD", "indexedDBPDir"];
if (localProps.indexOf(prop) != -1) {
prop.persistent = true;
let file = Cc["@mozilla.org/file/local;1"]
@ -37,4 +37,3 @@ DirectoryProvider.prototype = {
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]);

View File

@ -584,7 +584,7 @@ stack[anonid=browserStack][responsivemode] {
}
stack[anonid=browserStack][responsivemode] {
-moz-transition-properties: min-width, max-width, min-height, max-height;
-moz-transition-property: min-width, max-width, min-height, max-height;
}
stack[anonid=browserStack][responsivemode][notransition] {

View File

@ -1400,7 +1400,7 @@ var gBrowserInit = {
// Show the toolbar if it was previously visible
if (gPrefService.getBoolPref("devtools.toolbar.visible")) {
this.DeveloperToolbar.show();
DeveloperToolbar.show();
}
}

View File

@ -3051,13 +3051,13 @@
if (doPosition) {
this.setAttribute("positionpinnedtabs", "true");
let scrollButtonWidth = this.mTabstrip._scrollButtonDown.scrollWidth;
let scrollButtonWidth = this.mTabstrip._scrollButtonDown.getBoundingClientRect().width;
let paddingStart = this.mTabstrip.scrollboxPaddingStart;
let width = 0;
for (let i = numPinned - 1; i >= 0; i--) {
let tab = this.childNodes[i];
width += tab.scrollWidth;
width += tab.getBoundingClientRect().width;
tab.style.MozMarginStart = - (width + scrollButtonWidth + paddingStart) + "px";
}

View File

@ -977,6 +977,9 @@ PropertiesView.prototype = {
let valueLabel = document.createElement("label");
let title = element.getElementsByClassName("title")[0];
// Use attribute flags to specify the element type and tooltip text.
this._setAttributes(element, aName, aFlags);
// Separator between the variable name and its value.
separatorLabel.className = "plain";
separatorLabel.setAttribute("value", ":");
@ -984,21 +987,6 @@ PropertiesView.prototype = {
// The variable information (type, class and/or value).
valueLabel.className = "value plain";
if (aFlags) {
// Use attribute flags to specify the element type and tooltip text.
let tooltip = [];
!aFlags.configurable ? element.setAttribute("non-configurable", "")
: tooltip.push("configurable");
!aFlags.enumerable ? element.setAttribute("non-enumerable", "")
: tooltip.push("enumerable");
!aFlags.writable ? element.setAttribute("non-writable", "")
: tooltip.push("writable");
element.setAttribute("tooltiptext", tooltip.join(", "));
}
if (aName === "this") { element.setAttribute("self", ""); }
// Handle the click event when pressing the element value label.
valueLabel.addEventListener("click", this._activateElementInputMode.bind({
scope: this,
@ -1029,6 +1017,36 @@ PropertiesView.prototype = {
return element;
},
/**
* Sets a variable's configurable, enumerable or writable attributes.
*
* @param object aVar
* The object to set the attributes on.
* @param object aName
* The varialbe name.
* @param object aFlags
* Contains configurable, enumerable or writable flags.
*/
_setAttributes: function DVP_setAttributes(aVar, aName, aFlags) {
if (aFlags) {
if (!aFlags.configurable) {
aVar.setAttribute("non-configurable", "");
}
if (!aFlags.enumerable) {
aVar.setAttribute("non-enumerable", "");
}
if (!aFlags.writable) {
aVar.setAttribute("non-writable", "");
}
}
if (aName === "this") {
aVar.setAttribute("self", "");
}
if (aName === "__proto__ ") {
aVar.setAttribute("proto", "");
}
},
/**
* Sets the specific grip for a variable.
* The grip should contain the value or the type & class, as defined in the
@ -1209,6 +1227,9 @@ PropertiesView.prototype = {
let separatorLabel = document.createElement("label");
let valueLabel = document.createElement("label");
// Use attribute flags to specify the element type and tooltip text.
this._setAttributes(element, pKey, aFlags);
if ("undefined" !== typeof pKey) {
// Use a key element to specify the property name.
nameLabel.className = "key plain";
@ -1228,21 +1249,6 @@ PropertiesView.prototype = {
title.appendChild(valueLabel);
}
if (aFlags) {
// Use attribute flags to specify the element type and tooltip text.
let tooltip = [];
!aFlags.configurable ? element.setAttribute("non-configurable", "")
: tooltip.push("configurable");
!aFlags.enumerable ? element.setAttribute("non-enumerable", "")
: tooltip.push("enumerable");
!aFlags.writable ? element.setAttribute("non-writable", "")
: tooltip.push("writable");
element.setAttribute("tooltiptext", tooltip.join(", "));
}
if (pKey === "__proto__ ") { element.setAttribute("proto", ""); }
// Handle the click event when pressing the element value label.
valueLabel.addEventListener("click", this._activateElementInputMode.bind({
scope: this,
@ -1498,6 +1504,7 @@ PropertiesView.prototype = {
} else {
arrow.addEventListener("click", function() { element.toggle(); }, false);
name.addEventListener("click", function() { element.toggle(); }, false);
name.addEventListener("mouseover", function() { element.updateTooltip(name); }, false);
}
title.appendChild(arrow);
@ -1728,6 +1735,52 @@ PropertiesView.prototype = {
}
});
/**
* Creates a tooltip for the element displaying certain attributes.
*
* @param object aAnchor
* The element which will anchor the tooltip.
*/
element.updateTooltip = function DVP_element_updateTooltip(aAnchor) {
let tooltip = document.getElementById("element-tooltip");
if (tooltip) {
document.documentElement.removeChild(tooltip);
}
tooltip = document.createElement("tooltip");
tooltip.id = "element-tooltip";
let configurableLabel = document.createElement("label");
configurableLabel.id = "configurableLabel";
configurableLabel.setAttribute("value", "configurable");
let enumerableLabel = document.createElement("label");
enumerableLabel.id = "enumerableLabel";
enumerableLabel.setAttribute("value", "enumerable");
let writableLabel = document.createElement("label");
writableLabel.id = "writableLabel";
writableLabel.setAttribute("value", "writable");
tooltip.setAttribute("orient", "horizontal")
tooltip.appendChild(configurableLabel);
tooltip.appendChild(enumerableLabel);
tooltip.appendChild(writableLabel);
if (element.hasAttribute("non-configurable")) {
configurableLabel.setAttribute("non-configurable", "");
}
if (element.hasAttribute("non-enumerable")) {
enumerableLabel.setAttribute("non-enumerable", "");
}
if (element.hasAttribute("non-writable")) {
writableLabel.setAttribute("non-writable", "");
}
document.documentElement.appendChild(tooltip);
aAnchor.setAttribute("tooltip", tooltip.id);
};
/**
* Generic function refreshing the internal state of the element when
* it's modified (e.g. a child detail, variable, property is added).

View File

@ -294,7 +294,12 @@ LayoutView.prototype = {
let clientRect = node.getBoundingClientRect();
let width = Math.round(clientRect.width);
let height = Math.round(clientRect.height);
this.doc.querySelector("#element-size").textContent = width + "x" + height;
let elt = this.doc.querySelector("#element-size");
let newLabel = width + "x" + height;
if (elt.textContent != newLabel) {
elt.textContent = newLabel;
}
// If the view is closed, no need to do anything more.
if (!this.isOpen) return;

View File

@ -28,10 +28,10 @@ let ResponsiveUIManager = {
* @param aTab the tab targeted.
*/
toggle: function(aWindow, aTab) {
if (aTab.responsiveUI) {
aTab.responsiveUI.close();
if (aTab.__responsiveUI) {
aTab.__responsiveUI.close();
} else {
aTab.responsiveUI = new ResponsiveUI(aWindow, aTab);
aTab.__responsiveUI = new ResponsiveUI(aWindow, aTab);
}
},
}
@ -169,7 +169,7 @@ ResponsiveUI.prototype = {
this.container.removeAttribute("responsivemode");
this.stack.removeAttribute("responsivemode");
delete this.tab.responsiveUI;
delete this.tab.__responsiveUI;
},
/**

View File

@ -42,7 +42,7 @@ function test() {
}
function onUIOpen() {
instance = gBrowser.selectedTab.responsiveUI;
instance = gBrowser.selectedTab.__responsiveUI;
ok(instance, "instance of the module is attached to the tab.");
instance.stack.setAttribute("notransition", "true");

View File

@ -37,7 +37,7 @@ function test() {
}
function onUIOpen() {
instance = gBrowser.selectedTab.responsiveUI;
instance = gBrowser.selectedTab.__responsiveUI;
ok(instance, "instance of the module is attached to the tab.");
instance.stack.setAttribute("notransition", "true");

View File

@ -28,7 +28,7 @@ function test() {
// Menus are correctly updated?
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
instance = gBrowser.selectedTab.responsiveUI;
instance = gBrowser.selectedTab.__responsiveUI;
ok(instance, "instance of the module is attached to the tab.");
instance.transitionsEnabled = false;

View File

@ -683,4 +683,5 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/webapprt/components/components.manifest
@BINPATH@/webapprt/defaults/preferences/prefs.js
@BINPATH@/webapprt/modules/WebappRT.jsm
@BINPATH@/webapprt/modules/WebappsHandler.jsm
#endif

View File

@ -23,3 +23,12 @@ geolocation.description=Do you want to share your location?
geolocation.sharelocation=Share Location
geolocation.dontshare=Don't Share
geolocation.remember=Remember my choice
# LOCALIZATION NOTE (webapps.install.title): %S will be replaced with the name
# of the webapp being installed.
webapps.install.title=Install %S
# LOCALIZATION NOTE (webapps.install.description): %S will be replaced with the
# name of the webapp being installed.
webapps.install.description=Do you want to install %S?
webapps.install.install=Install App
webapps.install.dontinstall=Don't Install

View File

@ -116,7 +116,7 @@ function NativeApp(aData) {
"app": app
};
this.processFolder = Services.dirsvc.get("CurProcD", Ci.nsIFile);
this.runtimeFolder = Services.dirsvc.get("GreD", Ci.nsIFile);
}
#ifdef XP_WIN
@ -284,11 +284,11 @@ WinNativeApp.prototype = {
* Copy the pre-built files into their destination folders.
*/
_copyPrebuiltFiles: function() {
let webapprt = this.processFolder.clone();
let webapprt = this.runtimeFolder.clone();
webapprt.append("webapprt-stub.exe");
webapprt.copyTo(this.installDir, this.appNameAsFilename + ".exe");
let uninstaller = this.processFolder.clone();
let uninstaller = this.runtimeFolder.clone();
uninstaller.append("webapp-uninstaller.exe");
uninstaller.copyTo(this.uninstallDir, this.uninstallerFile.leafName);
},
@ -313,7 +313,7 @@ WinNativeApp.prototype = {
writer.setString("Webapp", "Name", this.appName);
writer.setString("Webapp", "Profile", this.installDir.leafName);
writer.setString("Webapp", "Executable", this.appNameAsFilename);
writer.setString("WebappRT", "InstallDir", this.processFolder.path);
writer.setString("WebappRT", "InstallDir", this.runtimeFolder.path);
writer.writeFile(null, Ci.nsIINIParserWriter.WRITE_UTF16);
// ${UninstallDir}/shortcuts_log.ini
@ -534,7 +534,7 @@ MacNativeApp.prototype = {
},
_copyPrebuiltFiles: function() {
let webapprt = this.processFolder.clone();
let webapprt = this.runtimeFolder.clone();
webapprt.append("webapprt-stub");
webapprt.copyTo(this.macOSDir, "webapprt");
},
@ -719,7 +719,7 @@ LinuxNativeApp.prototype = {
},
_copyPrebuiltFiles: function() {
let webapprtPre = this.processFolder.clone();
let webapprtPre = this.runtimeFolder.clone();
webapprtPre.append(this.webapprt.leafName);
webapprtPre.copyTo(this.installDir, this.webapprt.leafName);
},
@ -740,7 +740,7 @@ LinuxNativeApp.prototype = {
let writer = factory.createINIParser(webappINI).QueryInterface(Ci.nsIINIParserWriter);
writer.setString("Webapp", "Name", this.appName);
writer.setString("Webapp", "Profile", this.uniqueName);
writer.setString("WebappRT", "InstallDir", this.processFolder.path);
writer.setString("WebappRT", "InstallDir", this.runtimeFolder.path);
writer.writeFile();
// $XDG_DATA_HOME/applications/owa-<webappuniquename>.desktop

View File

@ -168,6 +168,16 @@
opacity: 0.5;
}
#element-tooltip > label {
margin: 0 2px 0 2px;
}
#element-tooltip > label[non-enumerable],
#element-tooltip > label[non-configurable],
#element-tooltip > label[non-writable]{
text-decoration: line-through;
}
/**
* Property values colors
*/

View File

@ -170,6 +170,16 @@
opacity: 0.5;
}
#element-tooltip > label {
margin: 0 2px 0 2px;
}
#element-tooltip > label[non-enumerable],
#element-tooltip > label[non-configurable],
#element-tooltip > label[non-writable]{
text-decoration: line-through;
}
/**
* Property values colors
*/

View File

@ -168,6 +168,16 @@
opacity: 0.5;
}
#element-tooltip > label {
margin: 0 2px 0 2px;
}
#element-tooltip > label[non-enumerable],
#element-tooltip > label[non-configurable],
#element-tooltip > label[non-writable]{
text-decoration: line-through;
}
/**
* Property values colors
*/

41
build/unix/build-clang/build-clang.py Normal file → Executable file
View File

@ -13,6 +13,7 @@ import os.path
import shutil
import tarfile
import subprocess
import platform
def check_run(args):
r = subprocess.call(args)
@ -46,8 +47,7 @@ def with_env(env, f):
def build_tar_package(tar, name, base, directory):
name = os.path.realpath(name)
run_in(base, [tar, "-cjf", name, "--mtime=2012-01-01", "--owner=root",
directory])
run_in(base, [tar, "-cjf", name, directory])
def svn_co(url, directory, revision):
check_run(["svn", "co", "-r", revision, url, directory])
@ -74,7 +74,7 @@ def build_one_stage_aux(stage_dir, is_stage_one):
os.mkdir(stage_dir)
build_dir = stage_dir + "/build"
inst_dir = stage_dir + "/inst"
inst_dir = stage_dir + "/clang"
configure_opts = ["--enable-optimized",
"--prefix=%s" % inst_dir,
@ -84,6 +84,8 @@ def build_one_stage_aux(stage_dir, is_stage_one):
build_package(llvm_source_dir, build_dir, configure_opts)
isDarwin = platform.system() == "Darwin"
if not os.path.exists(source_dir):
os.makedirs(source_dir)
svn_co("http://llvm.org/svn/llvm-project/llvm/trunk",
@ -94,8 +96,12 @@ if not os.path.exists(source_dir):
compiler_rt_source_dir, llvm_revision)
os.symlink("../../clang", llvm_source_dir + "/tools/clang")
os.symlink("../../compiler-rt", llvm_source_dir + "/projects/compiler-rt")
patch("old-ld-hack.patch", 1, llvm_source_dir)
patch("compiler-rt-gnu89-inline.patch", 0, compiler_rt_source_dir)
if isDarwin:
patch("clang-no-ios.patch", 0, clang_source_dir)
patch("compiler-rt-no-ios.patch", 0, compiler_rt_source_dir)
else:
patch("old-ld-hack.patch", 1, llvm_source_dir)
patch("compiler-rt-gnu89-inline.patch", 0, compiler_rt_source_dir)
if os.path.exists(build_dir):
shutil.rmtree(build_dir)
@ -103,13 +109,28 @@ os.makedirs(build_dir)
stage1_dir = build_dir + '/stage1'
stage1_inst_dir = stage1_dir + '/clang'
build_one_stage({"CC" : "/tools/gcc-4.5-0moz3/bin/gcc -static-libgcc",
"CXX" : "/tools/gcc-4.5-0moz3/bin/g++ -static-libgcc -static-libstdc++"},
if isDarwin:
extra_cflags = ""
extra_cxxflags = ""
cc = "/usr/bin/clang"
cxx = "/usr/bin/clang++"
else:
extra_cflags = "-static-libgcc"
extra_cxxflags = "-static-libgcc -static-libstdc++"
cc = "/tools/gcc-4.5-0moz3/bin/gcc %s" % extra_cflags
cxx = "/tools/gcc-4.5-0moz3/bin/g++ %s" % extra_cxxflags
build_one_stage({"CC" : cc,
"CXX" : cxx },
stage1_dir, True)
if not isDarwin:
extra_cflags += " -fgnu89-inline"
stage2_dir = build_dir + '/stage2'
build_one_stage({"CC" : stage1_inst_dir + "/bin/clang -static-libgcc -fgnu89-inline",
"CXX" : stage1_inst_dir + "/bin/clang++ -static-libgcc -static-libstdc++"},
build_one_stage({"CC" : stage1_inst_dir + "/bin/clang %s" % extra_cflags,
"CXX" : stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags},
stage2_dir, False)
build_tar_package("/bin/tar", "clang.tar.bz2", stage3_dir, "clang")
build_tar_package("tar", "clang.tar.bz2", stage2_dir, "clang")

View File

@ -0,0 +1,15 @@
Index: runtime/compiler-rt/Makefile
===================================================================
--- runtime/compiler-rt/Makefile (revision 157958)
+++ runtime/compiler-rt/Makefile (working copy)
@@ -74,8 +74,8 @@
ifeq ($(OS),Darwin)
RuntimeDirs += darwin
RuntimeLibrary.darwin.Configs := \
- eprintf 10.4 osx ios cc_kext \
- asan_osx profile_osx profile_ios
+ eprintf 10.4 osx \
+ asan_osx profile_osx
endif
# On Linux, include a library which has all the runtime functions.

View File

@ -0,0 +1,29 @@
Index: make/platform/clang_darwin.mk
===================================================================
--- make/platform/clang_darwin.mk (revision 157958)
+++ make/platform/clang_darwin.mk (working copy)
@@ -47,7 +47,7 @@
# Configuration for targetting iOS, for some ARMv6 functions, which must be
# in the same linkage unit, and for a couple of other functions that didn't
# make it into libSystem.
-Configs += ios
+#Configs += ios
UniversalArchs.ios := $(call CheckArches,i386 x86_64 armv6 armv7,ios)
# Configuration for targetting OSX. These functions may not be in libSystem
@@ -56,13 +56,13 @@
UniversalArchs.osx := $(call CheckArches,i386 x86_64,osx)
# Configuration for use with kernel/kexts.
-Configs += cc_kext
+#Configs += cc_kext
UniversalArchs.cc_kext := $(call CheckArches,armv6 armv7 i386 x86_64,cc_kext)
# Configurations which define the profiling support functions.
Configs += profile_osx
UniversalArchs.profile_osx := $(call CheckArches,i386 x86_64,profile_osx)
-Configs += profile_ios
+#Configs += profile_ios
UniversalArchs.profile_ios := $(call CheckArches,i386 x86_64 armv6 armv7,profile_ios)
# Configurations which define the ASAN support functions.

View File

@ -0,0 +1,4 @@
#!/bin/sh
rm -rf clang
tar -xjf clang.tar.bz2

View File

@ -26,9 +26,13 @@ namespace std {
template ostream& ostream::_M_insert(unsigned long);
template ostream& ostream::_M_insert(long long);
template ostream& ostream::_M_insert(unsigned long long);
template ostream& ostream::_M_insert(bool);
template ostream& ostream::_M_insert(const void*);
template ostream& __ostream_insert(ostream&, const char*, streamsize);
template istream& istream::_M_extract(double&);
template istream& istream::_M_extract(float&);
template istream& istream::_M_extract(unsigned int&);
template istream& istream::_M_extract(unsigned long&);
#endif
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
/* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions
@ -42,6 +46,7 @@ namespace std {
template string& string::operator=(string&&);
template wstring::basic_string(wstring&&);
template wstring& wstring::operator=(wstring&&);
template string& string::assign(string&&);
template wstring& wstring::assign(wstring&&);
#endif /* __GXX_EXPERIMENTAL_CXX0X__ */
#endif /* (__GNUC__ == 4) && (__GNUC_MINOR__ >= 5) */

View File

@ -137,6 +137,7 @@ MOZ_WEBM = @MOZ_WEBM@
MOZ_MEDIA_PLUGINS = @MOZ_MEDIA_PLUGINS@
MOZ_OMX_PLUGIN = @MOZ_OMX_PLUGIN@
MOZ_GSTREAMER = @MOZ_GSTREAMER@
MOZ_VP8 = @MOZ_VP8@
MOZ_VP8_ERROR_CONCEALMENT = @MOZ_VP8_ERROR_CONCEALMENT@
MOZ_VP8_ENCODER = @MOZ_VP8_ENCODER@
VPX_AS = @VPX_AS@
@ -170,6 +171,7 @@ MOZ_D3DX9_DLL = @MOZ_D3DX9_DLL@
MOZ_D3DCOMPILER_DLL = @MOZ_D3DCOMPILER_DLL@
MOZ_GL_PROVIDER = @MOZ_GL_PROVIDER@
MOZ_GL_DEFAULT_PROVIDER = @MOZ_GL_DEFAULT_PROVIDER@
MOZ_WEBRTC = @MOZ_WEBRTC@
JAVA=@JAVA@

View File

@ -56,6 +56,8 @@ space :=$(nullstr) # EOL
core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
RM = rm -f
# LIBXUL_DIST is not defined under js/src, thus we make it mean DIST there.
LIBXUL_DIST ?= $(DIST)

View File

@ -633,7 +633,10 @@ endif
HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
# Dependencies which, if modified, should cause everything to rebuild
GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
ifndef NO_MAKEFILE_RULE
GLOBAL_DEPS += Makefile.in
endif
##############################################
include $(topsrcdir)/config/makefiles/target_libs.mk
@ -1147,16 +1150,20 @@ GARBAGE_DIRS += $(_JAVA_DIR)
# Update Makefiles
###############################################################################
ifndef NO_MAKEFILE_RULE
# Note: Passing depth to make-makefile is optional.
# It saves the script some work, though.
Makefile: Makefile.in
@$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH)
endif
ifndef NO_SUBMAKEFILES_RULE
ifdef SUBMAKEFILES
# VPATH does not work on some machines in this case, so add $(srcdir)
$(SUBMAKEFILES): % : $(srcdir)/%.in
$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH) $@
endif
endif
ifdef AUTOUPDATE_CONFIGURE
$(topsrcdir)/configure: $(topsrcdir)/configure.in

View File

@ -1059,3 +1059,5 @@ gst/gst.h
gst/app/gstappsink.h
gst/app/gstappsrc.h
gst/video/video.h
sys/msg.h
sys/ipc.h

View File

@ -495,7 +495,7 @@ case "$target" in
AC_LANG_RESTORE
changequote(,)
_MSVC_VER_FILTER='s|.* ([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
_MSVC_VER_FILTER='s|.*[^!-~]([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
changequote([,])
# Determine compiler version
@ -522,18 +522,22 @@ case "$target" in
fi
_CC_SUITE=8
_MSVS_VERSION=2005
AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
elif test "$_CC_MAJOR_VERSION" = "15"; then
_CC_SUITE=9
_MSVS_VERSION=2008
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "16"; then
_CC_SUITE=10
_MSVS_VERSION=2010
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "17"; then
_CC_SUITE=11
_MSVS_VERSION=2011
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
else
@ -567,7 +571,7 @@ case "$target" in
fi
changequote(,)
_MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
_MSMT_VER_FILTER='s|.*[^!-~]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
changequote([,])
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
if test -z "$MSMANIFEST_TOOL_VERSION"; then
@ -4250,9 +4254,12 @@ MOZ_WAVE=1
MOZ_MEDIA=
MOZ_OPUS=1
MOZ_WEBM=1
MOZ_WEBRTC=
MOZ_WEBRTC_SIGNALING=
MOZ_MEDIA_PLUGINS=
MOZ_MEDIA_NAVIGATOR=
MOZ_OMX_PLUGIN=
MOZ_VP8=
MOZ_VP8_ERROR_CONCEALMENT=
MOZ_VP8_ENCODER=
VPX_AS=
@ -5271,6 +5278,25 @@ if test "$NS_PRINTING"; then
AC_DEFINE(NS_PRINT_PREVIEW)
fi
dnl ========================================================
dnl = Enable WebRTC code
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(webrtc,
[ --enable-webrtc Enable support for WebRTC],
MOZ_WEBRTC=1,
MOZ_WEBRTC=)
if test -n "$MOZ_WEBRTC"; then
AC_DEFINE(MOZ_WEBRTC)
MOZ_MEDIA=1
MOZ_RAW=1
MOZ_VP8=1
MOZ_VP8_ENCODER=1
MOZ_VP8_ERROR_CONCEALMENT=1
fi
AC_SUBST(MOZ_WEBRTC)
dnl ========================================================
dnl = Enable Raw Codecs
dnl ========================================================
@ -5346,6 +5372,11 @@ MOZ_ARG_DISABLE_BOOL(webm,
MOZ_WEBM=,
MOZ_WEBM=1)
if test -n "$MOZ_WEBM"; then
AC_DEFINE(MOZ_WEBM)
MOZ_VP8=1
fi;
dnl ========================================================
dnl = Disable media plugin support
dnl ========================================================
@ -5397,8 +5428,8 @@ MOZ_ARG_WITH_BOOL(system-libvpx,
MOZ_LIBVPX_INCLUDES=
MOZ_LIBVPX_LIBS=
if test -n "$MOZ_WEBM"; then
AC_DEFINE(MOZ_WEBM)
if test -n "$MOZ_VP8"; then
AC_DEFINE(MOZ_VP8)
if test -n "$MOZ_VP8_ERROR_CONCEALMENT" ; then
AC_DEFINE(MOZ_VP8_ERROR_CONCEALMENT)
fi
@ -5425,7 +5456,7 @@ AC_SUBST(MOZ_NATIVE_LIBVPX)
AC_SUBST(MOZ_LIBVPX_INCLUDES)
AC_SUBST(MOZ_LIBVPX_LIBS)
if test -n "$MOZ_WEBM" -a -z "$MOZ_NATIVE_LIBVPX"; then
if test "$MOZ_WEBM"; then
MOZ_SYDNEYAUDIO=1
MOZ_CUBEB=1
MOZ_MEDIA=1
@ -5437,7 +5468,9 @@ if test -n "$MOZ_WEBM" -a -z "$MOZ_NATIVE_LIBVPX"; then
MOZ_VORBIS=1
;;
esac
fi
if test -n "$MOZ_VP8" -a -z "$MOZ_NATIVE_LIBVPX"; then
dnl Detect if we can use an assembler to compile optimized assembly for libvpx.
dnl We currently require yasm on all x86 platforms and require yasm 1.1.0 on Win32.
@ -8588,6 +8621,7 @@ AC_SUBST(MOZ_MEDIA_PLUGINS)
AC_SUBST(MOZ_OMX_PLUGIN)
AC_SUBST(MOZ_VP8_ERROR_CONCEALMENT)
AC_SUBST(MOZ_VP8_ENCODER)
AC_SUBST(MOZ_VP8)
AC_SUBST(MOZ_OGG)
AC_SUBST(MOZ_ALSA_LIBS)
AC_SUBST(MOZ_ALSA_CFLAGS)
@ -8865,6 +8899,52 @@ mv -f config/autoconf.mk config/autoconf.mk.orig 2> /dev/null
AC_OUTPUT($MAKEFILES)
# Generate Makefiles for WebRTC directly from .gyp files
if test "${OS_TARGET}" = "WINNT"; then
if test "$HAVE_64BIT_OS"; then
OS_BITS=64
else
OS_BITS=32
fi
EXTRA_GYP_DEFINES="-D MSVS_VERSION=${_MSVS_VERSION} -D MSVS_OS_BITS=${OS_BITS}"
fi
if test -n "$MOZ_WEBRTC"; then
AC_MSG_RESULT("generating WebRTC Makefiles...")
GYP_WEBRTC_OPTIONS="--format=mozmake -D build_with_mozilla=1 -D enable_protobuf=0 -D include_internal_video_render=0 ${EXTRA_GYP_DEFINES} --depth=${srcdir}/media/webrtc/trunk --toplevel-dir=${srcdir} -G OBJDIR=${_objdir}"
$PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \
$GYP_WEBRTC_OPTIONS \
--generator-output=${_objdir}/media/webrtc/trunk \
${srcdir}/media/webrtc/trunk/peerconnection.gyp
if test "$?" != 0; then
AC_MSG_ERROR([failed to generate WebRTC Makefiles])
fi
# XXX disable until we land the tranche with signaling
if test -n "$MOZ_WEBRTC_SIGNALING"; then
AC_MSG_RESULT("generating WebRTC/Signaling Makefiles...")
$PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \
$GYP_WEBRTC_OPTIONS \
--generator-output=${_objdir}/media/webrtc/signaling \
${srcdir}/media/webrtc/signaling/signaling.gyp
if test "$?" != 0; then
AC_MSG_ERROR([failed to generate WebRTC/Signaling Makefiles])
fi
fi
AC_MSG_RESULT("generating gtest Makefiles...")
# Ok to pass some extra -D's that are ignored here
$PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \
$GYP_WEBRTC_OPTIONS \
--generator-output=${_objdir}/media/webrtc/trunk/testing/ \
${srcdir}/media/webrtc/trunk/testing/gtest.gyp
if test "$?" != 0; then
AC_MSG_ERROR([failed to generate gtest Makefiles])
fi
fi
# Populate the virtualenv
AC_MSG_RESULT([Populating Python virtualenv])
$MAKE -C build/virtualenv MACOSX_DEPLOYMENT_TARGET= || exit 1

View File

@ -250,6 +250,64 @@ public:
return OwnerDoc()->IsHTML();
}
/**
* Get the namespace that this element's tag is defined in
* @return the namespace
*/
inline PRInt32 GetNameSpaceID() const
{
return mNodeInfo->NamespaceID();
}
/**
* Get the NodeInfo for this element
* @return the nodes node info
*/
inline nsINodeInfo* NodeInfo() const
{
return mNodeInfo;
}
inline bool IsInNamespace(PRInt32 aNamespace) const
{
return mNodeInfo->NamespaceID() == aNamespace;
}
inline bool IsHTML() const
{
return IsInNamespace(kNameSpaceID_XHTML);
}
inline bool IsHTML(nsIAtom* aTag) const
{
return mNodeInfo->Equals(aTag, kNameSpaceID_XHTML);
}
inline bool IsSVG() const
{
return IsInNamespace(kNameSpaceID_SVG);
}
inline bool IsSVG(nsIAtom* aTag) const
{
return mNodeInfo->Equals(aTag, kNameSpaceID_SVG);
}
inline bool IsXUL() const
{
return IsInNamespace(kNameSpaceID_XUL);
}
inline bool IsMathML() const
{
return IsInNamespace(kNameSpaceID_MathML);
}
inline bool IsMathML(nsIAtom* aTag) const
{
return mNodeInfo->Equals(aTag, kNameSpaceID_MathML);
}
/**
* Returns an atom holding the name of the attribute of type ID on
* this content node (if applicable). Returns null for non-element

View File

@ -476,15 +476,6 @@ public:
return mNodeInfo->LocalName();
}
/**
* Get the namespace that this element's tag is defined in
* @return the namespace
*/
PRInt32 GetNameSpaceID() const
{
return mNodeInfo->NamespaceID();
}
/**
* Get the tag for this element. This will always return a non-null atom
* pointer (as implied by the naming of the method). For elements this is
@ -496,55 +487,6 @@ public:
return mNodeInfo->NameAtom();
}
/**
* Get the NodeInfo for this element
* @return the nodes node info
*/
nsINodeInfo* NodeInfo() const
{
return mNodeInfo;
}
bool IsInNamespace(PRInt32 aNamespace) const
{
return mNodeInfo->NamespaceID() == aNamespace;
}
bool IsHTML() const
{
return IsInNamespace(kNameSpaceID_XHTML);
}
bool IsHTML(nsIAtom* aTag) const
{
return mNodeInfo->Equals(aTag, kNameSpaceID_XHTML);
}
bool IsSVG() const
{
return IsInNamespace(kNameSpaceID_SVG);
}
bool IsSVG(nsIAtom* aTag) const
{
return mNodeInfo->Equals(aTag, kNameSpaceID_SVG);
}
bool IsXUL() const
{
return IsInNamespace(kNameSpaceID_XUL);
}
bool IsMathML() const
{
return IsInNamespace(kNameSpaceID_MathML);
}
bool IsMathML(nsIAtom* aTag) const
{
return mNodeInfo->Equals(aTag, kNameSpaceID_MathML);
}
nsINode*
InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn)
{

View File

@ -1505,13 +1505,6 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell->SetChromeEventHandler(chromeEventHandler);
}
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (OwnerIsBrowserFrame() && os) {
mDocShell->SetIsBrowserFrame(true);
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
"in-process-browser-frame-shown", NULL);
}
// This is nasty, this code (the do_GetInterface(mDocShell) below)
// *must* come *after* the above call to
// mDocShell->SetChromeEventHandler() for the global window to get
@ -1538,6 +1531,22 @@ nsFrameLoader::MaybeCreateDocShell()
EnsureMessageManager();
if (OwnerIsBrowserFrame()) {
mDocShell->SetIsBrowserFrame(true);
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
"in-process-browser-frame-shown", NULL);
}
if (mMessageManager) {
mMessageManager->LoadFrameScript(
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
/* allowDelayedLoad = */ true);
}
}
return NS_OK;
}
@ -1899,7 +1908,8 @@ nsFrameLoader::TryRemoteBrowser()
ContentParent* parent = ContentParent::GetNewOrUsed();
NS_ASSERTION(parent->IsAlive(), "Process parent should be alive; something is very wrong!");
mRemoteBrowser = parent->CreateTab(chromeFlags);
mRemoteBrowser = parent->CreateTab(chromeFlags,
/* aIsBrowserFrame = */ OwnerIsBrowserFrame());
if (mRemoteBrowser) {
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
mRemoteBrowser->SetOwnerElement(element);

View File

@ -2033,6 +2033,20 @@ nsGenericElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height);
}
nsIntSize
nsGenericElement::GetPaddingRectSize()
{
nsIFrame* frame = GetStyledFrame();
if (!frame) {
return nsIntSize(0, 0);
}
NS_ASSERTION(frame->GetParent(), "Styled frame has no parent");
nsRect rcFrame = nsLayoutUtils::GetAllInFlowPaddingRectsUnion(frame, frame->GetParent());
return nsIntSize(nsPresContext::AppUnitsToIntCSSPixels(rcFrame.width),
nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height));
}
nsIScrollableFrame*
nsGenericElement::GetScrollFrame(nsIFrame **aStyledFrame)
{
@ -2145,10 +2159,7 @@ nsGenericElement::GetScrollHeight()
nsIScrollableFrame* sf = GetScrollFrame();
if (!sf) {
nsRect rcFrame;
nsCOMPtr<nsIContent> parent;
GetOffsetRect(rcFrame, getter_AddRefs(parent));
return rcFrame.height;
return GetPaddingRectSize().height;
}
nscoord height = sf->GetScrollRange().height + sf->GetScrollPortRect().height;
@ -2171,10 +2182,7 @@ nsGenericElement::GetScrollWidth()
nsIScrollableFrame* sf = GetScrollFrame();
if (!sf) {
nsRect rcFrame;
nsCOMPtr<nsIContent> parent;
GetOffsetRect(rcFrame, getter_AddRefs(parent));
return rcFrame.width;
return GetPaddingRectSize().width;
}
nscoord width = sf->GetScrollRange().width + sf->GetScrollPortRect().width;

View File

@ -777,6 +777,13 @@ protected:
*/
virtual void GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent);
/**
* Retrieve the size of the padding rect of this element.
*
* @param aSize the size of the padding rect
*/
nsIntSize GetPaddingRectSize();
nsIFrame* GetStyledFrame();
virtual mozilla::dom::Element* GetNameSpaceElement()

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=320799
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=320799">Mozilla Bug 320799</a>
<p id="display">
<select id="s" style="width: 100px">
<select id="s" style="width: 100px; -moz-box-sizing: padding-box">
<option>This is a test, it really is a test I tell you</option>
</select>
<select id="s2">

View File

@ -41,13 +41,13 @@ function t3(id,c,o,s,pid) {
function run_test() {
t3('span1',[0,0,20,20],[12,12,20,20],[0,0,20,20],'td1');
t3('td1' ,[1,1,69,44],[16,16,71,46],[0,0,71,46],'table1');
t3('td1' ,[1,1,69,44],[16,16,71,46],[0,0,69,46],'table1');
t3('tr1' ,[0,0,71,46],[16,16,71,46],[0,0,71,44],'table1');
t3('span2',[10,0,20,20],[27,12,30,20],[0,0,30,20],'td2');
t3('table1',[9,9,85,113],[10,10,103,131],[0,0,103,50],'body');
t3('span2',[10,0,20,20],[27,12,30,20],[0,0,20,20],'td2');
t3('table1',[9,9,85,113],[10,10,103,131],[0,0,85,50],'body');
t3('div1',[10,10,-1,131],[0,0,-1,151],[0,0,-1,85],'body');
t3('span2b',[10,0,20,20],[25,-1,30,20],[0,0,30,20],'body');
t3('span2b',[10,0,20,20],[25,-1,30,20],[0,0,20,20],'body');
// XXX not sure how to make reliable cross-platform tests for replaced-inline, inline
// t3('span2c',[10,2,18,2],[25,-1,30,6],[0,0,30,20],'body');
// t3('span2d',[0,0,0,0],[25,-1,10,19],[0,0,10,20],'body');
@ -60,24 +60,24 @@ function run_test() {
t3('div3',[10,10,-1,40],[0,151,-1,60],[0,0,-1,70],'body');
t3('span5' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td5');
t3('td5' ,[7,7,22,22],[2,2,36,36],[0,0,36,36],'table5');
t3('td5' ,[7,7,22,22],[2,2,36,36],[0,0,22,36],'table5');
t3('tr5' ,[0,0,36,36],[2,2,36,36],[0,0,36,22],'table5');
t3('span6' ,[0,0,20,20],[20,58,20,20],[0,0,20,20],'div5');
t3('table5',[0,0,40,78],[0,0,40,78],[0,0,40,78],'div5');
t3('div5',[10,10,-1,78],[0,211,-1,98],[0,0,-1,70],'body');
t3('span7' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td7');
t3('td7' ,[1,1,37,22],[9,9,39,24],[0,0,39,22],'table7');
t3('td7' ,[1,1,37,22],[9,9,39,24],[0,0,37,22],'table7');
t3('tr7' ,[0,0,39,24],[9,9,39,24],[0,0,39,22],'table7');
t3('span8' ,[0,0,20,20],[26,37,20,20],[0,0,20,20],'table7');
t3('table7',[7,7,43,54],[10,319,57,68],[0,0,57,50],'body');
t3('table7',[7,7,43,54],[10,319,57,68],[0,0,43,50],'body');
t3('div7',[10,10,-1,68],[0,309,-1,88],[0,0,-1,70],'body');
t3('span9' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td9');
t3('td9' ,[1,1,22,22],[15,15,24,24],[0,0,24,24],'table9');
t3('td9' ,[1,1,22,22],[15,15,24,24],[0,0,22,24],'table9');
t3('tr9' ,[0,0,24,24],[15,15,24,24],[0,0,24,22],'table9');
t3('span10' ,[0,0,20,20],[17,43,20,20],[0,0,20,20],'table9');
t3('table9',[13,13,28,34],[10,407,54,60],[0,0,54,50],'body');
t3('table9',[13,13,28,34],[10,407,54,60],[0,0,28,50],'body');
t3('div9',[10,10,-1,0],[0,397,-1,20],[0,0,-1,70],'body');
t3('span11' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td11');

View File

@ -68,9 +68,9 @@ function run_test() {
// without hard-coding the scrollbar width?
t3('div1',[20,20,-1,-1],[10,10,200,160],[0,0,230,20],'body');
t3('abs1',[20,20,-1,-1],[500,170,200,160],[0,0,230,20],'body');
t3('table1',[20,20,266,266],[10,170,306,306],[0,0,306,20],'body');
t3('table1',[20,20,266,266],[10,170,306,306],[0,0,266,20],'body');
t3('table2',[0,0,206,206],[0,0,206,206],[0,0,206,20],'table2parent');
t3('table3',[10,10,208,208],[0,0,228,228],[0,0,228,228],'table3parent');
t3('table3',[10,10,208,208],[0,0,228,228],[0,0,208,228],'table3parent');
t3('table3parent',[0,0,228,228],[300,100,228,228],[0,0,228,228],'body');
}
</script>
@ -106,4 +106,4 @@ run_test();
</pre>
</body>
</html>
</html>

View File

@ -191,7 +191,7 @@ nsresult nsGStreamerReader::ReadMetadata(nsVideoInfo* aInfo)
* stream but that are otherwise decodeable.
*/
guint flags[3] = {GST_PLAY_FLAG_VIDEO|GST_PLAY_FLAG_AUDIO,
~GST_PLAY_FLAG_AUDIO, ~GST_PLAY_FLAG_VIDEO};
static_cast<guint>(~GST_PLAY_FLAG_AUDIO), static_cast<guint>(~GST_PLAY_FLAG_VIDEO)};
guint default_flags, current_flags;
g_object_get(mPlayBin, "flags", &default_flags, NULL);

View File

@ -78,98 +78,327 @@ XBLFinalize(JSFreeOp *fop, JSObject *obj)
c->Drop();
}
static JSBool
XBLResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
JSObject **objp)
// XBL fields are represented on elements inheriting that field a bit trickily.
// Initially the element itself won't have a property for the field. When an
// attempt is made to access the field, the element's resolve hook won't find
// it. But the XBL prototype object, in the prototype chain of the element,
// will resolve an accessor property for the field on the XBL prototype object.
// That accessor, when used, will then (via InstallXBLField below) reify a
// property for the field onto the actual XBL-backed element.
//
// The accessor property is a plain old property backed by a getter function and
// a setter function. These properties are backed by the FieldGetter and
// FieldSetter natives; they're created by XBLResolve. The precise field to be
// reified is identified using two extra slots on the getter/setter functions.
// XBLPROTO_SLOT stores the XBL prototype object that provides the field.
// FIELD_SLOT stores the name of the field, i.e. its JavaScript property name.
//
// This two-step field installation process -- reify an accessor on the
// prototype, then have that reify an own property on the actual element -- is
// admittedly convoluted. Better would be for XBL-backed elements to be proxies
// that could resolve fields onto themselves. But given that XBL bindings are
// associated with elements mutably -- you can add/remove/change -moz-binding
// whenever you want, alas -- doing so would require all elements to be proxies,
// which isn't performant now. So we do this two-step instead.
static const uint32_t XBLPROTO_SLOT = 0;
static const uint32_t FIELD_SLOT = 1;
static bool
ObjectHasISupportsPrivate(JS::Handle<JSObject*> obj)
{
// Note: if we get here, that means that the implementation for some binding
// was installed, which means that AllowScripts() tested true. Hence no need
// to do checks like that here.
// Default to not resolving things.
NS_ASSERTION(*objp, "Must have starting object");
JSClass* clasp = ::JS_GetClass(obj);
const uint32_t HAS_PRIVATE_NSISUPPORTS =
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS;
return (clasp->flags & HAS_PRIVATE_NSISUPPORTS) == HAS_PRIVATE_NSISUPPORTS;
}
JSObject* origObj = *objp;
*objp = NULL;
// Define a shadowing property on |this| for the XBL field defined by the
// contents of the callee's reserved slots. If the property was defined,
// *installed will be true, and idp will be set to the property name that was
// defined.
static JSBool
InstallXBLField(JSContext* cx,
JS::Handle<JSObject*> callee, JS::Handle<JSObject*> thisObj,
jsid* idp, bool* installed)
{
*installed = false;
if (!JSID_IS_STRING(id)) {
return JS_TRUE;
}
nsDependentJSString fieldName(id);
jsval slotVal = ::JS_GetReservedSlot(obj, 0);
NS_ASSERTION(!JSVAL_IS_VOID(slotVal), "How did that happen?");
nsXBLPrototypeBinding* protoBinding =
static_cast<nsXBLPrototypeBinding*>(JSVAL_TO_PRIVATE(slotVal));
NS_ASSERTION(protoBinding, "Must have prototype binding!");
nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
if (!field) {
return JS_TRUE;
}
// We have this field. Time to install it. Get our node.
JSClass* nodeClass = ::JS_GetClass(origObj);
if (!nodeClass) {
return JS_FALSE;
}
if (~nodeClass->flags &
(JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
return JS_FALSE;
}
// First ensure |this| is a reasonable XBL bound node.
//
// FieldAccessorGuard already determined whether |thisObj| was acceptable as
// |this| in terms of not throwing a TypeError. Assert this for good measure.
MOZ_ASSERT(ObjectHasISupportsPrivate(thisObj));
// But there are some cases where we must accept |thisObj| but not install a
// property on it, or otherwise touch it. Hence this split of |this|-vetting
// duties.
nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
do_QueryInterface(static_cast<nsISupports*>(::JS_GetPrivate(origObj)));
do_QueryInterface(static_cast<nsISupports*>(::JS_GetPrivate(thisObj)));
if (!xpcWrapper) {
// Looks like whatever |origObj| is it's not our nsIContent. It might well
// Looks like whatever |thisObj| is it's not our nsIContent. It might well
// be the proto our binding installed, however, where the private is the
// nsXBLDocumentInfo, so just baul out quietly. Do NOT throw an exception
// here.
// We could make this stricter by checking the class maybe, but whatever
return JS_TRUE;
//
// We could make this stricter by checking the class maybe, but whatever.
return true;
}
nsCOMPtr<nsIContent> content = do_QueryWrappedNative(xpcWrapper);
if (!content) {
nsCOMPtr<nsIContent> xblNode = do_QueryWrappedNative(xpcWrapper);
if (!xblNode) {
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
return JS_FALSE;
return false;
}
// Now that |this| is okay, actually install the field. Some of this
// installation work could have been done in XBLResolve, but this splitting
// of work seems simplest to implement and friendliest regarding lifetimes
// and potential cycles.
// Because of the possibility (due to XBL binding inheritance, because each
// XBL binding lives in its own global object) that |this| might be in a
// different compartment from the callee (not to mention that this method can
// be called with an arbitrary |this| regardless of how insane XBL is), and
// because in this method we've entered |this|'s compartment (see in
// Field[GS]etter where we attempt a cross-compartment call), we must enter
// the callee's compartment to access its reserved slots.
nsXBLPrototypeBinding* protoBinding;
nsDependentJSString fieldName;
{
JSAutoEnterCompartment ac;
if (!ac.enter(cx, callee)) {
return false;
}
JS::Rooted<JSObject*> xblProto(cx);
xblProto = &js::GetFunctionNativeReserved(callee, XBLPROTO_SLOT).toObject();
JS::Value name = js::GetFunctionNativeReserved(callee, FIELD_SLOT);
JSFlatString* fieldStr = JS_ASSERT_STRING_IS_FLAT(name.toString());
fieldName.init(fieldStr);
MOZ_ALWAYS_TRUE(JS_ValueToId(cx, name, idp));
JS::Value slotVal = ::JS_GetReservedSlot(xblProto, 0);
protoBinding = static_cast<nsXBLPrototypeBinding*>(slotVal.toPrivate());
MOZ_ASSERT(protoBinding);
}
nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
MOZ_ASSERT(field);
// This mirrors code in nsXBLProtoImpl::InstallImplementation
nsIDocument* doc = content->OwnerDoc();
nsIScriptGlobalObject* global = doc->GetScriptGlobalObject();
nsIScriptGlobalObject* global = xblNode->OwnerDoc()->GetScriptGlobalObject();
if (!global) {
return JS_TRUE;
return true;
}
nsCOMPtr<nsIScriptContext> context = global->GetContext();
if (!context) {
return JS_TRUE;
return true;
}
nsresult rv = field->InstallField(context, thisObj, xblNode->NodePrincipal(),
protoBinding->DocURI(), installed);
if (NS_SUCCEEDED(rv)) {
return true;
}
// Now we either resolve or fail
bool didInstall;
nsresult rv = field->InstallField(context, origObj,
content->NodePrincipal(),
protoBinding->DocURI(),
&didInstall);
if (NS_FAILED(rv)) {
if (!::JS_IsExceptionPending(cx)) {
xpc::Throw(cx, rv);
return JS_FALSE;
}
return false;
}
// Determine whether the |this| passed to this method is valid for an XBL field
// access (which is to say, an object with an nsISupports private), taking into
// account proxies and/or wrappers around |this|. There are three possible
// outcomes from calling this method:
//
// 1. An error was hit, and this method returned false. In this case, the
// caller should propagate it.
// 2. The |this| passed in was directly acceptable for XBL field access. This
// method returned true and set *thisObj to a |this| that can be used for
// field definition (i.e. that passes ObjectHasISupportsPrivate). In this
// case, the caller should install the field on *thisObj.
// 3. The |this| passed in was a proxy/wrapper around an object usable for
// XBL field access. The method recursively (and successfully) invoked the
// native on the unwrapped |this|, then it returned true and set *thisObj
// to null. In this case, the caller should itself return true.
//
// Thus this method implements the JS_CallNonGenericMethodOnProxy idiom in
// jsapi.h.
//
// Note that a |this| valid for field access is *not* necessarily one on which
// the field value will be installed. It's just one where calling the specified
// method on it won't unconditionally throw a TypeError. Confusing? Perhaps,
// but it's compatible with what we did before we implemented XBL fields using
// this technique.
inline bool
FieldAccessorGuard(JSContext *cx, unsigned argc, JS::Value *vp, JSNative native, JSObject **thisObj)
{
JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
if (!obj) {
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
return false;
}
if (didInstall) {
*objp = origObj;
if (ObjectHasISupportsPrivate(obj)) {
*thisObj = obj;
return true;
}
// else we didn't resolve this field after all
return JS_TRUE;
// |this| wasn't an unwrapped object passing the has-private-nsISupports test.
// So try to unwrap |this| and recursively call the native on it.
//
// This |protoClass| gunk is needed for the JS engine to report an error if an
// object of the wrong class was passed as |this|, so that it can complain
// that it expected an object of type |protoClass|. It would be better if the
// error didn't try to specify the expected class of objects -- particularly
// because there's no one class of objects -- but it's what the API wants, so
// pass a class that's marginally correct as an answer.
JSClass* protoClass;
{
JS::Rooted<JSObject*> callee(cx, &JS_CALLEE(cx, vp).toObject());
JS::Rooted<JSObject*> xblProto(cx);
xblProto = &js::GetFunctionNativeReserved(callee, XBLPROTO_SLOT).toObject();
JSAutoEnterCompartment ac;
if (!ac.enter(cx, xblProto)) {
return false;
}
protoClass = ::JS_GetClass(xblProto);
}
*thisObj = NULL;
return JS_CallNonGenericMethodOnProxy(cx, argc, vp, native, protoClass);
}
static JSBool
FieldGetter(JSContext *cx, unsigned argc, JS::Value *vp)
{
JS::Rooted<JSObject*> thisObj(cx);
if (!FieldAccessorGuard(cx, argc, vp, FieldGetter, thisObj.address())) {
return false;
}
if (!thisObj) {
return true; // FieldGetter was recursively invoked on an unwrapped |this|
}
bool installed = false;
JS::Rooted<JSObject*> callee(cx, &JS_CALLEE(cx, vp).toObject());
JS::Rooted<jsid> id(cx);
if (!InstallXBLField(cx, callee, thisObj, id.address(), &installed)) {
return false;
}
if (!installed) {
JS_SET_RVAL(cx, vp, JS::UndefinedValue());
return true;
}
JS::Rooted<JS::Value> v(cx);
if (!JS_GetPropertyById(cx, thisObj, id, v.address())) {
return false;
}
JS_SET_RVAL(cx, vp, v);
return true;
}
static JSBool
FieldSetter(JSContext *cx, unsigned argc, JS::Value *vp)
{
JS::Rooted<JSObject*> thisObj(cx);
if (!FieldAccessorGuard(cx, argc, vp, FieldSetter, thisObj.address())) {
return false;
}
if (!thisObj) {
return true; // FieldSetter was recursively invoked on an unwrapped |this|
}
bool installed = false;
JS::Rooted<JSObject*> callee(cx, &JS_CALLEE(cx, vp).toObject());
JS::Rooted<jsid> id(cx);
if (!InstallXBLField(cx, callee, thisObj, id.address(), &installed)) {
return false;
}
JS::Rooted<JS::Value> v(cx,
argc > 0 ? JS_ARGV(cx, vp)[0] : JS::UndefinedValue());
return JS_SetPropertyById(cx, thisObj, id, v.address());
}
static JSBool
XBLResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
JSObject **objp)
{
*objp = NULL;
if (!JSID_IS_STRING(id)) {
return true;
}
nsXBLPrototypeBinding* protoBinding =
static_cast<nsXBLPrototypeBinding*>(::JS_GetReservedSlot(obj, 0).toPrivate());
MOZ_ASSERT(protoBinding);
// If the field's not present, don't resolve it. Also don't resolve it if the
// field is empty; see also nsXBLProtoImplField::InstallField which also must
// implement the not-empty requirement.
nsDependentJSString fieldName(id);
nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
if (!field || field->IsEmpty()) {
return true;
}
// We have a field: now install a getter/setter pair which will resolve the
// field onto the actual object, when invoked.
JS::Rooted<JSObject*> global(cx, JS_GetGlobalForObject(cx, obj));
JS::Rooted<JSObject*> get(cx);
get = ::JS_GetFunctionObject(js::NewFunctionByIdWithReserved(cx, FieldGetter,
0, 0, global,
id));
if (!get) {
return false;
}
js::SetFunctionNativeReserved(get, XBLPROTO_SLOT, JS::ObjectValue(*obj));
js::SetFunctionNativeReserved(get, FIELD_SLOT,
JS::StringValue(JSID_TO_STRING(id)));
JS::Rooted<JSObject*> set(cx);
set = ::JS_GetFunctionObject(js::NewFunctionByIdWithReserved(cx, FieldSetter,
1, 0, global,
id));
if (!set) {
return false;
}
js::SetFunctionNativeReserved(set, XBLPROTO_SLOT, JS::ObjectValue(*obj));
js::SetFunctionNativeReserved(set, FIELD_SLOT,
JS::StringValue(JSID_TO_STRING(id)));
if (!::JS_DefinePropertyById(cx, obj, id, JS::UndefinedValue(),
JS_DATA_TO_FUNC_PTR(JSPropertyOp,
get.reference()),
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp,
set.reference()),
field->AccessorAttributes())) {
return false;
}
*objp = obj;
return true;
}
static JSBool
XBLEnumerate(JSContext *cx, JS::Handle<JSObject*> obj)
{
nsXBLPrototypeBinding* protoBinding =
static_cast<nsXBLPrototypeBinding*>(::JS_GetReservedSlot(obj, 0).toPrivate());
MOZ_ASSERT(protoBinding);
return protoBinding->ResolveAllFields(cx, obj);
}
nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName)
@ -179,12 +408,12 @@ nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName)
name = ToNewCString(aClassName);
flags =
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
JSCLASS_NEW_RESOLVE | JSCLASS_NEW_RESOLVE_GETS_START |
JSCLASS_NEW_RESOLVE |
// Our one reserved slot holds the relevant nsXBLPrototypeBinding
JSCLASS_HAS_RESERVED_SLOTS(1);
addProperty = delProperty = getProperty = ::JS_PropertyStub;
setProperty = ::JS_StrictPropertyStub;
enumerate = ::JS_EnumerateStub;
enumerate = XBLEnumerate;
resolve = (JSResolveOp)XBLResolve;
convert = ::JS_ConvertStub;
finalize = XBLFinalize;

View File

@ -88,7 +88,8 @@ nsXBLProtoImplField::InstallField(nsIScriptContext* aContext,
*aDidInstall = false;
if (mFieldTextLength == 0) {
// Empty fields are treated as not actually present.
if (IsEmpty()) {
return NS_OK;
}

View File

@ -41,6 +41,13 @@ public:
const PRUnichar* GetName() const { return mName; }
unsigned AccessorAttributes() const {
return JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER |
(mJSAttributes & (JSPROP_ENUMERATE | JSPROP_PERMANENT));
}
bool IsEmpty() const { return mFieldTextLength == 0; }
protected:
nsXBLProtoImplField* mNext;
PRUnichar* mName;

View File

@ -116,8 +116,9 @@ addLoadEvent(function() {
is(found, true, "Enumeration is broken");
is(d.four, 9, "Shouldn't have rerun field six");
is(d.five, 5, "Should have run field 7");
is(d.five, 11, "Shouldn't have run field 7");
is(d.seven, 7, "Should be 7")
is(d.five, 5, "Should have run field 7");
d = $("display2");
is(typeof(d.eight), "undefined", "Recursive resolve should bail out");

View File

@ -648,6 +648,7 @@ ConvertLoadTypeToNavigationType(PRUint32 aLoadType)
case LOAD_NORMAL_REPLACE:
case LOAD_LINK:
case LOAD_STOP_CONTENT:
case LOAD_REPLACE_BYPASS_CACHE:
result = nsIDOMPerformanceNavigation::TYPE_NAVIGATE;
break;
case LOAD_HISTORY:
@ -1141,6 +1142,9 @@ ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType)
case nsIDocShellLoadInfo::loadPushState:
loadType = LOAD_PUSHSTATE;
break;
case nsIDocShellLoadInfo::loadReplaceBypassCache:
loadType = LOAD_REPLACE_BYPASS_CACHE;
break;
default:
NS_NOTREACHED("Unexpected nsDocShellInfoLoadType value");
}
@ -1209,6 +1213,9 @@ nsDocShell::ConvertLoadTypeToDocShellLoadInfo(PRUint32 aLoadType)
case LOAD_PUSHSTATE:
docShellLoadType = nsIDocShellLoadInfo::loadPushState;
break;
case LOAD_REPLACE_BYPASS_CACHE:
docShellLoadType = nsIDocShellLoadInfo::loadReplaceBypassCache;
break;
default:
NS_NOTREACHED("Unexpected load type value");
}
@ -5923,6 +5930,7 @@ nsDocShell::Embed(nsIContentViewer * aContentViewer,
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_REPLACE_BYPASS_CACHE:
updateHistory = false;
break;
default:
@ -9226,6 +9234,7 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_REPLACE_BYPASS_CACHE:
loadFlags |= nsIRequest::LOAD_BYPASS_CACHE |
nsIRequest::LOAD_FRESH_CONNECTION;
break;

View File

@ -60,6 +60,7 @@ enum LoadType {
LOAD_STOP_CONTENT = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_STOP_CONTENT),
LOAD_STOP_CONTENT_AND_REPLACE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_STOP_CONTENT | nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY),
LOAD_PUSHSTATE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_PUSHSTATE, nsIWebNavigation::LOAD_FLAGS_NONE),
LOAD_REPLACE_BYPASS_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY | nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
/**
* Load type for an error page. These loads are never triggered by users of
* Docshell. Instead, Docshell triggers the load itself when a
@ -91,6 +92,7 @@ static inline bool IsValidLoadType(PRUint32 aLoadType)
case LOAD_STOP_CONTENT:
case LOAD_STOP_CONTENT_AND_REPLACE:
case LOAD_PUSHSTATE:
case LOAD_REPLACE_BYPASS_CACHE:
case LOAD_ERROR_PAGE:
return true;
}

View File

@ -60,6 +60,7 @@ interface nsIDocShellLoadInfo : nsISupports
const long loadNormalBypassProxy = 15;
const long loadNormalBypassProxyAndCache = 16;
const long loadPushState = 17; // history.pushState or replaceState
const long loadReplaceBypassCache = 18;
/** Contains a load type as specified by the load* constants */
attribute nsDocShellInfoLoadType loadType;

View File

@ -37,8 +37,8 @@ function convertAppsArray(aApps, aWindow) {
let apps = Cu.createArrayIn(aWindow);
for (let i = 0; i < aApps.length; i++) {
let app = aApps[i];
apps.push(new WebappsApplication(aWindow, app.origin, app.manifest, app.manifestURL,
app.receipts, app.installOrigin, app.installTime));
apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
app.receipts, app.installOrigin, app.installTime));
}
return apps;
@ -49,6 +49,12 @@ function WebappsRegistry() {
WebappsRegistry.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
__exposedProps__: {
install: 'r',
getSelf: 'r',
getInstalled: 'r',
mgmt: 'r'
},
/** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest
* only the name property is mandatory
@ -76,8 +82,8 @@ WebappsRegistry.prototype = {
let app = msg.app;
switch (aMessage.name) {
case "Webapps:Install:Return:OK":
Services.DOMRequest.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime));
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime));
break;
case "Webapps:Install:Return:KO":
Services.DOMRequest.fireError(req, "DENIED");
@ -85,8 +91,8 @@ WebappsRegistry.prototype = {
case "Webapps:GetSelf:Return:OK":
if (msg.apps.length) {
app = msg.apps[0];
Services.DOMRequest.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime));
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime));
} else {
Services.DOMRequest.fireSuccess(req, null);
}
@ -200,63 +206,57 @@ WebappsRegistry.prototype = {
/**
* mozIDOMApplication object
*/
function WebappsApplication(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
this._origin = aOrigin;
this._manifestURL = aManifestURL;
this._manifest = wrapObjectIn(aManifest, aWindow);
this._receipts = aReceipts;
this._installOrigin = aInstallOrigin;
this._installTime = aInstallTime;
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO"]);
function createApplicationObject(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
let app = Cc["@mozilla.org/webapps/application;1"].createInstance(Ci.mozIDOMApplication);
app.wrappedJSObject.init(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime);
return app;
}
function WebappsApplication() {
this.wrappedJSObject = this;
}
WebappsApplication.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
_origin: null,
_manifest: null,
_manifestURL: null,
_receipts: [],
_installOrigin: null,
_installTime: 0,
__exposedProps__: {
origin: 'r',
manifest: 'r',
manifestURL: 'r',
installOrigin: 'r',
installTime: 'r',
status: 'r',
progress: 'r',
onprogress: 'rw',
launch: 'r',
receipts: 'r',
uninstall: 'r'
},
get origin() {
return this._origin;
init: function(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
this.origin = aOrigin;
this.manifest = wrapObjectIn(aManifest, aWindow);
this.manifestURL = aManifestURL;
this.receipts = aReceipts;
this.installOrigin = aInstallOrigin;
this.installTime = aInstallTime;
this.status = "installed";
this.progress = NaN;
this._onprogress = null;
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO", "Webapps:OfflineCache"]);
},
get manifest() {
return this._manifest;
set onprogress(aCallback) {
this._onprogress = aCallback;
},
get manifestURL() {
return this._manifestURL;
},
get receipts() {
return this._receipts;
},
get installOrigin() {
return this._installOrigin;
},
get installTime() {
return this._installTime;
get onprogress() {
return this._onprogress;
},
launch: function(aStartPoint) {
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this._origin,
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this.origin,
startPoint: aStartPoint || "",
oid: this._id,
requestID: this.getRequestId(request) });
@ -265,16 +265,20 @@ WebappsApplication.prototype = {
uninstall: function() {
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this._origin,
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this.origin,
oid: this._id,
requestID: this.getRequestId(request) });
return request;
},
uninit: function() {
this._onprogress = null;
},
receiveMessage: function(aMessage) {
var msg = aMessage.json;
let req = this.getRequest(msg.requestID);
if (msg.oid != this._id || !req)
let req = this.takeRequest(msg.requestID);
if ((msg.oid != this._id || !req) && aMessage.name !== "Webapps:OfflineCache")
return;
switch (aMessage.name) {
case "Webapps:Uninstall:Return:OK":
@ -283,8 +287,17 @@ WebappsApplication.prototype = {
case "Webapps:Uninstall:Return:KO":
Services.DOMRequest.fireError(req, "NOT_INSTALLED");
break;
case "Webapps:OfflineCache":
if (msg.manifest != this.manifestURL)
return;
this.status = msg.status;
if (this._onprogress) {
let event = new this._window.MozApplicationEvent("applicationinstall", { application: this });
this._onprogress.handleEvent(event);
}
break;
}
this.removeRequest(msg.requestID);
},
classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
@ -321,6 +334,11 @@ function WebappsApplicationMgmt(aWindow) {
WebappsApplicationMgmt.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
__exposedProps__: {
getAll: 'r',
oninstall: 'rw',
onuninstall: 'rw'
},
uninit: function() {
this._oninstall = null;
@ -376,7 +394,7 @@ WebappsApplicationMgmt.prototype = {
if (this._oninstall) {
let app = msg.app;
let event = new this._window.MozApplicationEvent("applicationinstall",
{ application : new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
{ application : createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime) });
this._oninstall.handleEvent(event);
}
@ -384,7 +402,7 @@ WebappsApplicationMgmt.prototype = {
case "Webapps:Uninstall:Return:OK":
if (this._onuninstall) {
let event = new this._window.MozApplicationEvent("applicationuninstall",
{ application : new WebappsApplication(this._window, msg.origin, null, null, null, null, 0) });
{ application : createApplicationObject(this._window, msg.origin, null, null, null, null, 0) });
this._onuninstall.handleEvent(event);
}
break;

View File

@ -156,7 +156,9 @@ let DOMApplicationRegistry = {
origin: aApp.origin,
receipts: aApp.receipts,
installTime: aApp.installTime,
manifestURL: aApp.manifestURL
manifestURL: aApp.manifestURL,
progress: aApp.progress || 0.0,
status: aApp.status || "installed"
};
return clone;
},
@ -165,7 +167,7 @@ let DOMApplicationRegistry = {
ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
},
confirmInstall: function(aData, aFromSync) {
confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
let app = aData.app;
let id = app.syncId || this._appId(app.origin);
@ -191,11 +193,29 @@ let DOMApplicationRegistry = {
this._writeFile(manFile, JSON.stringify(app.manifest));
this.webapps[id] = appObject;
appObject.status = "installed";
let manifest = new DOMApplicationManifest(app.manifest, app.origin);
if (!aFromSync)
this._saveApps((function() {
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
}).bind(this));
// if the manifest has an appcache_path property, use it to populate the appcache
if (manifest.appcache_path) {
let appcacheURI = Services.io.newURI(manifest.fullAppcachePath(), null, null);
let updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"]
.getService(Ci.nsIOfflineCacheUpdateService);
let docURI = Services.io.newURI(manifest.fullLaunchPath(), null, null);
let cacheUpdate = aProfileDir ? updateService.scheduleCustomProfileUpdate(appcacheURI, docURI, aProfileDir)
: updateService.scheduleUpdate(appcacheURI, docURI, null);
cacheUpdate.addObserver(new AppcacheObserver(appObject), false);
if (aOfflineCacheObserver) {
cacheUpdate.addObserver(aOfflineCacheObserver, false);
}
}
},
_appId: function(aURI) {
@ -428,6 +448,53 @@ let DOMApplicationRegistry = {
}
};
/**
* Appcache download observer
*/
AppcacheObserver = function(aApp) {
this.app = aApp;
};
AppcacheObserver.prototype = {
// nsIOfflineCacheUpdateObserver implementation
updateStateChanged: function appObs_Update(aUpdate, aState) {
let mustSave = false;
let app = this.app;
let setStatus = function appObs_setStatus(aStatus) {
mustSave = (app.status != aStatus);
app.status = aStatus;
ppmm.sendAsyncMessage("Webapps:OfflineCache", { manifest: app.manifestURL, status: aStatus });
}
switch (aState) {
case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
aUpdate.removeObserver(this);
setStatus("cache-error");
break;
case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
case Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED:
aUpdate.removeObserver(this);
setStatus("cached");
break;
case Ci.nsIOfflineCacheUpdateObserver.STATE_DOWNLOADING:
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED:
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMPROGRESS:
setStatus("downloading")
break;
}
// Status changed, update the stored version.
if (mustSave) {
DOMApplicationRegistry._saveApps();
}
},
applicationCacheAvailable: function appObs_CacheAvail(aApplicationCache) {
// Nothing to do.
}
};
/**
* Helper object to access manifest information with locale support
*/
@ -481,6 +548,10 @@ DOMApplicationManifest.prototype = {
return this._localeProp("icons");
},
get appcache_path() {
return this._localeProp("appcache_path");
},
iconURLForSize: function(aSize) {
let icons = this._localeProp("icons");
if (!icons)
@ -501,6 +572,11 @@ DOMApplicationManifest.prototype = {
let startPoint = aStartPoint || "";
let launchPath = this._localeProp("launch_path") || "";
return this._origin.resolve(launchPath + startPoint);
},
fullAppcachePath: function() {
let appcachePath = this._localeProp("appcache_path");
return this._origin.resolve(appcachePath ? appcachePath : "");
}
};

View File

@ -2,3 +2,6 @@
component {fff440b3-fae2-45c1-bf03-3b5a2e432270} Webapps.js
contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270}
category JavaScript-navigator-property mozApps @mozilla.org/webapps;1
component {723ed303-7757-4fb0-b261-4f78b1f6bd22} Webapps.js
contract @mozilla.org/webapps/application;1 {723ed303-7757-4fb0-b261-4f78b1f6bd22}

View File

@ -574,8 +574,7 @@ static const char kDOMStringBundleURL[] =
#define ELEMENT_SCRIPTABLE_FLAGS \
((NODE_SCRIPTABLE_FLAGS & ~nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY) | \
nsIXPCScriptable::WANT_POSTCREATE | \
nsIXPCScriptable::WANT_ENUMERATE)
nsIXPCScriptable::WANT_POSTCREATE)
#define EXTERNAL_OBJ_SCRIPTABLE_FLAGS \
((ELEMENT_SCRIPTABLE_FLAGS & \
@ -8188,27 +8187,6 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
NS_IMETHODIMP
nsElementSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, bool *_retval)
{
// Make sure to not call the superclass here!
nsCOMPtr<nsIContent> content(do_QueryWrappedNative(wrapper, obj));
NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED);
nsIDocument* doc = content->OwnerDoc();
nsRefPtr<nsXBLBinding> binding = doc->BindingManager()->GetBinding(content);
if (!binding) {
// Nothing else to do here
return NS_OK;
}
*_retval = binding->ResolveAllFields(cx, obj);
return NS_OK;
}
// Generic array scriptable helper.
@ -8557,21 +8535,9 @@ nsDOMStringMapSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
nsDOMStringMap* dataset = static_cast<nsDOMStringMap*>(nativeObj);
nsIDocument* document = dataset->GetElement()->OwnerDoc();
nsCOMPtr<nsIScriptGlobalObject> sgo =
do_GetInterface(document->GetScopeObject());
if (sgo) {
JSObject *global = sgo->GetGlobalJSObject();
if (global) {
*parentObj = global;
return NS_OK;
}
}
return NS_OK;
// Parent the string map to its element.
nsINode* element = dataset->GetElement();
return WrapNativeParent(cx, globalObj, element, element, parentObj);
}
NS_IMETHODIMP

View File

@ -562,8 +562,6 @@ public:
JSObject *globalObj, JSObject **parentObj);
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj);
NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, bool *_retval);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{

View File

@ -492,6 +492,7 @@ nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
PRInt32 aModifiers,
bool aIgnoreRootScrollFrame)
{
SAMPLE_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow");
return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
aIgnoreRootScrollFrame, true);
}
@ -1825,13 +1826,13 @@ nsDOMWindowUtils::GetParent(const JS::Value& aObject,
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
JSObject* parent = JS_GetParent(JSVAL_TO_OBJECT(aObject));
JS::Rooted<JSObject*> parent(aCx, JS_GetParent(JSVAL_TO_OBJECT(aObject)));
*aParent = OBJECT_TO_JSVAL(parent);
// Outerize if necessary.
if (parent) {
if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
*aParent = OBJECT_TO_JSVAL(outerize(aCx, JS::RootedObject(aCx, parent)));
*aParent = OBJECT_TO_JSVAL(outerize(aCx, parent));
}
}

View File

@ -1090,6 +1090,7 @@ nsGlobalWindow::FreeInnerObjects()
}
if (mScreen) {
mScreen->Reset();
mScreen = nsnull;
}

View File

@ -63,8 +63,25 @@ nsScreen::nsScreen()
{
}
void
nsScreen::Reset()
{
hal::UnlockScreenOrientation();
if (mEventListener) {
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
if (target) {
target->RemoveSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
mEventListener, true);
}
mEventListener = nsnull;
}
}
nsScreen::~nsScreen()
{
Reset();
hal::UnregisterScreenConfigurationObserver(this);
}
@ -318,6 +335,7 @@ NS_IMETHODIMP
nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
{
ScreenOrientation orientation;
*aReturn = false;
if (aOrientation.EqualsLiteral("portrait")) {
orientation = eScreenOrientation_Portrait;
@ -332,37 +350,31 @@ nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
} else if (aOrientation.EqualsLiteral("landscape-secondary")) {
orientation = eScreenOrientation_LandscapeSecondary;
} else {
*aReturn = false;
return NS_OK;
}
if (!GetOwner()) {
*aReturn = false;
return NS_OK;
}
if (!IsChromeType(GetOwner()->GetDocShell())) {
// Chrome code and apps can always lock the screen orientation.
if (!IsChromeType(GetOwner()->GetDocShell()) &&
!static_cast<nsGlobalWindow*>(GetOwner())->IsPartOfApp()) {
nsCOMPtr<nsIDOMDocument> doc;
GetOwner()->GetDocument(getter_AddRefs(doc));
if (!doc) {
*aReturn = false;
return NS_OK;
}
// Apps and frames contained in apps can lock orientation.
// But non-apps can lock orientation only if they're fullscreen.
if (!static_cast<nsGlobalWindow*>(GetOwner())->IsPartOfApp()) {
bool fullscreen;
doc->GetMozFullScreen(&fullscreen);
if (!fullscreen) {
*aReturn = false;
return NS_OK;
}
// Non-apps content can lock orientation only if fullscreen.
bool fullscreen;
doc->GetMozFullScreen(&fullscreen);
if (!fullscreen) {
return NS_OK;
}
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
if (!target) {
*aReturn = false;
return NS_OK;
}

View File

@ -26,7 +26,7 @@ class nsScreen : public nsDOMEventTargetHelper
public:
static already_AddRefed<nsScreen> Create(nsPIDOMWindow* aWindow);
void Invalidate();
void Reset();
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMSCREEN

View File

@ -2118,7 +2118,8 @@ if (!%(resultStr)s) {
"resultStr" : result + "_str",
"strings" : type.inner.identifier.name + "Values::strings" } + setValue("JS::StringValue(%s_str)" % result)
if type.isCallback() and not type.isInterface():
if type.isCallback():
assert not type.isInterface()
# XXXbz we're going to assume that callback types are always
# nullable and always have [TreatNonCallableAsNull] for now.
# See comments in WrapNewBindingObject explaining why we need
@ -2622,8 +2623,7 @@ class CGMethodCall(CGThing):
interfacesSigs = [
s for s in possibleSignatures
if (s[1][distinguishingIndex].type.isObject() or
(s[1][distinguishingIndex].type.isInterface() and
not s[1][distinguishingIndex].type.isCallback())) ]
s[1][distinguishingIndex].type.isNonCallbackInterface()) ]
# There might be more than one of these; we need to check
# which ones we unwrap to.
@ -2692,6 +2692,7 @@ class CGMethodCall(CGThing):
pickFirstSignature("%s.isObject() && !IsPlatformObject(cx, &%s.toObject())" %
(distinguishingArg, distinguishingArg),
lambda s: (s[1][distinguishingIndex].type.isCallback() or
s[1][distinguishingIndex].type.isCallbackInterface() or
s[1][distinguishingIndex].type.isDictionary() or
s[1][distinguishingIndex].type.isObject()))

View File

@ -426,6 +426,13 @@ class IDLInterface(IDLObjectWithScope):
for iface in self.implementedInterfaces:
iface.finish(scope)
cycleInGraph = self.findInterfaceLoopPoint(self)
if cycleInGraph:
raise WebIDLError("Interface %s has itself as ancestor or "
"implemented interface" % self.identifier.name,
self.location,
extraLocation=cycleInGraph.location)
# Now resolve() and finish() our members before importing the
# ones from our implemented interfaces.
@ -594,6 +601,26 @@ class IDLInterface(IDLObjectWithScope):
return consequentialInterfaces | temp
def findInterfaceLoopPoint(self, otherInterface):
"""
Finds an interface, amongst our ancestors and consequential interfaces,
that inherits from otherInterface or implements otherInterface
directly. If there is no such interface, returns None.
"""
if self.parent:
if self.parent == otherInterface:
return self
loopPoint = self.parent.findInterfaceLoopPoint(otherInterface)
if loopPoint:
return loopPoint
if otherInterface in self.implementedInterfaces:
return self
for iface in self.implementedInterfaces:
loopPoint = iface.findInterfaceLoopPoint(otherInterface)
if loopPoint:
return loopPoint
return None
class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
@ -761,6 +788,12 @@ class IDLType(IDLObject):
def isTypedArray(self):
return False
def isCallbackInterface(self):
return False
def isNonCallbackInterface(self):
return False
def isGeckoInterface(self):
""" Returns a boolean indicating whether this type is an 'interface'
type that is implemented in Gecko. At the moment, this returns
@ -908,6 +941,12 @@ class IDLNullableType(IDLType):
def isInterface(self):
return self.inner.isInterface()
def isCallbackInterface(self):
return self.inner.isCallbackInterface()
def isNonCallbackInterface(self):
return self.inner.isNonCallbackInterface()
def isEnum(self):
return self.inner.isEnum()
@ -998,7 +1037,7 @@ class IDLSequenceType(IDLType):
def isDistinguishableFrom(self, other):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isDictionary() or other.isDate() or
(other.isInterface() and not other.isCallback()))
other.isNonCallbackInterface())
class IDLArrayType(IDLType):
def __init__(self, location, parameterType):
@ -1071,7 +1110,7 @@ class IDLArrayType(IDLType):
def isDistinguishableFrom(self, other):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isDictionary() or other.isDate() or
(other.isInterface() and not other.isCallback()))
other.isNonCallbackInterface())
class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def __init__(self, location, innerType, name):
@ -1124,6 +1163,12 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def isInterface(self):
return self.inner.isInterface()
def isCallbackInterface(self):
return self.inner.isCallbackInterface()
def isNonCallbackInterface(self):
return self.inner.isNonCallbackInterface()
def resolve(self, parentScope):
assert isinstance(parentScope, IDLScope)
IDLObjectWithIdentifier.resolve(self, parentScope)
@ -1177,6 +1222,12 @@ class IDLWrapperType(IDLType):
return isinstance(self.inner, IDLInterface) or \
isinstance(self.inner, IDLExternalInterface)
def isCallbackInterface(self):
return self.isInterface() and self.inner.isCallback()
def isNonCallbackInterface(self):
return self.isInterface() and not self.inner.isCallback()
def isEnum(self):
return isinstance(self.inner, IDLEnum)
@ -1198,7 +1249,7 @@ class IDLWrapperType(IDLType):
assert False
def isDistinguishableFrom(self, other):
assert self.isInterface() or self.isEnum()
assert self.isInterface() or self.isEnum() or self.isDictionary()
if self.isEnum():
return (other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
@ -1206,15 +1257,20 @@ class IDLWrapperType(IDLType):
other.isDate())
if other.isPrimitive() or other.isString() or other.isEnum():
return True
if self.isDictionary():
return (other.isNonCallbackInterface() or other.isSequence() or
other.isArray() or other.isDate())
assert self.isInterface()
# XXXbz need to check that the interfaces can't be implemented
# by the same object
if other.isInterface():
return (self != other and
(not self.isCallback() or not other.isCallback()))
if other.isDictionary() or other.isCallback():
return not self.isCallback()
if other.isSequence() or other.isArray():
return not self.isCallback()
(self.isNonCallbackInterface() or
other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or
other.isSequence() or other.isArray()):
return self.isNonCallbackInterface()
class IDLBuiltinType(IDLType):
@ -1314,6 +1370,10 @@ class IDLBuiltinType(IDLType):
self.isArrayBufferView() or \
self.isTypedArray()
def isNonCallbackInterface(self):
# All the interfaces we can be are non-callback
return self.isInterface()
def isFloat(self):
return self._typeTag == IDLBuiltinType.Types.float or \
self._typeTag == IDLBuiltinType.Types.double
@ -1347,7 +1407,7 @@ class IDLBuiltinType(IDLType):
other.isSequence() or other.isArray() or other.isDate() or
(other.isInterface() and (
# ArrayBuffer is distinguishable from everything
# that's not an ArrayBuffer
# that's not an ArrayBuffer or a callback interface
(self.isArrayBuffer() and not other.isArrayBuffer()) or
# ArrayBufferView is distinguishable from everything
# that's not an ArrayBufferView or typed array.
@ -1681,8 +1741,7 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
def isDistinguishableFrom(self, other):
return (other.isPrimitive() or other.isString() or other.isEnum() or
(other.isInterface() and not other.isCallback()) or
other.isDate())
other.isNonCallbackInterface() or other.isDate())
class IDLMethod(IDLInterfaceMember, IDLScope):

View File

@ -1,5 +1,3 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
dictionary Dict2 : Dict1 {
@ -29,7 +27,7 @@ def WebIDLTest(parser, harness):
"'a' really comes before 'c'")
# Now reset our parser
parser = WebIDL.Parser()
parser = parser.reset()
threw = False
try:
parser.parse("""
@ -45,7 +43,7 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Should not allow name duplication in a dictionary")
# Now reset our parser again
parser = WebIDL.Parser()
parser = parser.reset()
threw = False
try:
parser.parse("""
@ -67,7 +65,7 @@ def WebIDLTest(parser, harness):
"its ancestor")
# More reset
parser = WebIDL.Parser()
parser = parser.reset()
threw = False
try:
parser.parse("""
@ -83,7 +81,7 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
# Even more reset
parser = WebIDL.Parser()
parser = parser.reset()
threw = False
try:
parser.parse("""

View File

@ -0,0 +1,33 @@
def WebIDLTest(parser, harness):
parser.parse("""
dictionary Dict {
};
callback interface Foo {
};
interface Bar {
// Bit of a pain to get things that have dictionary types
void passDict(Dict arg);
void passFoo(Foo arg);
};
""")
results = parser.finish()
iface = results[2]
harness.ok(iface.isInterface(), "Should have interface")
dictMethod = iface.members[0]
ifaceMethod = iface.members[1]
def firstArgType(method):
return method.signatures()[0][1][0].type
dictType = firstArgType(dictMethod)
ifaceType = firstArgType(ifaceMethod)
harness.ok(dictType.isDictionary(), "Should have dictionary type");
harness.ok(ifaceType.isInterface(), "Should have interface type");
harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type");
harness.ok(not dictType.isDistinguishableFrom(ifaceType),
"Dictionary not distinguishable from callback interface")
harness.ok(not ifaceType.isDistinguishableFrom(dictType),
"Callback interface not distinguishable from dictionary")

View File

@ -52,3 +52,124 @@ def WebIDLTest(parser, harness):
"Member has the right QName")
harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar",
"Member has the right QName")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B : A {};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow cycles in interface inheritance chains")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : C {};
interface C : B {};
interface B : A {};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirect cycles in interface inheritance chains")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {};
interface B {};
A implements B;
B implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow cycles via implements")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {};
interface C {};
interface B {};
A implements C;
C implements B;
B implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirect cycles via implements")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B {};
B implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow inheriting from an interface that implements us")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B {};
interface C {};
B implements C;
C implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow inheriting from an interface that indirectly implements us")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B : C {};
interface C {};
C implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirectly inheriting from an interface that implements us")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B : C {};
interface C {};
interface D {};
C implements D;
D implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirectly inheriting from an interface that indirectly implements us")

View File

@ -297,6 +297,7 @@ DiamondBranch1A implements DiamondImplements;
DiamondBranch1B implements DiamondImplements;
dictionary Dict : ParentDict {
TestEnum someEnum;
long x;
long a;
long b = 8;

View File

@ -111,6 +111,10 @@ BrowserElementChild.prototype = {
addMsgListener("get-screenshot", this._recvGetScreenshot);
addMsgListener("set-visible", this._recvSetVisible);
addMsgListener("get-can-go-back", this._recvCanGoBack);
addMsgListener("get-can-go-forward", this._recvCanGoForward);
addMsgListener("go-back", this._recvGoBack);
addMsgListener("go-forward", this._recvGoForward);
addMsgListener("unblock-modal-prompt", this._recvStopWaiting);
let els = Cc["@mozilla.org/eventlistenerservice;1"]
@ -320,7 +324,7 @@ BrowserElementChild.prototype = {
content.innerHeight, "rgb(255,255,255)");
sendAsyncMsg('got-screenshot', {
id: data.json.id,
screenshot: canvas.toDataURL("image/png")
rv: canvas.toDataURL("image/png")
});
},
@ -331,6 +335,38 @@ BrowserElementChild.prototype = {
}
},
_recvCanGoBack: function(data) {
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
sendAsyncMsg('got-can-go-back', {
id: data.json.id,
rv: webNav.canGoBack
});
},
_recvCanGoForward: function(data) {
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
sendAsyncMsg('got-can-go-forward', {
id: data.json.id,
rv: webNav.canGoForward
});
},
_recvGoBack: function(data) {
try {
docShell.QueryInterface(Ci.nsIWebNavigation).goBack();
} catch(e) {
// Silently swallow errors; these happen when we can't go back.
}
},
_recvGoForward: function(data) {
try {
docShell.QueryInterface(Ci.nsIWebNavigation).goForward();
} catch(e) {
// Silently swallow errors; these happen when we can't go forward.
}
},
_keyEventHandler: function(e) {
if (whitelistedEvents.indexOf(e.keyCode) != -1 && !e.defaultPrevented) {
sendAsyncMsg('keyevent', {

View File

@ -120,8 +120,8 @@ BrowserElementParentFactory.prototype = {
function BrowserElementParent(frameLoader) {
debug("Creating new BrowserElementParent object for " + frameLoader);
this._screenshotListeners = {};
this._screenshotReqCounter = 0;
this._domRequestCounter = 0;
this._pendingDOMRequests = {};
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
if (!this._frameElement) {
@ -150,18 +150,25 @@ function BrowserElementParent(frameLoader) {
addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
addMessageListener("keyevent", this._fireKeyEvent);
addMessageListener("showmodalprompt", this._handleShowModalPrompt);
addMessageListener('got-screenshot', this._recvGotScreenshot);
addMessageListener('got-screenshot', this._gotDOMRequestResult);
addMessageListener('got-can-go-back', this._gotDOMRequestResult);
addMessageListener('got-can-go-forward', this._gotDOMRequestResult);
function defineMethod(name, fn) {
XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self);
}
// Define methods on the frame element.
defineMethod('getScreenshot', this._getScreenshot);
defineMethod('setVisible', this._setVisible);
function defineDOMRequestMethod(domName, msgName) {
XPCNativeWrapper.unwrap(self._frameElement)[domName] = self._sendDOMRequest.bind(self, msgName);
}
this._mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
/* allowDelayedLoad = */ true);
// Define methods on the frame element.
defineMethod('setVisible', this._setVisible);
defineMethod('goBack', this._goBack);
defineMethod('goForward', this._goForward);
defineDOMRequestMethod('getScreenshot', 'get-screenshot');
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
}
BrowserElementParent.prototype = {
@ -265,25 +272,49 @@ BrowserElementParent.prototype = {
return this._frameElement.getAttribute('mozapp');
},
_getScreenshot: function() {
let id = 'req_' + this._screenshotReqCounter++;
/**
* Kick off a DOMRequest in the child process.
*
* We'll fire an event called |msgName| on the child process, passing along
* an object with a single field, id, containing the ID of this request.
*
* We expect the child to pass the ID back to us upon completion of the
* request; see _gotDOMRequestResult.
*/
_sendDOMRequest: function(msgName) {
let id = 'req_' + this._domRequestCounter++;
let req = Services.DOMRequest.createRequest(this._window);
this._screenshotListeners[id] = req;
this._sendAsyncMsg('get-screenshot', {id: id});
this._pendingDOMRequests[id] = req;
this._sendAsyncMsg(msgName, {id: id});
return req;
},
_recvGotScreenshot: function(data) {
var req = this._screenshotListeners[data.json.id];
delete this._screenshotListeners[data.json.id];
Services.DOMRequest.fireSuccess(req, data.json.screenshot);
/**
* Called when the child process finishes handling a DOMRequest. We expect
* data.json to have two fields:
*
* - id: the ID of the DOM request (see _sendDOMRequest), and
* - rv: the request's return value.
*
*/
_gotDOMRequestResult: function(data) {
let req = this._pendingDOMRequests[data.json.id];
delete this._pendingDOMRequests[data.json.id];
Services.DOMRequest.fireSuccess(req, data.json.rv);
},
_setVisible: function(visible) {
this._sendAsyncMsg('set-visible', {visible: visible});
},
_goBack: function() {
this._sendAsyncMsg('go-back');
},
_goForward: function() {
this._sendAsyncMsg('go-forward');
},
_fireKeyEvent: function(data) {
let evt = this._window.document.createEvent("KeyboardEvent");
evt.initKeyEvent(data.json.type, true, true, this._window,

View File

@ -58,9 +58,12 @@ _TEST_FILES = \
browserElement_SecurityChange.js \
test_browserElement_inproc_SecurityChange.html \
file_browserElement_SecurityChange.html \
browserElement_BackForward.js \
$(NULL)
# OOP tests don't work on Windows (bug 763081).
#
# Note that there's no inproc equivalent of BackForward; that's intentional.
ifneq ($(OS_ARCH),WINNT)
_TEST_FILES += \
test_browserElement_oop_LoadEvents.html \
@ -78,6 +81,7 @@ _TEST_FILES += \
test_browserElement_oop_OpenWindow.html \
test_browserElement_oop_OpenWindowRejected.html \
test_browserElement_oop_SecurityChange.html \
test_browserElement_oop_BackForward.html \
$(NULL)
endif

View File

@ -101,13 +101,16 @@ const browserElementTestHelpers = {
'origOOPByDefaultPref': null,
'origPageThumbsEnabledPref': null,
// Two basically-empty pages from two different domains you can load.
// Some basically-empty pages from different domains you can load.
'emptyPage1': 'http://example.com' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_empty.html',
'emptyPage2': 'http://example.org' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_empty.html',
'emptyPage3': 'http://test1.example.org' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_empty.html',
'focusPage': 'http://example.org' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_focus.html',

View File

@ -0,0 +1,112 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 741755 - Test that canGo{Back,Forward} and go{Forward,Back} work with
// <iframe mozbrowser>.
"use strict";
SimpleTest.waitForExplicitFinish();
var iframe;
function addOneShotIframeEventListener(event, fn) {
function wrapper(e) {
iframe.removeEventListener(event, wrapper);
fn(e);
};
iframe.addEventListener(event, wrapper);
}
function runTest() {
// At the moment, this isn't going to work unless we're actually out of
// process.
//
// With in-process mozbrowser, the root SHistory for an <iframe mozbrowser>
// crosses the mozbrowser boundary. It's like the mozbrowser wasn't there;
// canGoBack reflects whether the top-level frame can go back, not whether the
// iframe itself can go back.
if (!browserElementTestHelpers.getOOPByDefaultPref()) {
ok(false, "This test only works OOP.");
return;
}
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addToWhitelist();
iframe = document.createElement('iframe');
iframe.mozbrowser = true;
addOneShotIframeEventListener('mozbrowserloadend', function() {
SimpleTest.executeSoon(test2);
});
iframe.src = browserElementTestHelpers.emptyPage1;
document.body.appendChild(iframe);
}
function checkCanGoBackAndForward(canGoBack, canGoForward, nextTest) {
var seenCanGoBackResult = false;
iframe.getCanGoBack().onsuccess = function(e) {
is(seenCanGoBackResult, false, "onsuccess handler shouldn't be called twice.");
seenCanGoBackResult = true;
is(e.target.result, canGoBack);
maybeRunNextTest();
};
var seenCanGoForwardResult = false;
iframe.getCanGoForward().onsuccess = function(e) {
is(seenCanGoForwardResult, false, "onsuccess handler shouldn't be called twice.");
seenCanGoForwardResult = true;
is(e.target.result, canGoForward);
maybeRunNextTest();
};
function maybeRunNextTest() {
if (seenCanGoBackResult && seenCanGoForwardResult) {
nextTest();
}
}
}
function test2() {
checkCanGoBackAndForward(false, false, test3);
}
function test3() {
addOneShotIframeEventListener('mozbrowserloadend', function() {
checkCanGoBackAndForward(true, false, test4);
});
SimpleTest.executeSoon(function() {
iframe.src = browserElementTestHelpers.emptyPage2;
});
}
function test4() {
addOneShotIframeEventListener('mozbrowserlocationchange', function(e) {
is(e.detail, browserElementTestHelpers.emptyPage3);
checkCanGoBackAndForward(true, false, test5);
});
SimpleTest.executeSoon(function() {
iframe.src = browserElementTestHelpers.emptyPage3;
});
}
function test5() {
addOneShotIframeEventListener('mozbrowserlocationchange', function(e) {
is(e.detail, browserElementTestHelpers.emptyPage2);
checkCanGoBackAndForward(true, true, test6);
});
iframe.goBack();
}
function test6() {
addOneShotIframeEventListener('mozbrowserlocationchange', function(e) {
is(e.detail, browserElementTestHelpers.emptyPage1);
checkCanGoBackAndForward(false, true, SimpleTest.finish);
});
iframe.goBack();
}
runTest();

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test of browser element.</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_BackForward.js">
</script>
</body>
</html>

View File

@ -214,8 +214,10 @@ IndexedDatabaseManager::GetOrCreate()
if (sIsMainProcess) {
nsCOMPtr<nsIFile> dbBaseDirectory;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(dbBaseDirectory));
rv = NS_GetSpecialDirectory(NS_APP_INDEXEDDB_PARENT_DIR, getter_AddRefs(dbBaseDirectory));
if (NS_FAILED(rv)) {
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(dbBaseDirectory));
}
NS_ENSURE_SUCCESS(rv, nsnull);
rv = dbBaseDirectory->Append(NS_LITERAL_STRING("indexedDB"));

View File

@ -9,15 +9,34 @@
interface nsIDOMDOMRequest;
interface nsIArray;
[scriptable, uuid(b70b84f1-7ac9-4a92-bc32-8b6a7eb7879e)]
[scriptable, uuid(9583b825-46b1-4e8f-bb48-9fed660a95e6)]
interface mozIDOMApplication : nsISupports
{
readonly attribute jsval manifest;
readonly attribute DOMString manifestURL;
readonly attribute nsIArray receipts; /* an array of strings */
readonly attribute jsval receipts; /* an array of strings */
readonly attribute DOMString origin;
readonly attribute DOMString installOrigin;
readonly attribute unsigned long installTime;
readonly attribute unsigned long long installTime;
/*
* The current progress when downloading an offline cache.
*/
readonly attribute double progress;
/*
* The application status :
* "installed" : The app is in the registry, but we have no offline cache.
* "downlading" : We are downloading the offline cache.
* "cached" : We are done with the offline cache download.
* "cache-error" : An error occured while downloading the offline-cache.
*/
readonly attribute DOMString status;
/*
* fires a nsIDOMApplicationEvent when a change in appcache download or status happens
*/
attribute nsIDOMEventListener onprogress;
/* startPoint will be used when several launch_path exists for an app */
nsIDOMDOMRequest launch([optional] in DOMString startPoint);

View File

@ -26,6 +26,7 @@ interface nsIDOMCSSRule : nsISupports
const unsigned short PAGE_RULE = 6;
const unsigned short MOZ_KEYFRAMES_RULE = 7;
const unsigned short MOZ_KEYFRAME_RULE = 8;
const unsigned short NAMESPACE_RULE = 10;
readonly attribute unsigned short type;
attribute DOMString cssText;

View File

@ -382,9 +382,9 @@ ContentChild::DeallocPMemoryReportRequest(PMemoryReportRequestChild* actor)
}
PBrowserChild*
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags)
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame)
{
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags);
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserFrame);
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget().get() : NULL;
}

View File

@ -55,7 +55,8 @@ public:
/* if you remove this, please talk to cjones or dougt */
virtual bool RecvDummy(Shmem& foo) { return true; }
virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags);
virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags,
const bool& aIsBrowserFrame);
virtual bool DeallocPBrowser(PBrowserChild*);
virtual PCrashReporterChild*

View File

@ -356,9 +356,9 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
}
TabParent*
ContentParent::CreateTab(PRUint32 aChromeFlags)
ContentParent::CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame)
{
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags));
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags, aIsBrowserFrame));
}
TestShellParent*
@ -698,7 +698,7 @@ ContentParent::Observe(nsISupports* aSubject,
}
PBrowserParent*
ContentParent::AllocPBrowser(const PRUint32& aChromeFlags)
ContentParent::AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame)
{
TabParent* parent = new TabParent();
if (parent){

View File

@ -51,7 +51,13 @@ public:
NS_DECL_NSITHREADOBSERVER
NS_DECL_NSIDOMGEOPOSITIONCALLBACK
TabParent* CreateTab(PRUint32 aChromeFlags);
/**
* Create a new tab.
*
* |aIsBrowserFrame| indicates whether this tab is part of an
* <iframe mozbrowser>.
*/
TabParent* CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame);
TestShellParent* CreateTestShell();
bool DestroyTestShell(TestShellParent* aTestShell);
@ -90,7 +96,7 @@ private:
void Init();
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags);
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame);
virtual bool DeallocPBrowser(PBrowserParent* frame);
virtual PCrashReporterParent* AllocPCrashReporter(const NativeThreadId& tid,

View File

@ -84,7 +84,7 @@ both:
// The child creates the PBrowser as part of
// TabChild::BrowserFrameProvideWindow, and the parent creates the PBrowser
// as part of ContentParent::CreateTab.
async PBrowser(PRUint32 chromeFlags);
async PBrowser(PRUint32 chromeFlags, bool isBrowserFrame);
child:
PMemoryReportRequest();

View File

@ -87,13 +87,14 @@ public:
};
TabChild::TabChild(PRUint32 aChromeFlags)
TabChild::TabChild(PRUint32 aChromeFlags, bool aIsBrowserFrame)
: mRemoteFrame(nsnull)
, mTabChildGlobal(nsnull)
, mChromeFlags(aChromeFlags)
, mOuterRect(0, 0, 0, 0)
, mLastBackgroundColor(NS_RGB(255, 255, 255))
, mDidFakeShow(false)
, mIsBrowserFrame(aIsBrowserFrame)
{
printf("creating %d!\n", NS_IsMainThread());
}
@ -377,7 +378,9 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
*aReturn = nsnull;
nsRefPtr<TabChild> newChild =
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(0));
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
/* aChromeFlags = */ 0,
/* aIsBrowserFrame = */ true));
nsCAutoString spec;
aURI->GetSpec(spec);
@ -948,6 +951,13 @@ TabChild::InitTabChildGlobal()
nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
NS_ENSURE_TRUE(root, false);
root->SetParentTarget(scope);
// Initialize the child side of the browser element machinery, if appropriate.
if (mIsBrowserFrame) {
RecvLoadRemoteScript(
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"));
}
return true;
}

View File

@ -140,7 +140,13 @@ class TabChild : public PBrowserChild,
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
public:
TabChild(PRUint32 aChromeFlags);
/**
* Create a new TabChild object.
*
* |aIsBrowserFrame| indicates whether the TabChild is inside an
* <iframe mozbrowser>.
*/
TabChild(PRUint32 aChromeFlags, bool aIsBrowserFrame);
virtual ~TabChild();
nsresult Init();
@ -266,6 +272,7 @@ private:
nsIntRect mOuterRect;
nscolor mLastBackgroundColor;
bool mDidFakeShow;
bool mIsBrowserFrame;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

View File

@ -178,7 +178,7 @@ PluginModuleParent::TimeoutChanged(const char* aPref, void* aModule)
void
PluginModuleParent::CleanupFromTimeout()
{
if (!mShutdown)
if (!mShutdown && OkToCleanup())
Close();
}

View File

@ -20,6 +20,14 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "BindingUtils.h"
// Used to provide information on the OS
#include "nsIXULRuntime.h"
#include "nsXPCOMCIDInternal.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "OSFileConstants.h"
/**
@ -320,6 +328,28 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
return false;
}
#endif // defined(XP_WIN)
JSObject *objSys;
if (!(objSys = GetOrCreateObjectProperty(cx, objConstants, "Sys"))) {
return false;
}
nsCOMPtr<nsIXULRuntime> runtime = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
if (runtime) {
nsCAutoString os;
nsresult rv = runtime->GetOS(os);
MOZ_ASSERT(NS_SUCCEEDED(rv));
JSString* strVersion = JS_NewStringCopyZ(cx, os.get());
if (!strVersion) {
return false;
}
jsval valVersion = STRING_TO_JSVAL(strVersion);
if (!JS_SetProperty(cx, objSys, "Version", &valVersion)) {
return false;
}
}
return true;
}

View File

@ -17,8 +17,6 @@ const DEBUG = RIL.DEBUG_RIL;
const RADIOINTERFACELAYER_CID =
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
const DATACALLINFO_CID =
Components.ID("{ef474cd9-94f7-4c05-a31b-29b9de8a10d2}");
const nsIAudioManager = Ci.nsIAudioManager;
const nsIRadioInterfaceLayer = Ci.nsIRadioInterfaceLayer;
@ -131,20 +129,6 @@ XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() {
});
function DataCallInfo(state, cid, apn) {
this.callState = state;
this.cid = cid;
this.apn = apn;
}
DataCallInfo.protoptype = {
classID: DATACALLINFO_CID,
classInfo: XPCOMUtils.generateCI({classID: DATACALLINFO_CID,
classDescription: "DataCallInfo",
interfaces: [Ci.nsIDataCallInfo]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallInfo]),
};
function RadioInterfaceLayer() {
debug("Starting RIL Worker");
this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js");
@ -485,8 +469,7 @@ RadioInterfaceLayer.prototype = {
voiceInfo.type = null;
voiceInfo.signalStrength = null;
voiceInfo.relSignalStrength = null;
ppmm.sendAsyncMessage("RIL:VoiceThis.RadioState.VoiceChanged",
voiceInfo);
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
return;
}
@ -532,6 +515,23 @@ RadioInterfaceLayer.prototype = {
},
updateDataConnection: function updateDataConnection(state) {
let data = this.rilContext.data;
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
data.connected = false;
data.emergencyCallsOnly = false;
data.roaming = false;
data.network = null;
data.type = null;
data.signalStrength = null;
data.relSignalStrength = null;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
return;
}
data.roaming =
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
data.type = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
if (!this._isDataEnabled()) {
return false;
}
@ -548,9 +548,6 @@ RadioInterfaceLayer.prototype = {
// RILNetworkInterface will ignore this if it's already connected.
RILNetworkInterface.connect();
}
//TODO need to keep track of some of the state information, and then
// notify the content when state changes (connected, technology
// changes, etc.). This should be done in RILNetworkInterface.
return false;
},
@ -876,22 +873,23 @@ RadioInterfaceLayer.prototype = {
* Handle data call state changes.
*/
handleDataCallState: function handleDataCallState(datacall) {
let data = this.rilContext.data;
if (datacall.ifname) {
data.connected = (datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED);
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
}
this._deliverDataCallCallback("dataCallStateChanged",
[datacall.cid, datacall.ifname, datacall.state]);
[datacall]);
},
/**
* Handle data call list.
*/
handleDataCallList: function handleDataCallList(message) {
let datacalls = [];
for each (let datacall in message.datacalls) {
datacalls.push(new DataCallInfo(datacall.state,
datacall.cid,
datacall.apn));
}
this._deliverDataCallCallback("receiveDataCallList",
[datacalls, datacalls.length]);
[message.datacalls, message.datacalls.length]);
},
/**
@ -1695,14 +1693,14 @@ let RILNetworkInterface = {
// nsIRILDataCallback
dataCallStateChanged: function dataCallStateChanged(cid, interfaceName, callState) {
debug("Data call ID: " + cid + ", interface name: " + interfaceName);
dataCallStateChanged: function dataCallStateChanged(datacall) {
debug("Data call ID: " + datacall.cid + ", interface name: " + datacall.ifname);
if (this.connecting &&
(callState == RIL.GECKO_NETWORK_STATE_CONNECTING ||
callState == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
(datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTING ||
datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
this.connecting = false;
this.cid = cid;
this.name = interfaceName;
this.cid = datacall.cid;
this.name = datacall.ifname;
if (!this.registeredAsNetworkInterface) {
let networkManager = Cc["@mozilla.org/network/manager;1"]
.getService(Ci.nsINetworkManager);
@ -1710,14 +1708,14 @@ let RILNetworkInterface = {
this.registeredAsNetworkInterface = true;
}
}
if (this.cid != cid) {
if (this.cid != datacall.cid) {
return;
}
if (this.state == callState) {
if (this.state == datacall.state) {
return;
}
this.state = callState;
this.state = datacall.state;
Services.obs.notifyObservers(this,
kNetworkInterfaceStateChangedTopic,
null);

View File

@ -62,30 +62,25 @@ interface nsIRILTelephonyCallback : nsISupports
in AString error);
};
[scriptable, uuid(66a55943-e63b-4731-aece-9c04bfc14019)]
[scriptable, uuid(8a711703-1ee5-4675-9d9a-0b188e944cfe)]
interface nsIRILDataCallInfo : nsISupports
{
readonly attribute unsigned long callState;
readonly attribute unsigned long state;
readonly attribute AString cid;
readonly attribute AString apn;
readonly attribute AString ifname;
};
[scriptable, uuid(cea91bcb-3cfb-42bb-8638-dae89e8870fc)]
[scriptable, uuid(5bcac053-c245-46f0-bb45-d0039bfb89f5)]
interface nsIRILDataCallback : nsISupports
{
/**
* Notified when a data call changes state.
*
* @param cid
* The CID of the data call.
* @param interfaceName
* Name of the associated network interface.
* @param dataState
* One of the nsIRadioInterfaceLayer::DATACALL_STATE_* values.
* @param dataCall
* A nsIRILDataCallInfo object.
*/
void dataCallStateChanged(in AString cid,
in AString interfaceName,
in unsigned short callState);
void dataCallStateChanged(in nsIRILDataCallInfo dataCall);
/**
* Called when nsIRadioInterfaceLayer is asked to enumerate the current

View File

@ -689,6 +689,12 @@ let RIL = {
// call state.
let model_id = libcutils.property_get("ril.model_id");
if (DEBUG) debug("Detected RIL model " + model_id);
if (!model_id) {
// On some RIL models, the RIL has to be "warmed up" for us to read this property.
// It apparently isn't warmed up yet, going to try again later.
if (DEBUG) debug("Could not detect correct model_id. Going to try later.");
return;
}
if (model_id == "I9100") {
if (DEBUG) {
debug("Detected I9100, enabling " +
@ -1524,8 +1530,22 @@ let RIL = {
*/
hangUp: function hangUp(options) {
let call = this.currentCalls[options.callIndex];
if (call && call.state != CALL_STATE_HOLDING) {
Buf.simpleRequest(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND);
if (!call) {
return;
}
switch (call.state) {
case CALL_STATE_ACTIVE:
case CALL_STATE_DIALING:
case CALL_STATE_ALERTING:
Buf.newParcel(REQUEST_HANGUP);
Buf.writeUint32(1);
Buf.writeUint32(options.callIndex);
Buf.sendParcel();
break;
case CALL_STATE_HOLDING:
Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND);
break;
}
},
@ -2186,6 +2206,48 @@ let RIL = {
}
},
_processOperator: function _processOperator(operatorData) {
if (operatorData.length < 3) {
if (DEBUG) {
debug("Expected at least 3 strings for operator.");
}
}
if (!this.operator) {
this.operator = {type: "operatorchange"};
}
let [longName, shortName, networkTuple] = operatorData;
let thisTuple = String(this.operator.mcc) + this.operator.mnc;
if (this.operator.longName !== longName ||
this.operator.shortName !== shortName ||
thisTuple !== networkTuple) {
this.operator.longName = longName;
this.operator.shortName = shortName;
this.operator.mcc = 0;
this.operator.mnc = 0;
// According to ril.h, the operator fields will be NULL when the operator
// is not currently registered. We can avoid trying to parse the numeric
// tuple in that case.
if (DEBUG && !longName) {
debug("Operator is currently unregistered");
}
if (longName && shortName && networkTuple) {
try {
this._processNetworkTuple(networkTuple, this.operator);
} catch (e) {
debug("Error processing operator tuple: " + e);
}
}
this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
}
},
/**
* Helpers for processing call state and handle the active call.
*/
@ -2982,36 +3044,12 @@ RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
return;
}
let operator = Buf.readStringList();
let operatorData = Buf.readStringList();
if (DEBUG) debug("operator: " + operatorData);
if (DEBUG) debug("Operator data: " + operator);
if (operator.length < 3) {
if (DEBUG) debug("Expected at least 3 strings for operator.");
}
this._processOperator(operatorData);
if (!this.operator) {
this.operator = {type: "operatorchange"};
}
let numeric = String(this.operator.mcc) + this.operator.mnc;
if (this.operator.longName != operator[0] ||
this.operator.shortName != operator[1] ||
numeric != operator[2]) {
this.operator.longName = operator[0];
this.operator.shortName = operator[1];
this.operator.mcc = 0;
this.operator.mnc = 0;
let networkTuple = operator[2];
try {
this._processNetworkTuple(networkTuple, this.operator);
} catch (e) {
debug("Error processing operator tuple: " + e);
}
this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
}
};
RIL[REQUEST_RADIO_POWER] = null;
RIL[REQUEST_DTMF] = null;

View File

@ -478,26 +478,33 @@ Telephony::EnumerateCallState(PRUint32 aCallIndex, PRUint16 aCallState,
NS_IMETHODIMP
Telephony::NotifyError(PRInt32 aCallIndex,
const nsAString& aError)
const nsAString& aError)
{
PRInt32 index = -1;
PRInt32 length = mCalls.Length();
nsRefPtr<TelephonyCall> callToNotify;
if (!mCalls.IsEmpty()) {
// The connection is not established yet. Get the latest call object.
if (aCallIndex == -1) {
callToNotify = mCalls[mCalls.Length() - 1];
} else {
// The connection has been established. Get the failed call.
for (PRUint32 index = 0; index < mCalls.Length(); index++) {
nsRefPtr<TelephonyCall>& call = mCalls[index];
if (call->CallIndex() == aCallIndex) {
callToNotify = call;
break;
}
}
}
}
// The connection is not established yet, remove the latest call object
if (aCallIndex == -1) {
if (length > 0) {
index = length - 1;
}
} else {
if (aCallIndex < 0 || aCallIndex >= length) {
return NS_ERROR_INVALID_ARG;
}
index = aCallIndex;
}
if (index != -1) {
mCalls[index]->NotifyError(aError);
if (!callToNotify) {
NS_ERROR("Don't call me with a bad call index!");
return NS_ERROR_UNEXPECTED;
}
// Set the call state to 'disconnected' and remove it from the calls list.
callToNotify->NotifyError(aError);
return NS_OK;
}

View File

@ -71,9 +71,8 @@ function testElement(element)
clientHeight = paddingTop + height + paddingBottom - scrollbarHeight;
}
else {
// XXXndeakin note that Mozilla adds borders here, although the spec does not
scrollWidth = paddingLeft + width + paddingRight + borderLeft + borderRight;
scrollHeight = paddingTop + height + paddingBottom + borderTop + borderBottom;
scrollWidth = paddingLeft + width + paddingRight;
scrollHeight = paddingTop + height + paddingBottom;
clientWidth = paddingLeft + width + paddingRight;
clientHeight = paddingTop + height + paddingBottom;
}

View File

@ -774,7 +774,6 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
MarkChanged();
CGImageRef image;
CGImageRef subimage = NULL;
image = GetImageFromSourceSurface(aSurface);
IntSize size = aSurface->GetSize();
@ -797,7 +796,6 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
CGContextRestoreGState(mCg);
CGImageRelease(subimage);
}
bool

View File

@ -109,6 +109,9 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
if (!keep_running_)
break;
if (did_work)
continue;
// This will either sleep or process an event.
NS_ProcessNextEvent(mThread, true);
}

View File

@ -155,8 +155,8 @@ JSFunctionSpec MapObject::methods[] = {
JSObject *
MapObject::initClass(JSContext *cx, JSObject *obj)
{
return InitClass(cx, Rooted<GlobalObject*>(cx, &obj->asGlobal()),
&class_, JSProto_Map, construct, methods);
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
return InitClass(cx, global, &class_, JSProto_Map, construct, methods);
}
void
@ -348,8 +348,8 @@ JSFunctionSpec SetObject::methods[] = {
JSObject *
SetObject::initClass(JSContext *cx, JSObject *obj)
{
return InitClass(cx, Rooted<GlobalObject*>(cx, &obj->asGlobal()),
&class_, JSProto_Set, construct, methods);
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
return InitClass(cx, global, &class_, JSProto_Set, construct, methods);
}
void

View File

@ -23,8 +23,8 @@ class RegExpMatchBuilder
JSContext * const cx;
RootedObject array;
bool setProperty(JSAtom *name, Value v) {
return !!baseops::DefineProperty(cx, array, RootedId(cx, AtomToId(name)), &v,
bool setProperty(Handle<PropertyName*> name, Value v) {
return !!baseops::DefineProperty(cx, array, name, &v,
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
}
@ -38,12 +38,14 @@ class RegExpMatchBuilder
}
bool setIndex(int index) {
return setProperty(cx->runtime->atomState.indexAtom, Int32Value(index));
Rooted<PropertyName*> name(cx, cx->runtime->atomState.indexAtom);
return setProperty(name, Int32Value(index));
}
bool setInput(JSString *str) {
JS_ASSERT(str);
return setProperty(cx->runtime->atomState.inputAtom, StringValue(str));
Rooted<PropertyName*> name(cx, cx->runtime->atomState.inputAtom);
return setProperty(name, StringValue(str));
}
};
@ -194,8 +196,8 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
{
if (args.length() == 0) {
RegExpStatics *res = cx->regExpStatics();
RegExpObject *reobj = builder.build(RootedAtom(cx, cx->runtime->emptyString),
res->getFlags());
Rooted<JSAtom*> empty(cx, cx->runtime->emptyString);
RegExpObject *reobj = builder.build(empty, res->getFlags());
if (!reobj)
return false;
args.rval() = ObjectValue(*reobj);
@ -242,7 +244,8 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
if (!sourceObj.getProperty(cx, cx->runtime->atomState.sourceAtom, &v))
return false;
RegExpObject *reobj = builder.build(RootedAtom(cx, &v.toString()->asAtom()), flags);
Rooted<JSAtom*> sourceAtom(cx, &v.toString()->asAtom());
RegExpObject *reobj = builder.build(sourceAtom, flags);
if (!reobj)
return false;
@ -462,7 +465,8 @@ js_InitRegExpClass(JSContext *cx, JSObject *obj)
proto->setPrivate(NULL);
RegExpObjectBuilder builder(cx, &proto->asRegExp());
if (!builder.build(RootedAtom(cx, cx->runtime->emptyString), RegExpFlag(0)))
Rooted<JSAtom*> empty(cx, cx->runtime->emptyString);
if (!builder.build(empty, RegExpFlag(0)))
return NULL;
if (!DefinePropertiesAndBrand(cx, proto, NULL, regexp_methods))

View File

@ -56,6 +56,8 @@ space :=$(nullstr) # EOL
core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
RM = rm -f
# LIBXUL_DIST is not defined under js/src, thus we make it mean DIST there.
LIBXUL_DIST ?= $(DIST)

View File

@ -633,7 +633,10 @@ endif
HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
# Dependencies which, if modified, should cause everything to rebuild
GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
ifndef NO_MAKEFILE_RULE
GLOBAL_DEPS += Makefile.in
endif
##############################################
include $(topsrcdir)/config/makefiles/target_libs.mk
@ -1147,16 +1150,20 @@ GARBAGE_DIRS += $(_JAVA_DIR)
# Update Makefiles
###############################################################################
ifndef NO_MAKEFILE_RULE
# Note: Passing depth to make-makefile is optional.
# It saves the script some work, though.
Makefile: Makefile.in
@$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH)
endif
ifndef NO_SUBMAKEFILES_RULE
ifdef SUBMAKEFILES
# VPATH does not work on some machines in this case, so add $(srcdir)
$(SUBMAKEFILES): % : $(srcdir)/%.in
$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH) $@
endif
endif
ifdef AUTOUPDATE_CONFIGURE
$(topsrcdir)/configure: $(topsrcdir)/configure.in

View File

@ -1059,3 +1059,5 @@ gst/gst.h
gst/app/gstappsink.h
gst/app/gstappsrc.h
gst/video/video.h
sys/msg.h
sys/ipc.h

View File

@ -468,7 +468,7 @@ case "$target" in
AC_LANG_RESTORE
changequote(,)
_MSVC_VER_FILTER='s|.* ([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
_MSVC_VER_FILTER='s|.*[^!-~]([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
changequote([,])
# Determine compiler version
@ -521,7 +521,7 @@ case "$target" in
fi
changequote(,)
_MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
_MSMT_VER_FILTER='s|.*[^!-~]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
changequote([,])
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
if test -z "$MSMANIFEST_TOOL_VERSION"; then

View File

@ -95,7 +95,7 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
JS_ASSERT_IF(staticLevel != 0, callerFrame);
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
callerFrame, /* foldConstants = */ true, compileAndGo);
/* foldConstants = */ true, compileAndGo);
if (!parser.init())
return NULL;
@ -113,21 +113,16 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
if (!script)
return NULL;
BytecodeEmitter bce(&parser, &sc, script, lineno);
// We can specialize a bit for the given scope chain if that scope chain is the global object.
JSObject *globalScope = scopeChain && scopeChain == &scopeChain->global() ? scopeChain : NULL;
JS_ASSERT_IF(globalScope, globalScope->isNative());
JS_ASSERT_IF(globalScope, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalScope->getClass()));
BytecodeEmitter bce(/* parent = */ NULL, &parser, &sc, script, callerFrame, !!globalScope,
lineno);
if (!bce.init())
return NULL;
// We can specialize a bit for the given scope chain if that scope chain is the global object.
JSObject *globalObj = scopeChain && scopeChain == &scopeChain->global()
? &scopeChain->global()
: NULL;
JS_ASSERT_IF(globalObj, globalObj->isNative());
JS_ASSERT_IF(globalObj, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalObj->getClass()));
GlobalScope globalScope(cx, globalObj);
bce.globalScope = &globalScope;
/* If this is a direct call to eval, inherit the caller's strictness. */
if (callerFrame && callerFrame->isScriptFrame() && callerFrame->script()->strictModeCode)
sc.setInStrictMode();
@ -192,10 +187,10 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
if (inDirectivePrologue && !parser.recognizeDirectivePrologue(pn, &inDirectivePrologue))
return NULL;
if (!FoldConstants(cx, pn, bce.parser))
if (!FoldConstants(cx, pn, &parser))
return NULL;
if (!AnalyzeFunctions(bce.parser))
if (!AnalyzeFunctions(&parser, callerFrame))
return NULL;
tc.functionList = NULL;
@ -206,7 +201,7 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
if (!pn->isKind(PNK_SEMI) || !pn->pn_kid || !pn->pn_kid->isXMLItem())
onlyXML = false;
#endif
bce.parser->freeTree(pn);
parser.freeTree(pn);
}
#if JS_HAS_XML_SUPPORT
@ -222,8 +217,18 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
}
#endif
if (!parser.checkForArgumentsAndRest())
return NULL;
// It's an error to use |arguments| in a function that has a rest parameter.
if (callerFrame && callerFrame->isFunctionFrame() && callerFrame->fun()->hasRest()) {
PropertyName *arguments = cx->runtime->atomState.argumentsAtom;
for (AtomDefnRange r = tc.lexdeps->all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
parser.reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_ARGUMENTS_AND_REST);
return NULL;
}
}
// We're not in a function context, so we don't expect any bindings.
JS_ASSERT(sc.bindings.lookup(cx, arguments, NULL) == NONE);
}
/*
* Nowadays the threaded interpreter needs a stop instruction, so we
@ -250,8 +255,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
const char *filename, unsigned lineno, JSVersion version)
{
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
/* callerFrame = */ NULL, /* foldConstants = */ true,
/* compileAndGo = */ false);
/* foldConstants = */ true, /* compileAndGo = */ false);
if (!parser.init())
return false;
@ -271,11 +275,13 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
if (!script)
return false;
BytecodeEmitter funbce(&parser, &funsc, script, lineno);
StackFrame *nullCallerFrame = NULL;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, nullCallerFrame,
/* hasGlobalScope = */ false, lineno);
if (!funbce.init())
return false;
funsc.bindings.transfer(cx, bindings);
funsc.bindings.transfer(bindings);
fun->setArgCount(funsc.bindings.numArgs());
if (!GenerateBlockId(&funsc, funsc.bodyid))
return false;
@ -328,7 +334,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
if (!FoldConstants(cx, pn, &parser))
return false;
if (!AnalyzeFunctions(&parser))
if (!AnalyzeFunctions(&parser, nullCallerFrame))
return false;
if (fn->pn_body) {

View File

@ -65,12 +65,14 @@ NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, unsigned sta
static JSBool
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which, ptrdiff_t offset);
BytecodeEmitter::BytecodeEmitter(Parser *parser, SharedContext *sc, Handle<JSScript*> script,
BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, SharedContext *sc,
HandleScript script, StackFrame *callerFrame, bool hasGlobalScope,
unsigned lineno)
: sc(sc),
parent(NULL),
parent(parent),
script(sc->context, script),
parser(parser),
callerFrame(callerFrame),
atomIndices(sc->context),
stackDepth(0), maxStackDepth(0),
ntrynotes(0), lastTryNode(NULL),
@ -78,13 +80,14 @@ BytecodeEmitter::BytecodeEmitter(Parser *parser, SharedContext *sc, Handle<JSScr
emitLevel(0),
constMap(sc->context),
constList(sc->context),
globalScope(NULL),
closedArgs(sc->context),
closedVars(sc->context),
typesetCount(0),
hasSingletons(false),
inForInit(false)
inForInit(false),
hasGlobalScope(hasGlobalScope)
{
JS_ASSERT_IF(callerFrame, callerFrame->isScriptFrame());
memset(&prolog, 0, sizeof prolog);
memset(&main, 0, sizeof main);
current = &main;
@ -1068,7 +1071,7 @@ static bool
TryConvertToGname(BytecodeEmitter *bce, ParseNode *pn, JSOp *op)
{
if (bce->script->compileAndGo &&
bce->globalScope->globalObj &&
bce->hasGlobalScope &&
!bce->sc->funMightAliasLocals() &&
!pn->isDeoptimized() &&
!bce->sc->inStrictMode()) {
@ -1164,7 +1167,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break;
case JSOP_DELNAME:
if (dn_kind != Definition::UNKNOWN) {
if (bce->parser->callerFrame && dn->isTopLevel())
if (bce->callerFrame && dn->isTopLevel())
JS_ASSERT(bce->script->compileAndGo);
else
pn->setOp(JSOP_FALSE);
@ -1187,7 +1190,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
if (cookie.isFree()) {
StackFrame *caller = bce->parser->callerFrame;
StackFrame *caller = bce->callerFrame;
if (caller) {
JS_ASSERT(bce->script->compileAndGo);
@ -4733,24 +4736,28 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
sc.cxFlags = funbox->cxFlags;
if (bce->sc->funMightAliasLocals())
sc.setFunMightAliasLocals(); // inherit funMightAliasLocals from parent
sc.bindings.transfer(cx, &funbox->bindings);
sc.bindings.transfer(&funbox->bindings);
// Inherit various things (principals, version, etc) from the parent.
// Inherit most things (principals, version, etc) from the parent.
GlobalObject *globalObject = fun->getParent() ? &fun->getParent()->global() : NULL;
Rooted<JSScript*> script(cx);
Rooted<JSScript*> parent(cx, bce->script);
script = JSScript::Create(cx, parent->savedCallerFun, parent->principals,
parent->originPrincipals, parent->compileAndGo,
/* noScriptRval = */ false, globalObject,
parent->getVersion(), parent->staticLevel + 1);
script = JSScript::Create(cx,
/* savedCallerFun = */ false,
parent->principals,
parent->originPrincipals,
parent->compileAndGo,
/* noScriptRval = */ false,
globalObject,
parent->getVersion(),
parent->staticLevel + 1);
if (!script)
return false;
BytecodeEmitter bce2(bce->parser, &sc, script, pn->pn_pos.begin.lineno);
BytecodeEmitter bce2(bce, bce->parser, &sc, script, bce->callerFrame, bce->hasGlobalScope,
pn->pn_pos.begin.lineno);
if (!bce2.init())
return false;
bce2.parent = bce;
bce2.globalScope = bce->globalScope;
/* We measured the max scope depth when we parsed the function. */
if (!EmitFunctionScript(cx, &bce2, pn->pn_body))
@ -5630,8 +5637,8 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (obj) {
JS_ASSERT(!obj->inDictionaryMode());
if (!DefineNativeProperty(cx, obj, RootedId(cx, AtomToId(pn3->pn_atom)),
UndefinedValue(), NULL, NULL,
Rooted<jsid> id(cx, AtomToId(pn3->pn_atom));
if (!DefineNativeProperty(cx, obj, id, UndefinedValue(), NULL, NULL,
JSPROP_ENUMERATE, 0, 0))
{
return false;
@ -5930,6 +5937,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
CheckTypeSet(cx, bce, JSOP_REST);
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
return false;
if (!BindNameToSlot(cx, bce, rest))
return JS_FALSE;
if (!EmitVarOp(cx, rest, JSOP_SETARG, bce))
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)

View File

@ -63,21 +63,13 @@ class GCConstList {
void finish(ConstArray *array);
};
struct GlobalScope {
GlobalScope(JSContext *cx, JSObject *globalObj)
: globalObj(cx, globalObj)
{ }
RootedObject globalObj;
};
struct BytecodeEmitter
{
SharedContext *sc; /* context shared between parsing and bytecode generation */
SharedContext *const sc; /* context shared between parsing and bytecode generation */
BytecodeEmitter *parent; /* enclosing function or global context */
BytecodeEmitter *const parent; /* enclosing function or global context */
Rooted<JSScript*> script; /* the JSScript we're ultimately producing */
const Rooted<JSScript*> script; /* the JSScript we're ultimately producing */
struct {
jsbytecode *base; /* base of JS bytecode vector */
@ -90,7 +82,9 @@ struct BytecodeEmitter
unsigned currentLine; /* line number for tree-based srcnote gen */
} prolog, main, *current;
Parser *parser; /* the parser */
Parser *const parser; /* the parser */
StackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */
OwnedAtomIndexMapPtr atomIndices; /* literals indexed for mapping */
unsigned firstLine; /* first line, for JSScript::initFromEmitter */
@ -114,8 +108,6 @@ struct BytecodeEmitter
CGObjectList regexpList; /* list of emitted regexp that will be
cloned during execution */
GlobalScope *globalScope; /* frontend::CompileScript global scope, or null */
/* Vectors of pn_cookie slot values. */
typedef Vector<uint32_t, 8> SlotVector;
SlotVector closedArgs;
@ -127,7 +119,12 @@ struct BytecodeEmitter
bool inForInit:1; /* emitting init expr of for; exclude 'in' */
BytecodeEmitter(Parser *parser, SharedContext *sc, Handle<JSScript*> script, unsigned lineno);
const bool hasGlobalScope:1; /* frontend::CompileScript's scope chain is the
global object */
BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, SharedContext *sc,
HandleScript script, StackFrame *callerFrame, bool hasGlobalScope,
unsigned lineno);
bool init();
/*

View File

@ -84,13 +84,12 @@ StrictModeGetter::get() const
Parser::Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
const jschar *chars, size_t length, const char *fn, unsigned ln, JSVersion v,
StackFrame *cfp, bool foldConstants, bool compileAndGo)
bool foldConstants, bool compileAndGo)
: AutoGCRooter(cx, PARSER),
context(cx),
strictModeGetter(this),
tokenStream(cx, prin, originPrin, chars, length, fn, ln, v, &strictModeGetter),
tempPoolMark(NULL),
callerFrame(cfp),
allocator(cx),
traceListHead(NULL),
tc(NULL),
@ -99,7 +98,6 @@ Parser::Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
compileAndGo(compileAndGo)
{
cx->activeCompilations++;
JS_ASSERT_IF(cfp, cfp->isScriptFrame());
}
bool
@ -157,7 +155,7 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn,
siblings(tc->functionList),
kids(NULL),
parent(tc->sc->inFunction() ? tc->sc->funbox() : NULL),
bindings(tc->sc->context),
bindings(),
level(tc->staticLevel),
ndefaults(0),
inLoop(false),
@ -495,7 +493,7 @@ CheckStrictParameters(JSContext *cx, Parser *parser)
if (!parameters.init(sc->bindings.numArgs()))
return false;
/* Start with lastVariable(), not lastArgument(), for destructuring. */
// Start with lastVariable(), not the last argument, for destructuring.
for (Shape::Range r = sc->bindings.lastVariable(); !r.empty(); r.popFront()) {
jsid id = r.front().propid();
if (!JSID_IS_ATOM(id))
@ -540,7 +538,8 @@ BindLocalVariable(JSContext *cx, TreeContext *tc, ParseNode *pn, BindingKind kin
JS_ASSERT(kind == VARIABLE || kind == CONSTANT);
unsigned index = tc->sc->bindings.numVars();
if (!tc->sc->bindings.add(cx, RootedAtom(cx, pn->pn_atom), kind))
Rooted<JSAtom*> atom(cx, pn->pn_atom);
if (!tc->sc->bindings.add(cx, atom, kind))
return false;
if (!pn->pn_cookie.set(cx, tc->staticLevel, index))
@ -604,7 +603,7 @@ Parser::functionBody(FunctionBodyType type)
if (!CheckStrictParameters(context, this))
return NULL;
Rooted<PropertyName*> const arguments(context, context->runtime->atomState.argumentsAtom);
Rooted<PropertyName*> arguments(context, context->runtime->atomState.argumentsAtom);
/*
* Non-top-level functions use JSOP_DEFFUN which is a dynamic scope
@ -709,24 +708,6 @@ Parser::functionBody(FunctionBodyType type)
return pn;
}
bool
Parser::checkForArgumentsAndRest()
{
JS_ASSERT(!tc->sc->inFunction());
if (callerFrame && callerFrame->isFunctionFrame() && callerFrame->fun()->hasRest()) {
PropertyName *arguments = context->runtime->atomState.argumentsAtom;
for (AtomDefnRange r = tc->lexdeps->all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_ARGUMENTS_AND_REST);
return false;
}
}
/* We're not in a function context, so we don't expect any bindings. */
JS_ASSERT(tc->sc->bindings.lookup(context, arguments, NULL) == NONE);
}
return true;
}
// Create a placeholder Definition node for |atom|.
// Nb: unlike most functions that are passed a Parser, this one gets a
// SharedContext passed in separately, because in this case |sc| may not equal
@ -1237,7 +1218,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
}
funbox->bindings.transfer(funtc->sc->context, &funtc->sc->bindings);
funbox->bindings.transfer(&funtc->sc->bindings);
return true;
}
@ -6851,8 +6832,8 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
pn->pn_xflags |= PNX_NONCONST;
/* NB: Getter function in { get x(){} } is unnamed. */
pn2 = functionDef(RootedPropertyName(context, NULL),
op == JSOP_GETTER ? Getter : Setter, Expression);
Rooted<PropertyName*> funName(context, NULL);
pn2 = functionDef(funName, op == JSOP_GETTER ? Getter : Setter, Expression);
if (!pn2)
return NULL;
TokenPos pos = {begin, pn2->pn_pos.end};

View File

@ -38,7 +38,6 @@ struct Parser : private AutoGCRooter
StrictModeGetter strictModeGetter; /* used by tokenStream to test for strict mode */
TokenStream tokenStream;
void *tempPoolMark; /* initial JSContext.tempLifoAlloc mark */
StackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */
ParseNodeAllocator allocator;
ObjectBox *traceListHead; /* list of parsed object for GC tracing */
@ -57,7 +56,7 @@ struct Parser : private AutoGCRooter
public:
Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
const jschar *chars, size_t length, const char *fn, unsigned ln, JSVersion version,
StackFrame *cfp, bool foldConstants, bool compileAndGo);
bool foldConstants, bool compileAndGo);
~Parser();
friend void AutoGCRooter::trace(JSTracer *trc);
@ -141,8 +140,6 @@ struct Parser : private AutoGCRooter
enum FunctionBodyType { StatementListBody, ExpressionBody };
ParseNode *functionBody(FunctionBodyType type);
bool checkForArgumentsAndRest();
private:
/*
* JS parsers, from lowest to highest precedence.

View File

@ -158,7 +158,7 @@ MarkExtensibleScopeDescendants(JSContext *context, FunctionBox *funbox, bool has
}
bool
frontend::AnalyzeFunctions(Parser *parser)
frontend::AnalyzeFunctions(Parser *parser, StackFrame *callerFrame)
{
TreeContext *tc = parser->tc;
SharedContext *sc = tc->sc;
@ -166,7 +166,7 @@ frontend::AnalyzeFunctions(Parser *parser)
return true;
if (!MarkExtensibleScopeDescendants(sc->context, tc->functionList, false))
return false;
bool isDirectEval = !!parser->callerFrame;
bool isDirectEval = !!callerFrame;
bool isHeavyweight = false;
SetFunctionKinds(tc->functionList, &isHeavyweight, sc->inFunction(), isDirectEval);
if (isHeavyweight)

View File

@ -11,6 +11,7 @@
namespace js {
struct Parser;
class StackFrame;
namespace frontend {
@ -20,7 +21,7 @@ namespace frontend {
* accordingly.
*/
bool
AnalyzeFunctions(Parser *parser);
AnalyzeFunctions(Parser *parser, StackFrame *callerFrame);
} /* namespace frontend */
} /* namespace js */

View File

@ -27,7 +27,7 @@ SharedContext::SharedContext(JSContext *cx, JSObject *scopeChain, JSFunction *fu
fun_(cx, fun),
funbox_(funbox),
scopeChain_(cx, scopeChain),
bindings(cx),
bindings(),
bindingsRoot(cx, &bindings),
cxFlags(cx)
{

View File

@ -102,7 +102,7 @@ class Handle
* Construct a handle from an explicitly rooted location. This is the
* normal way to create a handle, and normally happens implicitly.
*/
template <typename S> inline Handle(const Rooted<S> &root);
template <typename S> inline Handle(Rooted<S> &root);
const T *address() const { return ptr; }
T value() const { return *ptr; }
@ -169,15 +169,6 @@ class Rooted
Rooted(JSContext *cx) { init(cx, RootMethods<T>::initial()); }
Rooted(JSContext *cx, T initial) { init(cx, initial); }
/*
* This method is only necessary due to an obscure C++98 requirement (that
* there be an accessible, usable copy constructor when passing a temporary
* to an implicitly-called constructor for use with a const-ref parameter).
* (Head spinning yet?) We can remove this when we build the JS engine
* with -std=c++11.
*/
operator Handle<T> () const { return Handle<T>(*this); }
~Rooted()
{
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
@ -223,7 +214,7 @@ class Rooted
template<typename T> template <typename S>
inline
Handle<T>::Handle(const Rooted<S> &root)
Handle<T>::Handle(Rooted<S> &root)
{
testAssign<S>();
ptr = reinterpret_cast<const T *>(root.address());

View File

@ -17,3 +17,8 @@ function f3(a=rest, ...rest) {
assertEqArray(rest, [2, 3, 4]);
}
f3(1, 2, 3, 4);
function f4(a=42, ...f) {
assertEq(typeof f, "function");
function f() {}
}
f4()

View File

@ -1795,7 +1795,8 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
assertSameCompartment(cx, obj);
return GlobalObject::initStandardClasses(cx, Rooted<GlobalObject*>(cx, &obj->global()));
Rooted<GlobalObject*> global(cx, &obj->global());
return GlobalObject::initStandardClasses(cx, global);
}
#define CLASP(name) (&name##Class)
@ -3165,7 +3166,7 @@ JS_ConvertStub(JSContext *cx, JSHandleObject obj, JSType type, jsval *vp)
{
JS_ASSERT(type != JSTYPE_OBJECT && type != JSTYPE_FUNCTION);
JS_ASSERT(obj);
return DefaultValue(cx, RootedObject(cx, obj), type, vp);
return DefaultValue(cx, obj, type, vp);
}
JS_PUBLIC_API(JSObject *)
@ -3253,12 +3254,15 @@ JS_GetPrototype(JSObject *obj)
}
JS_PUBLIC_API(JSBool)
JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
JS_SetPrototype(JSContext *cx, JSObject *obj_, JSObject *proto_)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, proto);
return SetProto(cx, RootedObject(cx, obj), RootedObject(cx, proto), JS_FALSE);
assertSameCompartment(cx, obj_, proto_);
Rooted<JSObject*> obj(cx, obj_);
Rooted<JSObject*> proto(cx, proto_);
return SetProto(cx, obj, proto, JS_FALSE);
}
JS_PUBLIC_API(JSObject *)
@ -3269,14 +3273,17 @@ JS_GetParent(JSObject *obj)
}
JS_PUBLIC_API(JSBool)
JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
JS_SetParent(JSContext *cx, JSObject *obj_, JSObject *parent_)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
JS_ASSERT(!obj->isScope());
JS_ASSERT(parent || !obj->getParent());
assertSameCompartment(cx, obj, parent);
return JSObject::setParent(cx, RootedObject(cx, obj), RootedObject(cx, parent));
JS_ASSERT(!obj_->isScope());
JS_ASSERT(parent_ || !obj_->getParent());
assertSameCompartment(cx, obj_, parent_);
Rooted<JSObject*> obj(cx, obj_);
Rooted<JSObject*> parent(cx, parent_);
return JSObject::setParent(cx, obj, parent);
}
JS_PUBLIC_API(JSObject *)
@ -3826,12 +3833,15 @@ JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, const jschar *name,
}
JS_PUBLIC_API(JSBool)
JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp)
JS_DefineOwnProperty(JSContext *cx, JSObject *obj_, jsid id_, jsval descriptor, JSBool *bp)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id, descriptor);
return js_DefineOwnProperty(cx, RootedObject(cx, obj), RootedId(cx, id), descriptor, bp);
assertSameCompartment(cx, obj_, id_, descriptor);
Rooted<JSObject*> obj(cx, obj_);
Rooted<jsid> id(cx, id_);
return js_DefineOwnProperty(cx, obj, id, descriptor, bp);
}
JS_PUBLIC_API(JSObject *)
@ -4007,11 +4017,14 @@ JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
}
JS_PUBLIC_API(JSBool)
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj_, jsid id_, jsval *vp)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
return GetOwnPropertyDescriptor(cx, RootedObject(cx, obj), RootedId(cx, id), vp);
Rooted<JSObject*> obj(cx, obj_);
Rooted<jsid> id(cx, id_);
return GetOwnPropertyDescriptor(cx, obj, id, vp);
}
static JSBool
@ -4040,7 +4053,8 @@ JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
unsigned attrs, JSBool *foundp)
{
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom && SetPropertyAttributesById(cx, obj, RootedId(cx, AtomToId(atom)), attrs, foundp);
Rooted<jsid> id(cx, AtomToId(atom));
return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
}
JS_PUBLIC_API(JSBool)
@ -4048,7 +4062,8 @@ JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, siz
unsigned attrs, JSBool *foundp)
{
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
return atom && SetPropertyAttributesById(cx, obj, RootedId(cx, AtomToId(atom)), attrs, foundp);
Rooted<jsid> id(cx, AtomToId(atom));
return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
}
JS_PUBLIC_API(JSBool)
@ -4072,9 +4087,11 @@ JS_ForwardGetPropertyTo(JSContext *cx, JSObject *obj, jsid id_, JSObject *onBeha
}
JS_PUBLIC_API(JSBool)
JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp)
JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj_, jsid id_, jsval def, jsval *vp)
{
return baseops::GetPropertyDefault(cx, RootedObject(cx, obj), RootedId(cx, id), def, vp);
Rooted<JSObject*> obj(cx, obj_);
Rooted<jsid> id(cx, id_);
return baseops::GetPropertyDefault(cx, obj, id, def, vp);
}
JS_PUBLIC_API(JSBool)
@ -4206,8 +4223,10 @@ JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
assertSameCompartment(cx, obj, id);
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
if (JSID_IS_SPECIAL(id))
return obj->deleteSpecial(cx, Rooted<SpecialId>(cx, JSID_TO_SPECIALID(id)), rval, false);
if (JSID_IS_SPECIAL(id)) {
Rooted<SpecialId> sid(cx, JSID_TO_SPECIALID(id));
return obj->deleteSpecial(cx, sid, rval, false);
}
return obj->deleteByValue(cx, IdToValue(id), rval, false);
}
@ -4453,12 +4472,14 @@ JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp)
}
JS_PUBLIC_API(JSObject *)
JS_NewElementIterator(JSContext *cx, JSObject *obj)
JS_NewElementIterator(JSContext *cx, JSObject *obj_)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
return ElementIteratorObject::create(cx, RootedObject(cx, obj));
assertSameCompartment(cx, obj_);
Rooted<JSObject*> obj(cx, obj_);
return ElementIteratorObject::create(cx, obj);
}
JS_PUBLIC_API(JSObject *)
@ -4750,6 +4771,8 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj_, JSFunctionSpec *fs)
if (!atom)
return JS_FALSE;
Rooted<jsid> id(cx, AtomToId(atom));
/*
* Define a generic arity N+1 static method for the arity N prototype
* method if flags contains JSFUN_GENERIC_NATIVE.
@ -4762,11 +4785,8 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj_, JSFunctionSpec *fs)
}
flags &= ~JSFUN_GENERIC_NATIVE;
fun = js_DefineFunction(cx, ctor, RootedId(cx, AtomToId(atom)),
js_generic_native_method_dispatcher,
fs->nargs + 1,
flags,
JSFunction::ExtendedFinalizeKind);
fun = js_DefineFunction(cx, ctor, id, js_generic_native_method_dispatcher,
fs->nargs + 1, flags, JSFunction::ExtendedFinalizeKind);
if (!fun)
return JS_FALSE;
@ -4777,8 +4797,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj_, JSFunctionSpec *fs)
fun->setExtendedSlot(0, PrivateValue(fs));
}
fun = js_DefineFunction(cx, obj,
RootedId(cx, AtomToId(atom)), fs->call, fs->nargs, flags);
fun = js_DefineFunction(cx, obj, id, fs->call, fs->nargs, flags);
if (!fun)
return JS_FALSE;
}
@ -4798,7 +4817,8 @@ JS_DefineFunction(JSContext *cx, JSObject *obj_, const char *name, JSNative call
JSAtom *atom = js_Atomize(cx, name, strlen(name));
if (!atom)
return NULL;
return js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)), call, nargs, attrs);
Rooted<jsid> id(cx, AtomToId(atom));
return js_DefineFunction(cx, obj, id, call, nargs, attrs);
}
JS_PUBLIC_API(JSFunction *)
@ -4815,7 +4835,8 @@ JS_DefineUCFunction(JSContext *cx, JSObject *obj_,
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
if (!atom)
return NULL;
return js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)), call, nargs, attrs);
Rooted<jsid> id(cx, AtomToId(atom));
return js_DefineFunction(cx, obj, id, call, nargs, attrs);
}
extern JS_PUBLIC_API(JSFunction *)
@ -4987,7 +5008,7 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSBool bytes_are_utf8, JSObject *obj, c
{
Parser parser(cx, /* prin = */ NULL, /* originPrin = */ NULL,
chars, length, /* filename = */ NULL, /* lineno = */ 1, cx->findVersion(),
/* cfp = */ NULL, /* foldConstants = */ true, /* compileAndGo = */ false);
/* foldConstants = */ true, /* compileAndGo = */ false);
if (parser.init()) {
older = JS_SetErrorReporter(cx, NULL);
if (!parser.parse(obj) &&
@ -5172,7 +5193,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj_,
return NULL;
}
Bindings bindings(cx);
Bindings bindings;
for (unsigned i = 0; i < nargs; i++) {
uint16_t dummy;
RootedAtom argAtom(cx, js_Atomize(cx, argnames[i], strlen(argnames[i])));
@ -5190,11 +5211,10 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj_,
return NULL;
}
if (obj && funAtom &&
!obj->defineGeneric(cx, RootedId(cx, AtomToId(funAtom)), ObjectValue(*fun), NULL, NULL,
JSPROP_ENUMERATE))
{
return NULL;
if (obj && funAtom) {
Rooted<jsid> id(cx, AtomToId(funAtom));
if (!obj->defineGeneric(cx, id, ObjectValue(*fun), NULL, NULL, JSPROP_ENUMERATE))
return NULL;
}
return fun;
@ -5493,8 +5513,11 @@ JS_CallFunctionName(JSContext *cx, JSObject *obj_, const char *name, unsigned ar
Value v;
JSAtom *atom = js_Atomize(cx, name, strlen(name));
return atom &&
GetMethod(cx, obj, RootedId(cx, AtomToId(atom)), 0, &v) &&
if (!atom)
return false;
Rooted<jsid> id(cx, AtomToId(atom));
return GetMethod(cx, obj, id, 0, &v) &&
Invoke(cx, ObjectOrNullValue(obj), v, argc, argv, rval);
}
@ -5873,7 +5896,9 @@ JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
{
AssertNoGC(cx);
CHECK_REQUEST(cx);
return js_ConcatStrings(cx, RootedString(cx, left), RootedString(cx, right));
Rooted<JSString*> lstr(cx, left);
Rooted<JSString*> rstr(cx, right);
return js_ConcatStrings(cx, lstr, rstr);
}
JS_PUBLIC_API(const jschar *)

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