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: case LOAD_PUSHSTATE:
printf("load pushstate; "); printf("load pushstate; ");
break; break;
case LOAD_REPLACE_BYPASS_CACHE:
printf("replace bypass cache; ");
break;
case LOAD_ERROR_PAGE: case LOAD_ERROR_PAGE:
printf("error page;"); printf("error page;");
break; break;

View File

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

View File

@ -584,7 +584,7 @@ stack[anonid=browserStack][responsivemode] {
} }
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] { stack[anonid=browserStack][responsivemode][notransition] {

View File

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

View File

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

View File

@ -977,6 +977,9 @@ PropertiesView.prototype = {
let valueLabel = document.createElement("label"); let valueLabel = document.createElement("label");
let title = element.getElementsByClassName("title")[0]; 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. // Separator between the variable name and its value.
separatorLabel.className = "plain"; separatorLabel.className = "plain";
separatorLabel.setAttribute("value", ":"); separatorLabel.setAttribute("value", ":");
@ -984,21 +987,6 @@ PropertiesView.prototype = {
// The variable information (type, class and/or value). // The variable information (type, class and/or value).
valueLabel.className = "value plain"; 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. // Handle the click event when pressing the element value label.
valueLabel.addEventListener("click", this._activateElementInputMode.bind({ valueLabel.addEventListener("click", this._activateElementInputMode.bind({
scope: this, scope: this,
@ -1029,6 +1017,36 @@ PropertiesView.prototype = {
return element; 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. * Sets the specific grip for a variable.
* The grip should contain the value or the type & class, as defined in the * 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 separatorLabel = document.createElement("label");
let valueLabel = 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) { if ("undefined" !== typeof pKey) {
// Use a key element to specify the property name. // Use a key element to specify the property name.
nameLabel.className = "key plain"; nameLabel.className = "key plain";
@ -1228,21 +1249,6 @@ PropertiesView.prototype = {
title.appendChild(valueLabel); 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. // Handle the click event when pressing the element value label.
valueLabel.addEventListener("click", this._activateElementInputMode.bind({ valueLabel.addEventListener("click", this._activateElementInputMode.bind({
scope: this, scope: this,
@ -1498,6 +1504,7 @@ PropertiesView.prototype = {
} else { } else {
arrow.addEventListener("click", function() { element.toggle(); }, false); arrow.addEventListener("click", function() { element.toggle(); }, false);
name.addEventListener("click", function() { element.toggle(); }, false); name.addEventListener("click", function() { element.toggle(); }, false);
name.addEventListener("mouseover", function() { element.updateTooltip(name); }, false);
} }
title.appendChild(arrow); 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 * Generic function refreshing the internal state of the element when
* it's modified (e.g. a child detail, variable, property is added). * 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 clientRect = node.getBoundingClientRect();
let width = Math.round(clientRect.width); let width = Math.round(clientRect.width);
let height = Math.round(clientRect.height); 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 the view is closed, no need to do anything more.
if (!this.isOpen) return; if (!this.isOpen) return;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,3 +23,12 @@ geolocation.description=Do you want to share your location?
geolocation.sharelocation=Share Location geolocation.sharelocation=Share Location
geolocation.dontshare=Don't Share geolocation.dontshare=Don't Share
geolocation.remember=Remember my choice 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 "app": app
}; };
this.processFolder = Services.dirsvc.get("CurProcD", Ci.nsIFile); this.runtimeFolder = Services.dirsvc.get("GreD", Ci.nsIFile);
} }
#ifdef XP_WIN #ifdef XP_WIN
@ -284,11 +284,11 @@ WinNativeApp.prototype = {
* Copy the pre-built files into their destination folders. * Copy the pre-built files into their destination folders.
*/ */
_copyPrebuiltFiles: function() { _copyPrebuiltFiles: function() {
let webapprt = this.processFolder.clone(); let webapprt = this.runtimeFolder.clone();
webapprt.append("webapprt-stub.exe"); webapprt.append("webapprt-stub.exe");
webapprt.copyTo(this.installDir, this.appNameAsFilename + ".exe"); webapprt.copyTo(this.installDir, this.appNameAsFilename + ".exe");
let uninstaller = this.processFolder.clone(); let uninstaller = this.runtimeFolder.clone();
uninstaller.append("webapp-uninstaller.exe"); uninstaller.append("webapp-uninstaller.exe");
uninstaller.copyTo(this.uninstallDir, this.uninstallerFile.leafName); uninstaller.copyTo(this.uninstallDir, this.uninstallerFile.leafName);
}, },
@ -313,7 +313,7 @@ WinNativeApp.prototype = {
writer.setString("Webapp", "Name", this.appName); writer.setString("Webapp", "Name", this.appName);
writer.setString("Webapp", "Profile", this.installDir.leafName); writer.setString("Webapp", "Profile", this.installDir.leafName);
writer.setString("Webapp", "Executable", this.appNameAsFilename); 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); writer.writeFile(null, Ci.nsIINIParserWriter.WRITE_UTF16);
// ${UninstallDir}/shortcuts_log.ini // ${UninstallDir}/shortcuts_log.ini
@ -534,7 +534,7 @@ MacNativeApp.prototype = {
}, },
_copyPrebuiltFiles: function() { _copyPrebuiltFiles: function() {
let webapprt = this.processFolder.clone(); let webapprt = this.runtimeFolder.clone();
webapprt.append("webapprt-stub"); webapprt.append("webapprt-stub");
webapprt.copyTo(this.macOSDir, "webapprt"); webapprt.copyTo(this.macOSDir, "webapprt");
}, },
@ -719,7 +719,7 @@ LinuxNativeApp.prototype = {
}, },
_copyPrebuiltFiles: function() { _copyPrebuiltFiles: function() {
let webapprtPre = this.processFolder.clone(); let webapprtPre = this.runtimeFolder.clone();
webapprtPre.append(this.webapprt.leafName); webapprtPre.append(this.webapprt.leafName);
webapprtPre.copyTo(this.installDir, this.webapprt.leafName); webapprtPre.copyTo(this.installDir, this.webapprt.leafName);
}, },
@ -740,7 +740,7 @@ LinuxNativeApp.prototype = {
let writer = factory.createINIParser(webappINI).QueryInterface(Ci.nsIINIParserWriter); let writer = factory.createINIParser(webappINI).QueryInterface(Ci.nsIINIParserWriter);
writer.setString("Webapp", "Name", this.appName); writer.setString("Webapp", "Name", this.appName);
writer.setString("Webapp", "Profile", this.uniqueName); writer.setString("Webapp", "Profile", this.uniqueName);
writer.setString("WebappRT", "InstallDir", this.processFolder.path); writer.setString("WebappRT", "InstallDir", this.runtimeFolder.path);
writer.writeFile(); writer.writeFile();
// $XDG_DATA_HOME/applications/owa-<webappuniquename>.desktop // $XDG_DATA_HOME/applications/owa-<webappuniquename>.desktop

View File

@ -168,6 +168,16 @@
opacity: 0.5; 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 * Property values colors
*/ */

View File

@ -170,6 +170,16 @@
opacity: 0.5; 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 * Property values colors
*/ */

View File

@ -168,6 +168,16 @@
opacity: 0.5; 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 * 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 shutil
import tarfile import tarfile
import subprocess import subprocess
import platform
def check_run(args): def check_run(args):
r = subprocess.call(args) r = subprocess.call(args)
@ -46,8 +47,7 @@ def with_env(env, f):
def build_tar_package(tar, name, base, directory): def build_tar_package(tar, name, base, directory):
name = os.path.realpath(name) name = os.path.realpath(name)
run_in(base, [tar, "-cjf", name, "--mtime=2012-01-01", "--owner=root", run_in(base, [tar, "-cjf", name, directory])
directory])
def svn_co(url, directory, revision): def svn_co(url, directory, revision):
check_run(["svn", "co", "-r", revision, url, directory]) 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) os.mkdir(stage_dir)
build_dir = stage_dir + "/build" build_dir = stage_dir + "/build"
inst_dir = stage_dir + "/inst" inst_dir = stage_dir + "/clang"
configure_opts = ["--enable-optimized", configure_opts = ["--enable-optimized",
"--prefix=%s" % inst_dir, "--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) build_package(llvm_source_dir, build_dir, configure_opts)
isDarwin = platform.system() == "Darwin"
if not os.path.exists(source_dir): if not os.path.exists(source_dir):
os.makedirs(source_dir) os.makedirs(source_dir)
svn_co("http://llvm.org/svn/llvm-project/llvm/trunk", 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) compiler_rt_source_dir, llvm_revision)
os.symlink("../../clang", llvm_source_dir + "/tools/clang") os.symlink("../../clang", llvm_source_dir + "/tools/clang")
os.symlink("../../compiler-rt", llvm_source_dir + "/projects/compiler-rt") os.symlink("../../compiler-rt", llvm_source_dir + "/projects/compiler-rt")
patch("old-ld-hack.patch", 1, llvm_source_dir) if isDarwin:
patch("compiler-rt-gnu89-inline.patch", 0, compiler_rt_source_dir) 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): if os.path.exists(build_dir):
shutil.rmtree(build_dir) shutil.rmtree(build_dir)
@ -103,13 +109,28 @@ os.makedirs(build_dir)
stage1_dir = build_dir + '/stage1' stage1_dir = build_dir + '/stage1'
stage1_inst_dir = stage1_dir + '/clang' 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) stage1_dir, True)
if not isDarwin:
extra_cflags += " -fgnu89-inline"
stage2_dir = build_dir + '/stage2' stage2_dir = build_dir + '/stage2'
build_one_stage({"CC" : stage1_inst_dir + "/bin/clang -static-libgcc -fgnu89-inline", build_one_stage({"CC" : stage1_inst_dir + "/bin/clang %s" % extra_cflags,
"CXX" : stage1_inst_dir + "/bin/clang++ -static-libgcc -static-libstdc++"}, "CXX" : stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags},
stage2_dir, False) 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(unsigned long);
template ostream& ostream::_M_insert(long long); template ostream& ostream::_M_insert(long long);
template ostream& ostream::_M_insert(unsigned 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::_M_insert(const void*);
template ostream& __ostream_insert(ostream&, const char*, streamsize); template ostream& __ostream_insert(ostream&, const char*, streamsize);
template istream& istream::_M_extract(double&); 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 #endif
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14) #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
/* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions /* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions
@ -42,6 +46,7 @@ namespace std {
template string& string::operator=(string&&); template string& string::operator=(string&&);
template wstring::basic_string(wstring&&); template wstring::basic_string(wstring&&);
template wstring& wstring::operator=(wstring&&); template wstring& wstring::operator=(wstring&&);
template string& string::assign(string&&);
template wstring& wstring::assign(wstring&&); template wstring& wstring::assign(wstring&&);
#endif /* __GXX_EXPERIMENTAL_CXX0X__ */ #endif /* __GXX_EXPERIMENTAL_CXX0X__ */
#endif /* (__GNUC__ == 4) && (__GNUC_MINOR__ >= 5) */ #endif /* (__GNUC__ == 4) && (__GNUC_MINOR__ >= 5) */

View File

@ -137,6 +137,7 @@ MOZ_WEBM = @MOZ_WEBM@
MOZ_MEDIA_PLUGINS = @MOZ_MEDIA_PLUGINS@ MOZ_MEDIA_PLUGINS = @MOZ_MEDIA_PLUGINS@
MOZ_OMX_PLUGIN = @MOZ_OMX_PLUGIN@ MOZ_OMX_PLUGIN = @MOZ_OMX_PLUGIN@
MOZ_GSTREAMER = @MOZ_GSTREAMER@ MOZ_GSTREAMER = @MOZ_GSTREAMER@
MOZ_VP8 = @MOZ_VP8@
MOZ_VP8_ERROR_CONCEALMENT = @MOZ_VP8_ERROR_CONCEALMENT@ MOZ_VP8_ERROR_CONCEALMENT = @MOZ_VP8_ERROR_CONCEALMENT@
MOZ_VP8_ENCODER = @MOZ_VP8_ENCODER@ MOZ_VP8_ENCODER = @MOZ_VP8_ENCODER@
VPX_AS = @VPX_AS@ VPX_AS = @VPX_AS@
@ -170,6 +171,7 @@ MOZ_D3DX9_DLL = @MOZ_D3DX9_DLL@
MOZ_D3DCOMPILER_DLL = @MOZ_D3DCOMPILER_DLL@ MOZ_D3DCOMPILER_DLL = @MOZ_D3DCOMPILER_DLL@
MOZ_GL_PROVIDER = @MOZ_GL_PROVIDER@ MOZ_GL_PROVIDER = @MOZ_GL_PROVIDER@
MOZ_GL_DEFAULT_PROVIDER = @MOZ_GL_DEFAULT_PROVIDER@ MOZ_GL_DEFAULT_PROVIDER = @MOZ_GL_DEFAULT_PROVIDER@
MOZ_WEBRTC = @MOZ_WEBRTC@
JAVA=@JAVA@ 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))))))) 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 is not defined under js/src, thus we make it mean DIST there.
LIBXUL_DIST ?= $(DIST) LIBXUL_DIST ?= $(DIST)

View File

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

View File

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

View File

@ -495,7 +495,7 @@ case "$target" in
AC_LANG_RESTORE AC_LANG_RESTORE
changequote(,) 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([,]) changequote([,])
# Determine compiler version # Determine compiler version
@ -522,18 +522,22 @@ case "$target" in
fi fi
_CC_SUITE=8 _CC_SUITE=8
_MSVS_VERSION=2005
AC_DEFINE(_CRT_SECURE_NO_DEPRECATE) AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE) AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
elif test "$_CC_MAJOR_VERSION" = "15"; then elif test "$_CC_MAJOR_VERSION" = "15"; then
_CC_SUITE=9 _CC_SUITE=9
_MSVS_VERSION=2008
AC_DEFINE(_CRT_SECURE_NO_WARNINGS) AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS) AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "16"; then elif test "$_CC_MAJOR_VERSION" = "16"; then
_CC_SUITE=10 _CC_SUITE=10
_MSVS_VERSION=2010
AC_DEFINE(_CRT_SECURE_NO_WARNINGS) AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS) AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "17"; then elif test "$_CC_MAJOR_VERSION" = "17"; then
_CC_SUITE=11 _CC_SUITE=11
_MSVS_VERSION=2011
AC_DEFINE(_CRT_SECURE_NO_WARNINGS) AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS) AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
else else
@ -567,7 +571,7 @@ case "$target" in
fi fi
changequote(,) 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([,]) changequote([,])
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"` MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
if test -z "$MSMANIFEST_TOOL_VERSION"; then if test -z "$MSMANIFEST_TOOL_VERSION"; then
@ -4250,9 +4254,12 @@ MOZ_WAVE=1
MOZ_MEDIA= MOZ_MEDIA=
MOZ_OPUS=1 MOZ_OPUS=1
MOZ_WEBM=1 MOZ_WEBM=1
MOZ_WEBRTC=
MOZ_WEBRTC_SIGNALING=
MOZ_MEDIA_PLUGINS= MOZ_MEDIA_PLUGINS=
MOZ_MEDIA_NAVIGATOR= MOZ_MEDIA_NAVIGATOR=
MOZ_OMX_PLUGIN= MOZ_OMX_PLUGIN=
MOZ_VP8=
MOZ_VP8_ERROR_CONCEALMENT= MOZ_VP8_ERROR_CONCEALMENT=
MOZ_VP8_ENCODER= MOZ_VP8_ENCODER=
VPX_AS= VPX_AS=
@ -5271,6 +5278,25 @@ if test "$NS_PRINTING"; then
AC_DEFINE(NS_PRINT_PREVIEW) AC_DEFINE(NS_PRINT_PREVIEW)
fi 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 ========================================================
dnl = Enable Raw Codecs dnl = Enable Raw Codecs
dnl ======================================================== dnl ========================================================
@ -5346,6 +5372,11 @@ MOZ_ARG_DISABLE_BOOL(webm,
MOZ_WEBM=, MOZ_WEBM=,
MOZ_WEBM=1) MOZ_WEBM=1)
if test -n "$MOZ_WEBM"; then
AC_DEFINE(MOZ_WEBM)
MOZ_VP8=1
fi;
dnl ======================================================== dnl ========================================================
dnl = Disable media plugin support dnl = Disable media plugin support
dnl ======================================================== dnl ========================================================
@ -5397,8 +5428,8 @@ MOZ_ARG_WITH_BOOL(system-libvpx,
MOZ_LIBVPX_INCLUDES= MOZ_LIBVPX_INCLUDES=
MOZ_LIBVPX_LIBS= MOZ_LIBVPX_LIBS=
if test -n "$MOZ_WEBM"; then if test -n "$MOZ_VP8"; then
AC_DEFINE(MOZ_WEBM) AC_DEFINE(MOZ_VP8)
if test -n "$MOZ_VP8_ERROR_CONCEALMENT" ; then if test -n "$MOZ_VP8_ERROR_CONCEALMENT" ; then
AC_DEFINE(MOZ_VP8_ERROR_CONCEALMENT) AC_DEFINE(MOZ_VP8_ERROR_CONCEALMENT)
fi fi
@ -5425,7 +5456,7 @@ AC_SUBST(MOZ_NATIVE_LIBVPX)
AC_SUBST(MOZ_LIBVPX_INCLUDES) AC_SUBST(MOZ_LIBVPX_INCLUDES)
AC_SUBST(MOZ_LIBVPX_LIBS) 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_SYDNEYAUDIO=1
MOZ_CUBEB=1 MOZ_CUBEB=1
MOZ_MEDIA=1 MOZ_MEDIA=1
@ -5437,7 +5468,9 @@ if test -n "$MOZ_WEBM" -a -z "$MOZ_NATIVE_LIBVPX"; then
MOZ_VORBIS=1 MOZ_VORBIS=1
;; ;;
esac 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 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. 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_OMX_PLUGIN)
AC_SUBST(MOZ_VP8_ERROR_CONCEALMENT) AC_SUBST(MOZ_VP8_ERROR_CONCEALMENT)
AC_SUBST(MOZ_VP8_ENCODER) AC_SUBST(MOZ_VP8_ENCODER)
AC_SUBST(MOZ_VP8)
AC_SUBST(MOZ_OGG) AC_SUBST(MOZ_OGG)
AC_SUBST(MOZ_ALSA_LIBS) AC_SUBST(MOZ_ALSA_LIBS)
AC_SUBST(MOZ_ALSA_CFLAGS) AC_SUBST(MOZ_ALSA_CFLAGS)
@ -8865,6 +8899,52 @@ mv -f config/autoconf.mk config/autoconf.mk.orig 2> /dev/null
AC_OUTPUT($MAKEFILES) 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 # Populate the virtualenv
AC_MSG_RESULT([Populating Python virtualenv]) AC_MSG_RESULT([Populating Python virtualenv])
$MAKE -C build/virtualenv MACOSX_DEPLOYMENT_TARGET= || exit 1 $MAKE -C build/virtualenv MACOSX_DEPLOYMENT_TARGET= || exit 1

View File

@ -250,6 +250,64 @@ public:
return OwnerDoc()->IsHTML(); 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 * Returns an atom holding the name of the attribute of type ID on
* this content node (if applicable). Returns null for non-element * this content node (if applicable). Returns null for non-element

View File

@ -476,15 +476,6 @@ public:
return mNodeInfo->LocalName(); 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 * 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 * pointer (as implied by the naming of the method). For elements this is
@ -496,55 +487,6 @@ public:
return mNodeInfo->NameAtom(); 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* nsINode*
InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn) InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn)
{ {

View File

@ -1505,13 +1505,6 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell->SetChromeEventHandler(chromeEventHandler); 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) // This is nasty, this code (the do_GetInterface(mDocShell) below)
// *must* come *after* the above call to // *must* come *after* the above call to
// mDocShell->SetChromeEventHandler() for the global window to get // mDocShell->SetChromeEventHandler() for the global window to get
@ -1538,6 +1531,22 @@ nsFrameLoader::MaybeCreateDocShell()
EnsureMessageManager(); 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; return NS_OK;
} }
@ -1899,7 +1908,8 @@ nsFrameLoader::TryRemoteBrowser()
ContentParent* parent = ContentParent::GetNewOrUsed(); ContentParent* parent = ContentParent::GetNewOrUsed();
NS_ASSERTION(parent->IsAlive(), "Process parent should be alive; something is very wrong!"); 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) { if (mRemoteBrowser) {
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent); nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
mRemoteBrowser->SetOwnerElement(element); mRemoteBrowser->SetOwnerElement(element);

View File

@ -2033,6 +2033,20 @@ nsGenericElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height); 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* nsIScrollableFrame*
nsGenericElement::GetScrollFrame(nsIFrame **aStyledFrame) nsGenericElement::GetScrollFrame(nsIFrame **aStyledFrame)
{ {
@ -2145,10 +2159,7 @@ nsGenericElement::GetScrollHeight()
nsIScrollableFrame* sf = GetScrollFrame(); nsIScrollableFrame* sf = GetScrollFrame();
if (!sf) { if (!sf) {
nsRect rcFrame; return GetPaddingRectSize().height;
nsCOMPtr<nsIContent> parent;
GetOffsetRect(rcFrame, getter_AddRefs(parent));
return rcFrame.height;
} }
nscoord height = sf->GetScrollRange().height + sf->GetScrollPortRect().height; nscoord height = sf->GetScrollRange().height + sf->GetScrollPortRect().height;
@ -2171,10 +2182,7 @@ nsGenericElement::GetScrollWidth()
nsIScrollableFrame* sf = GetScrollFrame(); nsIScrollableFrame* sf = GetScrollFrame();
if (!sf) { if (!sf) {
nsRect rcFrame; return GetPaddingRectSize().width;
nsCOMPtr<nsIContent> parent;
GetOffsetRect(rcFrame, getter_AddRefs(parent));
return rcFrame.width;
} }
nscoord width = sf->GetScrollRange().width + sf->GetScrollPortRect().width; nscoord width = sf->GetScrollRange().width + sf->GetScrollPortRect().width;

View File

@ -777,6 +777,13 @@ protected:
*/ */
virtual void GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent); 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(); nsIFrame* GetStyledFrame();
virtual mozilla::dom::Element* GetNameSpaceElement() virtual mozilla::dom::Element* GetNameSpaceElement()

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=320799
<body> <body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=320799">Mozilla Bug 320799</a> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=320799">Mozilla Bug 320799</a>
<p id="display"> <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> <option>This is a test, it really is a test I tell you</option>
</select> </select>
<select id="s2"> <select id="s2">

View File

@ -41,13 +41,13 @@ function t3(id,c,o,s,pid) {
function run_test() { function run_test() {
t3('span1',[0,0,20,20],[12,12,20,20],[0,0,20,20],'td1'); 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('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('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,103,50],'body'); 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('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 // 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('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'); // 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('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('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('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('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('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('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('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('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('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('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('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('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('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('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'); 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? // without hard-coding the scrollbar width?
t3('div1',[20,20,-1,-1],[10,10,200,160],[0,0,230,20],'body'); 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('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('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'); t3('table3parent',[0,0,228,228],[300,100,228,228],[0,0,228,228],'body');
} }
</script> </script>
@ -106,4 +106,4 @@ run_test();
</pre> </pre>
</body> </body>
</html> </html>

View File

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

View File

@ -78,98 +78,327 @@ XBLFinalize(JSFreeOp *fop, JSObject *obj)
c->Drop(); c->Drop();
} }
static JSBool // XBL fields are represented on elements inheriting that field a bit trickily.
XBLResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, // Initially the element itself won't have a property for the field. When an
JSObject **objp) // 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 JSClass* clasp = ::JS_GetClass(obj);
// was installed, which means that AllowScripts() tested true. Hence no need const uint32_t HAS_PRIVATE_NSISUPPORTS =
// to do checks like that here. JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS;
return (clasp->flags & HAS_PRIVATE_NSISUPPORTS) == HAS_PRIVATE_NSISUPPORTS;
// Default to not resolving things. }
NS_ASSERTION(*objp, "Must have starting object");
JSObject* origObj = *objp; // Define a shadowing property on |this| for the XBL field defined by the
*objp = NULL; // 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)) { // First ensure |this| is a reasonable XBL bound node.
return JS_TRUE; //
} // FieldAccessorGuard already determined whether |thisObj| was acceptable as
// |this| in terms of not throwing a TypeError. Assert this for good measure.
nsDependentJSString fieldName(id); MOZ_ASSERT(ObjectHasISupportsPrivate(thisObj));
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;
}
// 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 = nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
do_QueryInterface(static_cast<nsISupports*>(::JS_GetPrivate(origObj))); do_QueryInterface(static_cast<nsISupports*>(::JS_GetPrivate(thisObj)));
if (!xpcWrapper) { 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 // be the proto our binding installed, however, where the private is the
// nsXBLDocumentInfo, so just baul out quietly. Do NOT throw an exception // nsXBLDocumentInfo, so just baul out quietly. Do NOT throw an exception
// here. // 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); nsCOMPtr<nsIContent> xblNode = do_QueryWrappedNative(xpcWrapper);
if (!content) { if (!xblNode) {
xpc::Throw(cx, NS_ERROR_UNEXPECTED); 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 // This mirrors code in nsXBLProtoImpl::InstallImplementation
nsIDocument* doc = content->OwnerDoc(); nsIScriptGlobalObject* global = xblNode->OwnerDoc()->GetScriptGlobalObject();
nsIScriptGlobalObject* global = doc->GetScriptGlobalObject();
if (!global) { if (!global) {
return JS_TRUE; return true;
} }
nsCOMPtr<nsIScriptContext> context = global->GetContext(); nsCOMPtr<nsIScriptContext> context = global->GetContext();
if (!context) { 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 if (!::JS_IsExceptionPending(cx)) {
bool didInstall;
nsresult rv = field->InstallField(context, origObj,
content->NodePrincipal(),
protoBinding->DocURI(),
&didInstall);
if (NS_FAILED(rv)) {
xpc::Throw(cx, rv); 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) { if (ObjectHasISupportsPrivate(obj)) {
*objp = origObj; *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) nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName)
@ -179,12 +408,12 @@ nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName)
name = ToNewCString(aClassName); name = ToNewCString(aClassName);
flags = flags =
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | 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 // Our one reserved slot holds the relevant nsXBLPrototypeBinding
JSCLASS_HAS_RESERVED_SLOTS(1); JSCLASS_HAS_RESERVED_SLOTS(1);
addProperty = delProperty = getProperty = ::JS_PropertyStub; addProperty = delProperty = getProperty = ::JS_PropertyStub;
setProperty = ::JS_StrictPropertyStub; setProperty = ::JS_StrictPropertyStub;
enumerate = ::JS_EnumerateStub; enumerate = XBLEnumerate;
resolve = (JSResolveOp)XBLResolve; resolve = (JSResolveOp)XBLResolve;
convert = ::JS_ConvertStub; convert = ::JS_ConvertStub;
finalize = XBLFinalize; finalize = XBLFinalize;

View File

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

View File

@ -41,6 +41,13 @@ public:
const PRUnichar* GetName() const { return mName; } 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: protected:
nsXBLProtoImplField* mNext; nsXBLProtoImplField* mNext;
PRUnichar* mName; PRUnichar* mName;

View File

@ -116,8 +116,9 @@ addLoadEvent(function() {
is(found, true, "Enumeration is broken"); is(found, true, "Enumeration is broken");
is(d.four, 9, "Shouldn't have rerun field six"); 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.seven, 7, "Should be 7")
is(d.five, 5, "Should have run field 7");
d = $("display2"); d = $("display2");
is(typeof(d.eight), "undefined", "Recursive resolve should bail out"); 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_NORMAL_REPLACE:
case LOAD_LINK: case LOAD_LINK:
case LOAD_STOP_CONTENT: case LOAD_STOP_CONTENT:
case LOAD_REPLACE_BYPASS_CACHE:
result = nsIDOMPerformanceNavigation::TYPE_NAVIGATE; result = nsIDOMPerformanceNavigation::TYPE_NAVIGATE;
break; break;
case LOAD_HISTORY: case LOAD_HISTORY:
@ -1141,6 +1142,9 @@ ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType)
case nsIDocShellLoadInfo::loadPushState: case nsIDocShellLoadInfo::loadPushState:
loadType = LOAD_PUSHSTATE; loadType = LOAD_PUSHSTATE;
break; break;
case nsIDocShellLoadInfo::loadReplaceBypassCache:
loadType = LOAD_REPLACE_BYPASS_CACHE;
break;
default: default:
NS_NOTREACHED("Unexpected nsDocShellInfoLoadType value"); NS_NOTREACHED("Unexpected nsDocShellInfoLoadType value");
} }
@ -1209,6 +1213,9 @@ nsDocShell::ConvertLoadTypeToDocShellLoadInfo(PRUint32 aLoadType)
case LOAD_PUSHSTATE: case LOAD_PUSHSTATE:
docShellLoadType = nsIDocShellLoadInfo::loadPushState; docShellLoadType = nsIDocShellLoadInfo::loadPushState;
break; break;
case LOAD_REPLACE_BYPASS_CACHE:
docShellLoadType = nsIDocShellLoadInfo::loadReplaceBypassCache;
break;
default: default:
NS_NOTREACHED("Unexpected load type value"); NS_NOTREACHED("Unexpected load type value");
} }
@ -5923,6 +5930,7 @@ nsDocShell::Embed(nsIContentViewer * aContentViewer,
case LOAD_RELOAD_BYPASS_CACHE: case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY: case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_REPLACE_BYPASS_CACHE:
updateHistory = false; updateHistory = false;
break; break;
default: default:
@ -9226,6 +9234,7 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
case LOAD_RELOAD_BYPASS_CACHE: case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY: case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_REPLACE_BYPASS_CACHE:
loadFlags |= nsIRequest::LOAD_BYPASS_CACHE | loadFlags |= nsIRequest::LOAD_BYPASS_CACHE |
nsIRequest::LOAD_FRESH_CONNECTION; nsIRequest::LOAD_FRESH_CONNECTION;
break; 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 = 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_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_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 * Load type for an error page. These loads are never triggered by users of
* Docshell. Instead, Docshell triggers the load itself when a * 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:
case LOAD_STOP_CONTENT_AND_REPLACE: case LOAD_STOP_CONTENT_AND_REPLACE:
case LOAD_PUSHSTATE: case LOAD_PUSHSTATE:
case LOAD_REPLACE_BYPASS_CACHE:
case LOAD_ERROR_PAGE: case LOAD_ERROR_PAGE:
return true; return true;
} }

View File

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

View File

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

View File

@ -156,7 +156,9 @@ let DOMApplicationRegistry = {
origin: aApp.origin, origin: aApp.origin,
receipts: aApp.receipts, receipts: aApp.receipts,
installTime: aApp.installTime, installTime: aApp.installTime,
manifestURL: aApp.manifestURL manifestURL: aApp.manifestURL,
progress: aApp.progress || 0.0,
status: aApp.status || "installed"
}; };
return clone; return clone;
}, },
@ -165,7 +167,7 @@ let DOMApplicationRegistry = {
ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData); ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
}, },
confirmInstall: function(aData, aFromSync) { confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
let app = aData.app; let app = aData.app;
let id = app.syncId || this._appId(app.origin); let id = app.syncId || this._appId(app.origin);
@ -191,11 +193,29 @@ let DOMApplicationRegistry = {
this._writeFile(manFile, JSON.stringify(app.manifest)); this._writeFile(manFile, JSON.stringify(app.manifest));
this.webapps[id] = appObject; this.webapps[id] = appObject;
appObject.status = "installed";
let manifest = new DOMApplicationManifest(app.manifest, app.origin);
if (!aFromSync) if (!aFromSync)
this._saveApps((function() { this._saveApps((function() {
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData); ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-install", appNote); Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
}).bind(this)); }).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) { _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 * Helper object to access manifest information with locale support
*/ */
@ -481,6 +548,10 @@ DOMApplicationManifest.prototype = {
return this._localeProp("icons"); return this._localeProp("icons");
}, },
get appcache_path() {
return this._localeProp("appcache_path");
},
iconURLForSize: function(aSize) { iconURLForSize: function(aSize) {
let icons = this._localeProp("icons"); let icons = this._localeProp("icons");
if (!icons) if (!icons)
@ -501,6 +572,11 @@ DOMApplicationManifest.prototype = {
let startPoint = aStartPoint || ""; let startPoint = aStartPoint || "";
let launchPath = this._localeProp("launch_path") || ""; let launchPath = this._localeProp("launch_path") || "";
return this._origin.resolve(launchPath + startPoint); 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 component {fff440b3-fae2-45c1-bf03-3b5a2e432270} Webapps.js
contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270} contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270}
category JavaScript-navigator-property mozApps @mozilla.org/webapps;1 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 \ #define ELEMENT_SCRIPTABLE_FLAGS \
((NODE_SCRIPTABLE_FLAGS & ~nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY) | \ ((NODE_SCRIPTABLE_FLAGS & ~nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY) | \
nsIXPCScriptable::WANT_POSTCREATE | \ nsIXPCScriptable::WANT_POSTCREATE)
nsIXPCScriptable::WANT_ENUMERATE)
#define EXTERNAL_OBJ_SCRIPTABLE_FLAGS \ #define EXTERNAL_OBJ_SCRIPTABLE_FLAGS \
((ELEMENT_SCRIPTABLE_FLAGS & \ ((ELEMENT_SCRIPTABLE_FLAGS & \
@ -8188,27 +8187,6 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK; 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. // Generic array scriptable helper.
@ -8557,21 +8535,9 @@ nsDOMStringMapSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
nsDOMStringMap* dataset = static_cast<nsDOMStringMap*>(nativeObj); nsDOMStringMap* dataset = static_cast<nsDOMStringMap*>(nativeObj);
nsIDocument* document = dataset->GetElement()->OwnerDoc(); // Parent the string map to its element.
nsINode* element = dataset->GetElement();
nsCOMPtr<nsIScriptGlobalObject> sgo = return WrapNativeParent(cx, globalObj, element, element, parentObj);
do_GetInterface(document->GetScopeObject());
if (sgo) {
JSObject *global = sgo->GetGlobalJSObject();
if (global) {
*parentObj = global;
return NS_OK;
}
}
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

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

View File

@ -492,6 +492,7 @@ nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
PRInt32 aModifiers, PRInt32 aModifiers,
bool aIgnoreRootScrollFrame) bool aIgnoreRootScrollFrame)
{ {
SAMPLE_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow");
return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers, return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
aIgnoreRootScrollFrame, true); aIgnoreRootScrollFrame, true);
} }
@ -1825,13 +1826,13 @@ nsDOMWindowUtils::GetParent(const JS::Value& aObject,
return NS_ERROR_XPC_BAD_CONVERT_JS; 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); *aParent = OBJECT_TO_JSVAL(parent);
// Outerize if necessary. // Outerize if necessary.
if (parent) { if (parent) {
if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) { 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) { if (mScreen) {
mScreen->Reset();
mScreen = nsnull; 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() nsScreen::~nsScreen()
{ {
Reset();
hal::UnregisterScreenConfigurationObserver(this); hal::UnregisterScreenConfigurationObserver(this);
} }
@ -318,6 +335,7 @@ NS_IMETHODIMP
nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn) nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
{ {
ScreenOrientation orientation; ScreenOrientation orientation;
*aReturn = false;
if (aOrientation.EqualsLiteral("portrait")) { if (aOrientation.EqualsLiteral("portrait")) {
orientation = eScreenOrientation_Portrait; orientation = eScreenOrientation_Portrait;
@ -332,37 +350,31 @@ nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
} else if (aOrientation.EqualsLiteral("landscape-secondary")) { } else if (aOrientation.EqualsLiteral("landscape-secondary")) {
orientation = eScreenOrientation_LandscapeSecondary; orientation = eScreenOrientation_LandscapeSecondary;
} else { } else {
*aReturn = false;
return NS_OK; return NS_OK;
} }
if (!GetOwner()) { if (!GetOwner()) {
*aReturn = false;
return NS_OK; 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; nsCOMPtr<nsIDOMDocument> doc;
GetOwner()->GetDocument(getter_AddRefs(doc)); GetOwner()->GetDocument(getter_AddRefs(doc));
if (!doc) { if (!doc) {
*aReturn = false;
return NS_OK; return NS_OK;
} }
// Apps and frames contained in apps can lock orientation. // Non-apps content can lock orientation only if fullscreen.
// But non-apps can lock orientation only if they're fullscreen. bool fullscreen;
if (!static_cast<nsGlobalWindow*>(GetOwner())->IsPartOfApp()) { doc->GetMozFullScreen(&fullscreen);
bool fullscreen; if (!fullscreen) {
doc->GetMozFullScreen(&fullscreen); return NS_OK;
if (!fullscreen) {
*aReturn = false;
return NS_OK;
}
} }
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner()); nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
if (!target) { if (!target) {
*aReturn = false;
return NS_OK; return NS_OK;
} }

View File

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

View File

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

View File

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

View File

@ -1,5 +1,3 @@
import WebIDL
def WebIDLTest(parser, harness): def WebIDLTest(parser, harness):
parser.parse(""" parser.parse("""
dictionary Dict2 : Dict1 { dictionary Dict2 : Dict1 {
@ -29,7 +27,7 @@ def WebIDLTest(parser, harness):
"'a' really comes before 'c'") "'a' really comes before 'c'")
# Now reset our parser # Now reset our parser
parser = WebIDL.Parser() parser = parser.reset()
threw = False threw = False
try: try:
parser.parse(""" parser.parse("""
@ -45,7 +43,7 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Should not allow name duplication in a dictionary") harness.ok(threw, "Should not allow name duplication in a dictionary")
# Now reset our parser again # Now reset our parser again
parser = WebIDL.Parser() parser = parser.reset()
threw = False threw = False
try: try:
parser.parse(""" parser.parse("""
@ -67,7 +65,7 @@ def WebIDLTest(parser, harness):
"its ancestor") "its ancestor")
# More reset # More reset
parser = WebIDL.Parser() parser = parser.reset()
threw = False threw = False
try: try:
parser.parse(""" parser.parse("""
@ -83,7 +81,7 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Should not allow non-dictionary parents for dictionaries") harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
# Even more reset # Even more reset
parser = WebIDL.Parser() parser = parser.reset()
threw = False threw = False
try: try:
parser.parse(""" 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") "Member has the right QName")
harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar", harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar",
"Member has the right QName") "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; DiamondBranch1B implements DiamondImplements;
dictionary Dict : ParentDict { dictionary Dict : ParentDict {
TestEnum someEnum;
long x; long x;
long a; long a;
long b = 8; long b = 8;

View File

@ -111,6 +111,10 @@ BrowserElementChild.prototype = {
addMsgListener("get-screenshot", this._recvGetScreenshot); addMsgListener("get-screenshot", this._recvGetScreenshot);
addMsgListener("set-visible", this._recvSetVisible); 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); addMsgListener("unblock-modal-prompt", this._recvStopWaiting);
let els = Cc["@mozilla.org/eventlistenerservice;1"] let els = Cc["@mozilla.org/eventlistenerservice;1"]
@ -320,7 +324,7 @@ BrowserElementChild.prototype = {
content.innerHeight, "rgb(255,255,255)"); content.innerHeight, "rgb(255,255,255)");
sendAsyncMsg('got-screenshot', { sendAsyncMsg('got-screenshot', {
id: data.json.id, 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) { _keyEventHandler: function(e) {
if (whitelistedEvents.indexOf(e.keyCode) != -1 && !e.defaultPrevented) { if (whitelistedEvents.indexOf(e.keyCode) != -1 && !e.defaultPrevented) {
sendAsyncMsg('keyevent', { sendAsyncMsg('keyevent', {

View File

@ -120,8 +120,8 @@ BrowserElementParentFactory.prototype = {
function BrowserElementParent(frameLoader) { function BrowserElementParent(frameLoader) {
debug("Creating new BrowserElementParent object for " + frameLoader); debug("Creating new BrowserElementParent object for " + frameLoader);
this._screenshotListeners = {}; this._domRequestCounter = 0;
this._screenshotReqCounter = 0; this._pendingDOMRequests = {};
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement; this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
if (!this._frameElement) { if (!this._frameElement) {
@ -150,18 +150,25 @@ function BrowserElementParent(frameLoader) {
addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL); addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
addMessageListener("keyevent", this._fireKeyEvent); addMessageListener("keyevent", this._fireKeyEvent);
addMessageListener("showmodalprompt", this._handleShowModalPrompt); 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) { function defineMethod(name, fn) {
XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self); XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self);
} }
// Define methods on the frame element. function defineDOMRequestMethod(domName, msgName) {
defineMethod('getScreenshot', this._getScreenshot); XPCNativeWrapper.unwrap(self._frameElement)[domName] = self._sendDOMRequest.bind(self, msgName);
defineMethod('setVisible', this._setVisible); }
this._mm.loadFrameScript("chrome://global/content/BrowserElementChild.js", // Define methods on the frame element.
/* allowDelayedLoad = */ true); 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 = { BrowserElementParent.prototype = {
@ -265,25 +272,49 @@ BrowserElementParent.prototype = {
return this._frameElement.getAttribute('mozapp'); return this._frameElement.getAttribute('mozapp');
}, },
/**
_getScreenshot: function() { * Kick off a DOMRequest in the child process.
let id = 'req_' + this._screenshotReqCounter++; *
* 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); let req = Services.DOMRequest.createRequest(this._window);
this._screenshotListeners[id] = req; this._pendingDOMRequests[id] = req;
this._sendAsyncMsg('get-screenshot', {id: id}); this._sendAsyncMsg(msgName, {id: id});
return req; return req;
}, },
_recvGotScreenshot: function(data) { /**
var req = this._screenshotListeners[data.json.id]; * Called when the child process finishes handling a DOMRequest. We expect
delete this._screenshotListeners[data.json.id]; * data.json to have two fields:
Services.DOMRequest.fireSuccess(req, data.json.screenshot); *
* - 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) { _setVisible: function(visible) {
this._sendAsyncMsg('set-visible', {visible: visible}); this._sendAsyncMsg('set-visible', {visible: visible});
}, },
_goBack: function() {
this._sendAsyncMsg('go-back');
},
_goForward: function() {
this._sendAsyncMsg('go-forward');
},
_fireKeyEvent: function(data) { _fireKeyEvent: function(data) {
let evt = this._window.document.createEvent("KeyboardEvent"); let evt = this._window.document.createEvent("KeyboardEvent");
evt.initKeyEvent(data.json.type, true, true, this._window, evt.initKeyEvent(data.json.type, true, true, this._window,

View File

@ -58,9 +58,12 @@ _TEST_FILES = \
browserElement_SecurityChange.js \ browserElement_SecurityChange.js \
test_browserElement_inproc_SecurityChange.html \ test_browserElement_inproc_SecurityChange.html \
file_browserElement_SecurityChange.html \ file_browserElement_SecurityChange.html \
browserElement_BackForward.js \
$(NULL) $(NULL)
# OOP tests don't work on Windows (bug 763081). # 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) ifneq ($(OS_ARCH),WINNT)
_TEST_FILES += \ _TEST_FILES += \
test_browserElement_oop_LoadEvents.html \ test_browserElement_oop_LoadEvents.html \
@ -78,6 +81,7 @@ _TEST_FILES += \
test_browserElement_oop_OpenWindow.html \ test_browserElement_oop_OpenWindow.html \
test_browserElement_oop_OpenWindowRejected.html \ test_browserElement_oop_OpenWindowRejected.html \
test_browserElement_oop_SecurityChange.html \ test_browserElement_oop_SecurityChange.html \
test_browserElement_oop_BackForward.html \
$(NULL) $(NULL)
endif endif

View File

@ -101,13 +101,16 @@ const browserElementTestHelpers = {
'origOOPByDefaultPref': null, 'origOOPByDefaultPref': null,
'origPageThumbsEnabledPref': 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' + 'emptyPage1': 'http://example.com' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_empty.html', '/file_empty.html',
'emptyPage2': 'http://example.org' + 'emptyPage2': 'http://example.org' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_empty.html', '/file_empty.html',
'emptyPage3': 'http://test1.example.org' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_empty.html',
'focusPage': 'http://example.org' + 'focusPage': 'http://example.org' +
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
'/file_focus.html', '/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) { if (sIsMainProcess) {
nsCOMPtr<nsIFile> dbBaseDirectory; nsCOMPtr<nsIFile> dbBaseDirectory;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, rv = NS_GetSpecialDirectory(NS_APP_INDEXEDDB_PARENT_DIR, getter_AddRefs(dbBaseDirectory));
getter_AddRefs(dbBaseDirectory)); if (NS_FAILED(rv)) {
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(dbBaseDirectory));
}
NS_ENSURE_SUCCESS(rv, nsnull); NS_ENSURE_SUCCESS(rv, nsnull);
rv = dbBaseDirectory->Append(NS_LITERAL_STRING("indexedDB")); rv = dbBaseDirectory->Append(NS_LITERAL_STRING("indexedDB"));

View File

@ -9,15 +9,34 @@
interface nsIDOMDOMRequest; interface nsIDOMDOMRequest;
interface nsIArray; interface nsIArray;
[scriptable, uuid(b70b84f1-7ac9-4a92-bc32-8b6a7eb7879e)] [scriptable, uuid(9583b825-46b1-4e8f-bb48-9fed660a95e6)]
interface mozIDOMApplication : nsISupports interface mozIDOMApplication : nsISupports
{ {
readonly attribute jsval manifest; readonly attribute jsval manifest;
readonly attribute DOMString manifestURL; 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 origin;
readonly attribute DOMString installOrigin; 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 */ /* startPoint will be used when several launch_path exists for an app */
nsIDOMDOMRequest launch([optional] in DOMString startPoint); nsIDOMDOMRequest launch([optional] in DOMString startPoint);

View File

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

View File

@ -382,9 +382,9 @@ ContentChild::DeallocPMemoryReportRequest(PMemoryReportRequestChild* actor)
} }
PBrowserChild* 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; 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 */ /* if you remove this, please talk to cjones or dougt */
virtual bool RecvDummy(Shmem& foo) { return true; } 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 bool DeallocPBrowser(PBrowserChild*);
virtual PCrashReporterChild* virtual PCrashReporterChild*

View File

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

View File

@ -51,7 +51,13 @@ public:
NS_DECL_NSITHREADOBSERVER NS_DECL_NSITHREADOBSERVER
NS_DECL_NSIDOMGEOPOSITIONCALLBACK 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(); TestShellParent* CreateTestShell();
bool DestroyTestShell(TestShellParent* aTestShell); bool DestroyTestShell(TestShellParent* aTestShell);
@ -90,7 +96,7 @@ private:
void Init(); void Init();
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags); virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame);
virtual bool DeallocPBrowser(PBrowserParent* frame); virtual bool DeallocPBrowser(PBrowserParent* frame);
virtual PCrashReporterParent* AllocPCrashReporter(const NativeThreadId& tid, virtual PCrashReporterParent* AllocPCrashReporter(const NativeThreadId& tid,

View File

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

View File

@ -87,13 +87,14 @@ public:
}; };
TabChild::TabChild(PRUint32 aChromeFlags) TabChild::TabChild(PRUint32 aChromeFlags, bool aIsBrowserFrame)
: mRemoteFrame(nsnull) : mRemoteFrame(nsnull)
, mTabChildGlobal(nsnull) , mTabChildGlobal(nsnull)
, mChromeFlags(aChromeFlags) , mChromeFlags(aChromeFlags)
, mOuterRect(0, 0, 0, 0) , mOuterRect(0, 0, 0, 0)
, mLastBackgroundColor(NS_RGB(255, 255, 255)) , mLastBackgroundColor(NS_RGB(255, 255, 255))
, mDidFakeShow(false) , mDidFakeShow(false)
, mIsBrowserFrame(aIsBrowserFrame)
{ {
printf("creating %d!\n", NS_IsMainThread()); printf("creating %d!\n", NS_IsMainThread());
} }
@ -377,7 +378,9 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
*aReturn = nsnull; *aReturn = nsnull;
nsRefPtr<TabChild> newChild = nsRefPtr<TabChild> newChild =
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(0)); static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
/* aChromeFlags = */ 0,
/* aIsBrowserFrame = */ true));
nsCAutoString spec; nsCAutoString spec;
aURI->GetSpec(spec); aURI->GetSpec(spec);
@ -948,6 +951,13 @@ TabChild::InitTabChildGlobal()
nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler); nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
NS_ENSURE_TRUE(root, false); NS_ENSURE_TRUE(root, false);
root->SetParentTarget(scope); 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; return true;
} }

View File

@ -140,7 +140,13 @@ class TabChild : public PBrowserChild,
typedef mozilla::layout::RenderFrameChild RenderFrameChild; typedef mozilla::layout::RenderFrameChild RenderFrameChild;
public: 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(); virtual ~TabChild();
nsresult Init(); nsresult Init();
@ -266,6 +272,7 @@ private:
nsIntRect mOuterRect; nsIntRect mOuterRect;
nscolor mLastBackgroundColor; nscolor mLastBackgroundColor;
bool mDidFakeShow; bool mDidFakeShow;
bool mIsBrowserFrame;
DISALLOW_EVIL_CONSTRUCTORS(TabChild); DISALLOW_EVIL_CONSTRUCTORS(TabChild);
}; };

View File

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

View File

@ -20,6 +20,14 @@
#include "jsapi.h" #include "jsapi.h"
#include "jsfriendapi.h" #include "jsfriendapi.h"
#include "BindingUtils.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" #include "OSFileConstants.h"
/** /**
@ -320,6 +328,28 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
return false; return false;
} }
#endif // defined(XP_WIN) #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; return true;
} }

View File

@ -17,8 +17,6 @@ const DEBUG = RIL.DEBUG_RIL;
const RADIOINTERFACELAYER_CID = const RADIOINTERFACELAYER_CID =
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}"); Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
const DATACALLINFO_CID =
Components.ID("{ef474cd9-94f7-4c05-a31b-29b9de8a10d2}");
const nsIAudioManager = Ci.nsIAudioManager; const nsIAudioManager = Ci.nsIAudioManager;
const nsIRadioInterfaceLayer = Ci.nsIRadioInterfaceLayer; 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() { function RadioInterfaceLayer() {
debug("Starting RIL Worker"); debug("Starting RIL Worker");
this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js"); this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js");
@ -485,8 +469,7 @@ RadioInterfaceLayer.prototype = {
voiceInfo.type = null; voiceInfo.type = null;
voiceInfo.signalStrength = null; voiceInfo.signalStrength = null;
voiceInfo.relSignalStrength = null; voiceInfo.relSignalStrength = null;
ppmm.sendAsyncMessage("RIL:VoiceThis.RadioState.VoiceChanged", ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
voiceInfo);
return; return;
} }
@ -532,6 +515,23 @@ RadioInterfaceLayer.prototype = {
}, },
updateDataConnection: function updateDataConnection(state) { 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()) { if (!this._isDataEnabled()) {
return false; return false;
} }
@ -548,9 +548,6 @@ RadioInterfaceLayer.prototype = {
// RILNetworkInterface will ignore this if it's already connected. // RILNetworkInterface will ignore this if it's already connected.
RILNetworkInterface.connect(); 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; return false;
}, },
@ -876,22 +873,23 @@ RadioInterfaceLayer.prototype = {
* Handle data call state changes. * Handle data call state changes.
*/ */
handleDataCallState: function handleDataCallState(datacall) { 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", this._deliverDataCallCallback("dataCallStateChanged",
[datacall.cid, datacall.ifname, datacall.state]); [datacall]);
}, },
/** /**
* Handle data call list. * Handle data call list.
*/ */
handleDataCallList: function handleDataCallList(message) { 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", this._deliverDataCallCallback("receiveDataCallList",
[datacalls, datacalls.length]); [message.datacalls, message.datacalls.length]);
}, },
/** /**
@ -1695,14 +1693,14 @@ let RILNetworkInterface = {
// nsIRILDataCallback // nsIRILDataCallback
dataCallStateChanged: function dataCallStateChanged(cid, interfaceName, callState) { dataCallStateChanged: function dataCallStateChanged(datacall) {
debug("Data call ID: " + cid + ", interface name: " + interfaceName); debug("Data call ID: " + datacall.cid + ", interface name: " + datacall.ifname);
if (this.connecting && if (this.connecting &&
(callState == RIL.GECKO_NETWORK_STATE_CONNECTING || (datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTING ||
callState == RIL.GECKO_NETWORK_STATE_CONNECTED)) { datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
this.connecting = false; this.connecting = false;
this.cid = cid; this.cid = datacall.cid;
this.name = interfaceName; this.name = datacall.ifname;
if (!this.registeredAsNetworkInterface) { if (!this.registeredAsNetworkInterface) {
let networkManager = Cc["@mozilla.org/network/manager;1"] let networkManager = Cc["@mozilla.org/network/manager;1"]
.getService(Ci.nsINetworkManager); .getService(Ci.nsINetworkManager);
@ -1710,14 +1708,14 @@ let RILNetworkInterface = {
this.registeredAsNetworkInterface = true; this.registeredAsNetworkInterface = true;
} }
} }
if (this.cid != cid) { if (this.cid != datacall.cid) {
return; return;
} }
if (this.state == callState) { if (this.state == datacall.state) {
return; return;
} }
this.state = callState; this.state = datacall.state;
Services.obs.notifyObservers(this, Services.obs.notifyObservers(this,
kNetworkInterfaceStateChangedTopic, kNetworkInterfaceStateChangedTopic,
null); null);

View File

@ -62,30 +62,25 @@ interface nsIRILTelephonyCallback : nsISupports
in AString error); in AString error);
}; };
[scriptable, uuid(66a55943-e63b-4731-aece-9c04bfc14019)] [scriptable, uuid(8a711703-1ee5-4675-9d9a-0b188e944cfe)]
interface nsIRILDataCallInfo : nsISupports interface nsIRILDataCallInfo : nsISupports
{ {
readonly attribute unsigned long callState; readonly attribute unsigned long state;
readonly attribute AString cid; readonly attribute AString cid;
readonly attribute AString apn; 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 interface nsIRILDataCallback : nsISupports
{ {
/** /**
* Notified when a data call changes state. * Notified when a data call changes state.
* *
* @param cid * @param dataCall
* The CID of the data call. * A nsIRILDataCallInfo object.
* @param interfaceName
* Name of the associated network interface.
* @param dataState
* One of the nsIRadioInterfaceLayer::DATACALL_STATE_* values.
*/ */
void dataCallStateChanged(in AString cid, void dataCallStateChanged(in nsIRILDataCallInfo dataCall);
in AString interfaceName,
in unsigned short callState);
/** /**
* Called when nsIRadioInterfaceLayer is asked to enumerate the current * Called when nsIRadioInterfaceLayer is asked to enumerate the current

View File

@ -689,6 +689,12 @@ let RIL = {
// call state. // call state.
let model_id = libcutils.property_get("ril.model_id"); let model_id = libcutils.property_get("ril.model_id");
if (DEBUG) debug("Detected RIL model " + 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 (model_id == "I9100") {
if (DEBUG) { if (DEBUG) {
debug("Detected I9100, enabling " + debug("Detected I9100, enabling " +
@ -1524,8 +1530,22 @@ let RIL = {
*/ */
hangUp: function hangUp(options) { hangUp: function hangUp(options) {
let call = this.currentCalls[options.callIndex]; let call = this.currentCalls[options.callIndex];
if (call && call.state != CALL_STATE_HOLDING) { if (!call) {
Buf.simpleRequest(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND); 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. * Helpers for processing call state and handle the active call.
*/ */
@ -2982,36 +3044,12 @@ RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
return; return;
} }
let operator = Buf.readStringList(); let operatorData = Buf.readStringList();
if (DEBUG) debug("operator: " + operatorData);
if (DEBUG) debug("Operator data: " + operator); this._processOperator(operatorData);
if (operator.length < 3) {
if (DEBUG) debug("Expected at least 3 strings for operator.");
}
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_RADIO_POWER] = null;
RIL[REQUEST_DTMF] = null; RIL[REQUEST_DTMF] = null;

View File

@ -478,26 +478,33 @@ Telephony::EnumerateCallState(PRUint32 aCallIndex, PRUint16 aCallState,
NS_IMETHODIMP NS_IMETHODIMP
Telephony::NotifyError(PRInt32 aCallIndex, Telephony::NotifyError(PRInt32 aCallIndex,
const nsAString& aError) const nsAString& aError)
{ {
PRInt32 index = -1; nsRefPtr<TelephonyCall> callToNotify;
PRInt32 length = mCalls.Length(); 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 (!callToNotify) {
if (aCallIndex == -1) { NS_ERROR("Don't call me with a bad call index!");
if (length > 0) { return NS_ERROR_UNEXPECTED;
index = length - 1;
}
} else {
if (aCallIndex < 0 || aCallIndex >= length) {
return NS_ERROR_INVALID_ARG;
}
index = aCallIndex;
}
if (index != -1) {
mCalls[index]->NotifyError(aError);
} }
// Set the call state to 'disconnected' and remove it from the calls list.
callToNotify->NotifyError(aError);
return NS_OK; return NS_OK;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -23,8 +23,8 @@ class RegExpMatchBuilder
JSContext * const cx; JSContext * const cx;
RootedObject array; RootedObject array;
bool setProperty(JSAtom *name, Value v) { bool setProperty(Handle<PropertyName*> name, Value v) {
return !!baseops::DefineProperty(cx, array, RootedId(cx, AtomToId(name)), &v, return !!baseops::DefineProperty(cx, array, name, &v,
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE); JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
} }
@ -38,12 +38,14 @@ class RegExpMatchBuilder
} }
bool setIndex(int index) { 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) { bool setInput(JSString *str) {
JS_ASSERT(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) { if (args.length() == 0) {
RegExpStatics *res = cx->regExpStatics(); RegExpStatics *res = cx->regExpStatics();
RegExpObject *reobj = builder.build(RootedAtom(cx, cx->runtime->emptyString), Rooted<JSAtom*> empty(cx, cx->runtime->emptyString);
res->getFlags()); RegExpObject *reobj = builder.build(empty, res->getFlags());
if (!reobj) if (!reobj)
return false; return false;
args.rval() = ObjectValue(*reobj); args.rval() = ObjectValue(*reobj);
@ -242,7 +244,8 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
if (!sourceObj.getProperty(cx, cx->runtime->atomState.sourceAtom, &v)) if (!sourceObj.getProperty(cx, cx->runtime->atomState.sourceAtom, &v))
return false; 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) if (!reobj)
return false; return false;
@ -462,7 +465,8 @@ js_InitRegExpClass(JSContext *cx, JSObject *obj)
proto->setPrivate(NULL); proto->setPrivate(NULL);
RegExpObjectBuilder builder(cx, &proto->asRegExp()); 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; return NULL;
if (!DefinePropertiesAndBrand(cx, proto, NULL, regexp_methods)) 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))))))) 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 is not defined under js/src, thus we make it mean DIST there.
LIBXUL_DIST ?= $(DIST) LIBXUL_DIST ?= $(DIST)

View File

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

View File

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

View File

@ -468,7 +468,7 @@ case "$target" in
AC_LANG_RESTORE AC_LANG_RESTORE
changequote(,) 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([,]) changequote([,])
# Determine compiler version # Determine compiler version
@ -521,7 +521,7 @@ case "$target" in
fi fi
changequote(,) 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([,]) changequote([,])
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"` MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
if test -z "$MSMANIFEST_TOOL_VERSION"; then 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); JS_ASSERT_IF(staticLevel != 0, callerFrame);
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version, Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
callerFrame, /* foldConstants = */ true, compileAndGo); /* foldConstants = */ true, compileAndGo);
if (!parser.init()) if (!parser.init())
return NULL; return NULL;
@ -113,21 +113,16 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
if (!script) if (!script)
return NULL; 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()) if (!bce.init())
return NULL; 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 this is a direct call to eval, inherit the caller's strictness. */
if (callerFrame && callerFrame->isScriptFrame() && callerFrame->script()->strictModeCode) if (callerFrame && callerFrame->isScriptFrame() && callerFrame->script()->strictModeCode)
sc.setInStrictMode(); sc.setInStrictMode();
@ -192,10 +187,10 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
if (inDirectivePrologue && !parser.recognizeDirectivePrologue(pn, &inDirectivePrologue)) if (inDirectivePrologue && !parser.recognizeDirectivePrologue(pn, &inDirectivePrologue))
return NULL; return NULL;
if (!FoldConstants(cx, pn, bce.parser)) if (!FoldConstants(cx, pn, &parser))
return NULL; return NULL;
if (!AnalyzeFunctions(bce.parser)) if (!AnalyzeFunctions(&parser, callerFrame))
return NULL; return NULL;
tc.functionList = 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()) if (!pn->isKind(PNK_SEMI) || !pn->pn_kid || !pn->pn_kid->isXMLItem())
onlyXML = false; onlyXML = false;
#endif #endif
bce.parser->freeTree(pn); parser.freeTree(pn);
} }
#if JS_HAS_XML_SUPPORT #if JS_HAS_XML_SUPPORT
@ -222,8 +217,18 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
} }
#endif #endif
if (!parser.checkForArgumentsAndRest()) // It's an error to use |arguments| in a function that has a rest parameter.
return NULL; 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 * 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) const char *filename, unsigned lineno, JSVersion version)
{ {
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version, Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
/* callerFrame = */ NULL, /* foldConstants = */ true, /* foldConstants = */ true, /* compileAndGo = */ false);
/* compileAndGo = */ false);
if (!parser.init()) if (!parser.init())
return false; return false;
@ -271,11 +275,13 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
if (!script) if (!script)
return false; 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()) if (!funbce.init())
return false; return false;
funsc.bindings.transfer(cx, bindings); funsc.bindings.transfer(bindings);
fun->setArgCount(funsc.bindings.numArgs()); fun->setArgCount(funsc.bindings.numArgs());
if (!GenerateBlockId(&funsc, funsc.bodyid)) if (!GenerateBlockId(&funsc, funsc.bodyid))
return false; return false;
@ -328,7 +334,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
if (!FoldConstants(cx, pn, &parser)) if (!FoldConstants(cx, pn, &parser))
return false; return false;
if (!AnalyzeFunctions(&parser)) if (!AnalyzeFunctions(&parser, nullCallerFrame))
return false; return false;
if (fn->pn_body) { if (fn->pn_body) {

View File

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

View File

@ -63,21 +63,13 @@ class GCConstList {
void finish(ConstArray *array); void finish(ConstArray *array);
}; };
struct GlobalScope {
GlobalScope(JSContext *cx, JSObject *globalObj)
: globalObj(cx, globalObj)
{ }
RootedObject globalObj;
};
struct BytecodeEmitter 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 { struct {
jsbytecode *base; /* base of JS bytecode vector */ jsbytecode *base; /* base of JS bytecode vector */
@ -90,7 +82,9 @@ struct BytecodeEmitter
unsigned currentLine; /* line number for tree-based srcnote gen */ unsigned currentLine; /* line number for tree-based srcnote gen */
} prolog, main, *current; } 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 */ OwnedAtomIndexMapPtr atomIndices; /* literals indexed for mapping */
unsigned firstLine; /* first line, for JSScript::initFromEmitter */ unsigned firstLine; /* first line, for JSScript::initFromEmitter */
@ -114,8 +108,6 @@ struct BytecodeEmitter
CGObjectList regexpList; /* list of emitted regexp that will be CGObjectList regexpList; /* list of emitted regexp that will be
cloned during execution */ cloned during execution */
GlobalScope *globalScope; /* frontend::CompileScript global scope, or null */
/* Vectors of pn_cookie slot values. */ /* Vectors of pn_cookie slot values. */
typedef Vector<uint32_t, 8> SlotVector; typedef Vector<uint32_t, 8> SlotVector;
SlotVector closedArgs; SlotVector closedArgs;
@ -127,7 +119,12 @@ struct BytecodeEmitter
bool inForInit:1; /* emitting init expr of for; exclude 'in' */ 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(); bool init();
/* /*

View File

@ -84,13 +84,12 @@ StrictModeGetter::get() const
Parser::Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin, Parser::Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
const jschar *chars, size_t length, const char *fn, unsigned ln, JSVersion v, 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), : AutoGCRooter(cx, PARSER),
context(cx), context(cx),
strictModeGetter(this), strictModeGetter(this),
tokenStream(cx, prin, originPrin, chars, length, fn, ln, v, &strictModeGetter), tokenStream(cx, prin, originPrin, chars, length, fn, ln, v, &strictModeGetter),
tempPoolMark(NULL), tempPoolMark(NULL),
callerFrame(cfp),
allocator(cx), allocator(cx),
traceListHead(NULL), traceListHead(NULL),
tc(NULL), tc(NULL),
@ -99,7 +98,6 @@ Parser::Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
compileAndGo(compileAndGo) compileAndGo(compileAndGo)
{ {
cx->activeCompilations++; cx->activeCompilations++;
JS_ASSERT_IF(cfp, cfp->isScriptFrame());
} }
bool bool
@ -157,7 +155,7 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn,
siblings(tc->functionList), siblings(tc->functionList),
kids(NULL), kids(NULL),
parent(tc->sc->inFunction() ? tc->sc->funbox() : NULL), parent(tc->sc->inFunction() ? tc->sc->funbox() : NULL),
bindings(tc->sc->context), bindings(),
level(tc->staticLevel), level(tc->staticLevel),
ndefaults(0), ndefaults(0),
inLoop(false), inLoop(false),
@ -495,7 +493,7 @@ CheckStrictParameters(JSContext *cx, Parser *parser)
if (!parameters.init(sc->bindings.numArgs())) if (!parameters.init(sc->bindings.numArgs()))
return false; 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()) { for (Shape::Range r = sc->bindings.lastVariable(); !r.empty(); r.popFront()) {
jsid id = r.front().propid(); jsid id = r.front().propid();
if (!JSID_IS_ATOM(id)) if (!JSID_IS_ATOM(id))
@ -540,7 +538,8 @@ BindLocalVariable(JSContext *cx, TreeContext *tc, ParseNode *pn, BindingKind kin
JS_ASSERT(kind == VARIABLE || kind == CONSTANT); JS_ASSERT(kind == VARIABLE || kind == CONSTANT);
unsigned index = tc->sc->bindings.numVars(); 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; return false;
if (!pn->pn_cookie.set(cx, tc->staticLevel, index)) if (!pn->pn_cookie.set(cx, tc->staticLevel, index))
@ -604,7 +603,7 @@ Parser::functionBody(FunctionBodyType type)
if (!CheckStrictParameters(context, this)) if (!CheckStrictParameters(context, this))
return NULL; 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 * Non-top-level functions use JSOP_DEFFUN which is a dynamic scope
@ -709,24 +708,6 @@ Parser::functionBody(FunctionBodyType type)
return pn; 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|. // Create a placeholder Definition node for |atom|.
// Nb: unlike most functions that are passed a Parser, this one gets a // 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 // 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; return true;
} }
@ -6851,8 +6832,8 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
pn->pn_xflags |= PNX_NONCONST; pn->pn_xflags |= PNX_NONCONST;
/* NB: Getter function in { get x(){} } is unnamed. */ /* NB: Getter function in { get x(){} } is unnamed. */
pn2 = functionDef(RootedPropertyName(context, NULL), Rooted<PropertyName*> funName(context, NULL);
op == JSOP_GETTER ? Getter : Setter, Expression); pn2 = functionDef(funName, op == JSOP_GETTER ? Getter : Setter, Expression);
if (!pn2) if (!pn2)
return NULL; return NULL;
TokenPos pos = {begin, pn2->pn_pos.end}; 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 */ StrictModeGetter strictModeGetter; /* used by tokenStream to test for strict mode */
TokenStream tokenStream; TokenStream tokenStream;
void *tempPoolMark; /* initial JSContext.tempLifoAlloc mark */ void *tempPoolMark; /* initial JSContext.tempLifoAlloc mark */
StackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */
ParseNodeAllocator allocator; ParseNodeAllocator allocator;
ObjectBox *traceListHead; /* list of parsed object for GC tracing */ ObjectBox *traceListHead; /* list of parsed object for GC tracing */
@ -57,7 +56,7 @@ struct Parser : private AutoGCRooter
public: public:
Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin, Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
const jschar *chars, size_t length, const char *fn, unsigned ln, JSVersion version, const jschar *chars, size_t length, const char *fn, unsigned ln, JSVersion version,
StackFrame *cfp, bool foldConstants, bool compileAndGo); bool foldConstants, bool compileAndGo);
~Parser(); ~Parser();
friend void AutoGCRooter::trace(JSTracer *trc); friend void AutoGCRooter::trace(JSTracer *trc);
@ -141,8 +140,6 @@ struct Parser : private AutoGCRooter
enum FunctionBodyType { StatementListBody, ExpressionBody }; enum FunctionBodyType { StatementListBody, ExpressionBody };
ParseNode *functionBody(FunctionBodyType type); ParseNode *functionBody(FunctionBodyType type);
bool checkForArgumentsAndRest();
private: private:
/* /*
* JS parsers, from lowest to highest precedence. * JS parsers, from lowest to highest precedence.

View File

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

View File

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

View File

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

View File

@ -102,7 +102,7 @@ class Handle
* Construct a handle from an explicitly rooted location. This is the * Construct a handle from an explicitly rooted location. This is the
* normal way to create a handle, and normally happens implicitly. * 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; } const T *address() const { return ptr; }
T value() 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) { init(cx, RootMethods<T>::initial()); }
Rooted(JSContext *cx, T initial) { init(cx, 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() ~Rooted()
{ {
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) #if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
@ -223,7 +214,7 @@ class Rooted
template<typename T> template <typename S> template<typename T> template <typename S>
inline inline
Handle<T>::Handle(const Rooted<S> &root) Handle<T>::Handle(Rooted<S> &root)
{ {
testAssign<S>(); testAssign<S>();
ptr = reinterpret_cast<const T *>(root.address()); ptr = reinterpret_cast<const T *>(root.address());

View File

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

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