Merge from mozilla-central.

--HG--
extra : rebase_source : 521cbf2f434cad88106f32be797faae4861afc39
This commit is contained in:
David Anderson 2012-06-25 13:09:36 -07:00
parent b5f5c1ab01
commit 1222b46c77
210 changed files with 2596 additions and 1090 deletions

View File

@ -266,17 +266,14 @@ let MigratorPrototype = {
getService(Ci.nsIObserver); getService(Ci.nsIObserver);
browserGlue.observe(null, TOPIC_WILL_IMPORT_BOOKMARKS, ""); browserGlue.observe(null, TOPIC_WILL_IMPORT_BOOKMARKS, "");
let bookmarksHTMLFile = Services.dirsvc.get("BMarks", Ci.nsIFile); // Note doMigrate doesn't care about the success value of the
if (bookmarksHTMLFile.exists()) { // callback.
// Note doMigrate doesn't care about the success value of the BookmarkHTMLUtils.importFromURL(
// callback. "resource:///defaults/profile/bookmarks.html", true, function(a) {
BookmarkHTMLUtils.importFromURL( browserGlue.observe(null, TOPIC_DID_IMPORT_BOOKMARKS, "");
NetUtil.newURI(bookmarksHTMLFile).spec, true, function(a) { doMigrate();
browserGlue.observe(null, TOPIC_DID_IMPORT_BOOKMARKS, ""); });
doMigrate(); return;
});
return;
}
} }
} }
doMigrate(); doMigrate();

View File

@ -250,9 +250,6 @@ let UI = {
let event = document.createEvent("Events"); let event = document.createEvent("Events");
event.initEvent("tabviewframeinitialized", true, false); event.initEvent("tabviewframeinitialized", true, false);
dispatchEvent(event); dispatchEvent(event);
// XXX this can be removed when bug 731868 is fixed
event = null;
} catch(e) { } catch(e) {
Utils.log(e); Utils.log(e);
} finally { } finally {

View File

@ -42,10 +42,10 @@ let WebappsInstaller = {
shell.install(); shell.install();
} catch (ex) { } catch (ex) {
Cu.reportError("Error installing app: " + ex); Cu.reportError("Error installing app: " + ex);
return false; return null;
} }
return true; return shell;
} }
} }
@ -107,12 +107,16 @@ function NativeApp(aData) {
} }
this.shortDescription = sanitize(shortDesc); this.shortDescription = sanitize(shortDesc);
this.appcacheDefined = (app.manifest.appcache_path != undefined);
this.manifest = app.manifest; this.manifest = app.manifest;
this.profileFolder = Services.dirsvc.get("ProfD", Ci.nsIFile); // The app registry is the Firefox profile from which the app
// was installed.
this.registryFolder = Services.dirsvc.get("ProfD", Ci.nsIFile);
this.webappJson = { this.webappJson = {
"registryDir": this.profileFolder.path, "registryDir": this.registryFolder.path,
"app": app "app": app
}; };
@ -125,8 +129,8 @@ function NativeApp(aData) {
* *
* The Windows installation process will generate the following files: * The Windows installation process will generate the following files:
* *
* ${FolderName} = app-origin;protocol;port * ${FolderName} = protocol;app-origin[;port]
* e.g.: subdomain.example.com;http;-1 * e.g.: subdomain.example.com;http;85
* *
* %APPDATA%/${FolderName} * %APPDATA%/${FolderName}
* - webapp.ini * - webapp.ini
@ -170,6 +174,7 @@ WinNativeApp.prototype = {
this._createConfigFiles(); this._createConfigFiles();
this._createShortcutFiles(); this._createShortcutFiles();
this._writeSystemKeys(); this._writeSystemKeys();
this._createAppProfile();
} catch (ex) { } catch (ex) {
this._removeInstallation(); this._removeInstallation();
throw(ex); throw(ex);
@ -191,8 +196,8 @@ WinNativeApp.prototype = {
} }
// The ${InstallDir} format is as follows: // The ${InstallDir} format is as follows:
// host of the app origin + ";" +
// protocol // protocol
// + ";" + host of the app origin
// + ";" + port (only if port is not default) // + ";" + port (only if port is not default)
this.installDir = Services.dirsvc.get("AppData", Ci.nsIFile); this.installDir = Services.dirsvc.get("AppData", Ci.nsIFile);
let installDirLeaf = this.launchURI.scheme let installDirLeaf = this.launchURI.scheme
@ -280,6 +285,20 @@ WinNativeApp.prototype = {
this.uninstallDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); this.uninstallDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
}, },
/**
* Creates the profile to be used for this app.
*/
_createAppProfile: function() {
if (!this.appcacheDefined)
return;
let profSvc = Cc["@mozilla.org/toolkit/profile-service;1"]
.getService(Ci.nsIToolkitProfileService);
this.appProfile = profSvc.createDefaultProfileForApp(this.installDir.leafName,
null, null);
},
/** /**
* Copy the pre-built files into their destination folders. * Copy the pre-built files into their destination folders.
*/ */
@ -495,6 +514,7 @@ MacNativeApp.prototype = {
this._createDirectoryStructure(); this._createDirectoryStructure();
this._copyPrebuiltFiles(); this._copyPrebuiltFiles();
this._createConfigFiles(); this._createConfigFiles();
this._createAppProfile();
} catch (ex) { } catch (ex) {
this._removeInstallation(false); this._removeInstallation(false);
throw(ex); throw(ex);
@ -533,6 +553,17 @@ MacNativeApp.prototype = {
this.resourcesDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); this.resourcesDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
}, },
_createAppProfile: function() {
if (!this.appcacheDefined)
return;
let profSvc = Cc["@mozilla.org/toolkit/profile-service;1"]
.getService(Ci.nsIToolkitProfileService);
this.appProfile = profSvc.createDefaultProfileForApp(this.appProfileDir.leafName,
null, null);
},
_copyPrebuiltFiles: function() { _copyPrebuiltFiles: function() {
let webapprt = this.runtimeFolder.clone(); let webapprt = this.runtimeFolder.clone();
webapprt.append("webapprt-stub"); webapprt.append("webapprt-stub");
@ -695,6 +726,7 @@ LinuxNativeApp.prototype = {
this._createDirectoryStructure(); this._createDirectoryStructure();
this._copyPrebuiltFiles(); this._copyPrebuiltFiles();
this._createConfigFiles(); this._createConfigFiles();
this._createAppProfile();
} catch (ex) { } catch (ex) {
this._removeInstallation(); this._removeInstallation();
throw(ex); throw(ex);
@ -724,6 +756,17 @@ LinuxNativeApp.prototype = {
webapprtPre.copyTo(this.installDir, this.webapprt.leafName); webapprtPre.copyTo(this.installDir, this.webapprt.leafName);
}, },
_createAppProfile: function() {
if (!this.appcacheDefined)
return;
let profSvc = Cc["@mozilla.org/toolkit/profile-service;1"]
.getService(Ci.nsIToolkitProfileService);
return profSvc.createDefaultProfileForApp(this.installDir.leafName,
null, null);
},
_createConfigFiles: function() { _createConfigFiles: function() {
// ${InstallDir}/webapp.json // ${InstallDir}/webapp.json
let configJson = this.installDir.clone(); let configJson = this.installDir.clone();

View File

@ -109,8 +109,14 @@ let webappsUI = {
label: bundle.getString("webapps.install"), label: bundle.getString("webapps.install"),
accessKey: bundle.getString("webapps.install.accesskey"), accessKey: bundle.getString("webapps.install.accesskey"),
callback: function(notification) { callback: function(notification) {
if (WebappsInstaller.install(aData)) { let app = WebappsInstaller.install(aData);
DOMApplicationRegistry.confirmInstall(aData); if (app) {
let localDir = null;
if (app.appcacheDefined && app.appProfile) {
localDir = app.appProfile.localDir;
}
DOMApplicationRegistry.confirmInstall(aData, false, localDir);
} else { } else {
DOMApplicationRegistry.denyInstall(aData); DOMApplicationRegistry.denyInstall(aData);
} }

View File

@ -1009,10 +1009,6 @@ toolbar[iconsize="small"] #feed-button {
list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png); list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png);
} }
.mixedContent > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-icons-https-mixed.png);
}
#identity-box:hover > #page-proxy-favicon { #identity-box:hover > #page-proxy-favicon {
-moz-image-region: rect(0, 32px, 16px, 16px); -moz-image-region: rect(0, 32px, 16px, 16px);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 B

View File

@ -26,7 +26,6 @@ browser.jar:
skin/classic/browser/identity-icons-generic.png skin/classic/browser/identity-icons-generic.png
skin/classic/browser/identity-icons-https.png skin/classic/browser/identity-icons-https.png
skin/classic/browser/identity-icons-https-ev.png skin/classic/browser/identity-icons-https-ev.png
skin/classic/browser/identity-icons-https-mixed.png
skin/classic/browser/Info.png skin/classic/browser/Info.png
skin/classic/browser/KUI-close.png skin/classic/browser/KUI-close.png
skin/classic/browser/monitor.png skin/classic/browser/monitor.png

View File

@ -1066,10 +1066,6 @@ toolbar[mode="icons"] #zoom-in-button {
list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png); list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png);
} }
.mixedContent > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-icons-https-mixed.png);
}
#identity-box:hover:active > #page-proxy-favicon, #identity-box:hover:active > #page-proxy-favicon,
#identity-box[open=true] > #page-proxy-favicon { #identity-box[open=true] > #page-proxy-favicon {
-moz-image-region: rect(0, 32px, 16px, 16px); -moz-image-region: rect(0, 32px, 16px, 16px);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

View File

@ -32,7 +32,6 @@ browser.jar:
skin/classic/browser/identity-icons-generic.png skin/classic/browser/identity-icons-generic.png
skin/classic/browser/identity-icons-https.png skin/classic/browser/identity-icons-https.png
skin/classic/browser/identity-icons-https-ev.png skin/classic/browser/identity-icons-https-ev.png
skin/classic/browser/identity-icons-https-mixed.png
skin/classic/browser/Info.png skin/classic/browser/Info.png
skin/classic/browser/KUI-background.png skin/classic/browser/KUI-background.png
skin/classic/browser/KUI-close.png skin/classic/browser/KUI-close.png

View File

@ -1446,10 +1446,6 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png); list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png);
} }
.mixedContent > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-icons-https-mixed.png);
}
#identity-box:hover > #page-proxy-favicon { #identity-box:hover > #page-proxy-favicon {
-moz-image-region: rect(0, 32px, 16px, 16px); -moz-image-region: rect(0, 32px, 16px, 16px);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 B

View File

@ -32,7 +32,6 @@ browser.jar:
skin/classic/browser/identity-icons-generic.png skin/classic/browser/identity-icons-generic.png
skin/classic/browser/identity-icons-https.png skin/classic/browser/identity-icons-https.png
skin/classic/browser/identity-icons-https-ev.png skin/classic/browser/identity-icons-https-ev.png
skin/classic/browser/identity-icons-https-mixed.png
skin/classic/browser/keyhole-forward-mask.svg skin/classic/browser/keyhole-forward-mask.svg
skin/classic/browser/KUI-background.png skin/classic/browser/KUI-background.png
skin/classic/browser/KUI-close.png skin/classic/browser/KUI-close.png
@ -230,7 +229,6 @@ browser.jar:
skin/classic/aero/browser/identity-icons-generic.png skin/classic/aero/browser/identity-icons-generic.png
skin/classic/aero/browser/identity-icons-https.png skin/classic/aero/browser/identity-icons-https.png
skin/classic/aero/browser/identity-icons-https-ev.png skin/classic/aero/browser/identity-icons-https-ev.png
skin/classic/aero/browser/identity-icons-https-mixed.png
skin/classic/aero/browser/keyhole-forward-mask.svg skin/classic/aero/browser/keyhole-forward-mask.svg
skin/classic/aero/browser/KUI-background.png skin/classic/aero/browser/KUI-background.png
skin/classic/aero/browser/KUI-close.png skin/classic/aero/browser/KUI-close.png

View File

@ -98,6 +98,7 @@ case "$target" in
fi fi
dnl set up compilers dnl set up compilers
TOOLCHAIN_PREFIX="$android_toolchain/bin/$android_tool_prefix-"
AS="$android_toolchain"/bin/"$android_tool_prefix"-as AS="$android_toolchain"/bin/"$android_tool_prefix"-as
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++ CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++

View File

@ -105,7 +105,7 @@ public class DoCommand {
String ffxProvider = "org.mozilla.ffxcp"; String ffxProvider = "org.mozilla.ffxcp";
String fenProvider = "org.mozilla.fencp"; String fenProvider = "org.mozilla.fencp";
private final String prgVersion = "SUTAgentAndroid Version 1.08"; private final String prgVersion = "SUTAgentAndroid Version 1.09";
public enum Command public enum Command
{ {
@ -162,6 +162,7 @@ public class DoCommand {
INST ("inst"), INST ("inst"),
UPDT ("updt"), UPDT ("updt"),
UNINST ("uninst"), UNINST ("uninst"),
UNINSTALL ("uninstall"),
TEST ("test"), TEST ("test"),
DBG ("dbg"), DBG ("dbg"),
TRACE ("trace"), TRACE ("trace"),
@ -356,9 +357,16 @@ public class DoCommand {
case UNINST: case UNINST:
if (Argc >= 2) if (Argc >= 2)
strReturn = UnInstallApp(Argv[1], cmdOut); strReturn = UnInstallApp(Argv[1], cmdOut, true);
else else
strReturn = sErrorPrefix + "Wrong number of arguments for inst command!"; strReturn = sErrorPrefix + "Wrong number of arguments for uninst command!";
break;
case UNINSTALL:
if (Argc >= 2)
strReturn = UnInstallApp(Argv[1], cmdOut, false);
else
strReturn = sErrorPrefix + "Wrong number of arguments for uninstall command!";
break; break;
case ALRT: case ALRT:
@ -3115,13 +3123,17 @@ private void CancelNotification()
return theArgs; return theArgs;
} }
public String UnInstallApp(String sApp, OutputStream out) public String UnInstallApp(String sApp, OutputStream out, boolean reboot)
{ {
String sRet = ""; String sRet = "";
try try
{ {
pProc = Runtime.getRuntime().exec(this.getSuArgs("pm uninstall " + sApp + ";reboot;exit")); if (reboot == true) {
pProc = Runtime.getRuntime().exec(this.getSuArgs("pm uninstall " + sApp + ";reboot;exit"));
} else {
pProc = Runtime.getRuntime().exec(this.getSuArgs("pm uninstall " + sApp + ";exit"));
}
RedirOutputThread outThrd = new RedirOutputThread(pProc, out); RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
outThrd.start(); outThrd.start();
@ -3762,7 +3774,8 @@ private void CancelNotification()
"zip zipfile src - zip the source file/dir into zipfile\n" + "zip zipfile src - zip the source file/dir into zipfile\n" +
"rebt - reboot device\n" + "rebt - reboot device\n" +
"inst /path/filename.apk - install the referenced apk file\n" + "inst /path/filename.apk - install the referenced apk file\n" +
"uninst packagename - uninstall the referenced package\n" + "uninst packagename - uninstall the referenced package and reboot\n" +
"uninstall packagename - uninstall the referenced package without a reboot\n" +
"updt pkgname pkgfile - unpdate the referenced package\n" + "updt pkgname pkgfile - unpdate the referenced package\n" +
"clok - the current device time expressed as the" + "clok - the current device time expressed as the" +
" number of millisecs since epoch\n" + " number of millisecs since epoch\n" +

View File

@ -357,6 +357,7 @@ HAVE_64BIT_OS = @HAVE_64BIT_OS@
CC = @CC@ CC = @CC@
CXX = @CXX@ CXX = @CXX@
CPP = @CPP@ CPP = @CPP@
TOOLCHAIN_PREFIX = @TOOLCHAIN_PREFIX@
CC_VERSION = @CC_VERSION@ CC_VERSION = @CC_VERSION@
CXX_VERSION = @CXX_VERSION@ CXX_VERSION = @CXX_VERSION@

View File

@ -736,8 +736,8 @@ OPTIMIZE_JARS_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/optimizeja
CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py) CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(basename $(@F)).pp --target $@) EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp --target $@)
EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(basename $(@F)).pp) EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp)
EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR) EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC) EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC) EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC)

View File

@ -286,7 +286,7 @@ endif
ifndef MOZ_AUTO_DEPS ifndef MOZ_AUTO_DEPS
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)) ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:.$(OBJ_SUFFIX)=.pp)) MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:=.pp))
ifndef NO_GEN_XPT ifndef NO_GEN_XPT
MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp)) MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
endif endif

View File

@ -171,6 +171,7 @@ if test -n "$gonkdir" ; then
ANDROID_NDK="${ANDROID_SOURCE}/ndk" ANDROID_NDK="${ANDROID_SOURCE}/ndk"
dnl set up compilers dnl set up compilers
TOOLCHAIN_PREFIX="$gonk_toolchain_prefix"
AS="$gonk_toolchain_prefix"as AS="$gonk_toolchain_prefix"as
CC="$gonk_toolchain_prefix"gcc CC="$gonk_toolchain_prefix"gcc
CXX="$gonk_toolchain_prefix"g++ CXX="$gonk_toolchain_prefix"g++
@ -7762,7 +7763,7 @@ MOZ_ARG_DISABLE_BOOL(md,
fi]) fi])
if test "$_cpp_md_flag"; then if test "$_cpp_md_flag"; then
COMPILER_DEPEND=1 COMPILER_DEPEND=1
_DEPEND_CFLAGS='$(filter-out %/.pp,-MD -MF $(MDDEPDIR)/$(basename $(@F)).pp)' _DEPEND_CFLAGS='$(filter-out %/.pp,-MD -MF $(MDDEPDIR)/$(@F).pp)'
dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
if test "$SOLARIS_SUNPRO_CC"; then if test "$SOLARIS_SUNPRO_CC"; then
_DEPEND_CFLAGS= _DEPEND_CFLAGS=
@ -8320,6 +8321,7 @@ AC_SUBST(MOZ_FEEDS)
AC_SUBST(NS_PRINTING) AC_SUBST(NS_PRINTING)
AC_SUBST(MOZ_WEBGL) AC_SUBST(MOZ_WEBGL)
AC_SUBST(MOZ_HELP_VIEWER) AC_SUBST(MOZ_HELP_VIEWER)
AC_SUBST(TOOLCHAIN_PREFIX)
AC_SUBST(JAVA) AC_SUBST(JAVA)
AC_SUBST(JAVAC) AC_SUBST(JAVAC)
@ -8464,7 +8466,6 @@ AC_SUBST(MOZ_APP_UA_NAME)
AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION") AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION")
AC_SUBST(MOZ_APP_VERSION) AC_SUBST(MOZ_APP_VERSION)
AC_SUBST(MOZ_APP_MAXVERSION) AC_SUBST(MOZ_APP_MAXVERSION)
AC_DEFINE_UNQUOTED(MOZ_UA_FIREFOX_VERSION, "$FIREFOX_VERSION")
AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION) AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
AC_SUBST(FIREFOX_VERSION) AC_SUBST(FIREFOX_VERSION)

View File

@ -6251,6 +6251,12 @@ nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent)
return false; return false;
} }
// If the subdocument lives in another process, the frame is
// tabbable.
if (nsEventStateManager::IsRemoteTarget(aContent)) {
return true;
}
// XXXbz should this use OwnerDoc() for GetSubDocumentFor? // XXXbz should this use OwnerDoc() for GetSubDocumentFor?
// sXBL/XBL2 issue! // sXBL/XBL2 issue!
nsIDocument* subDoc = doc->GetSubDocumentFor(aContent); nsIDocument* subDoc = doc->GetSubDocumentFor(aContent);

View File

@ -201,13 +201,14 @@ GK_ATOM(commandupdater, "commandupdater")
GK_ATOM(comment, "comment") GK_ATOM(comment, "comment")
GK_ATOM(compact, "compact") GK_ATOM(compact, "compact")
GK_ATOM(concat, "concat") GK_ATOM(concat, "concat")
GK_ATOM(contenteditable, "contenteditable")
GK_ATOM(conditions, "conditions") GK_ATOM(conditions, "conditions")
GK_ATOM(constructor, "constructor") GK_ATOM(constructor, "constructor")
GK_ATOM(consumeoutsideclicks, "consumeoutsideclicks")
GK_ATOM(container, "container") GK_ATOM(container, "container")
GK_ATOM(containment, "containment") GK_ATOM(containment, "containment")
GK_ATOM(contains, "contains") GK_ATOM(contains, "contains")
GK_ATOM(content, "content") GK_ATOM(content, "content")
GK_ATOM(contenteditable, "contenteditable")
GK_ATOM(headerContentDisposition, "content-disposition") GK_ATOM(headerContentDisposition, "content-disposition")
GK_ATOM(headerContentLanguage, "content-language") GK_ATOM(headerContentLanguage, "content-language")
GK_ATOM(contentLocation, "content-location") GK_ATOM(contentLocation, "content-location")

View File

@ -494,7 +494,6 @@
return root[select](q, resolver); return root[select](q, resolver);
} catch(e){ } catch(e){
if ( e.message.indexOf("ERR") > -1 || if ( e.message.indexOf("ERR") > -1 ||
(e.name == "NamespaceError" && e.code == DOMException.NAMESPACE_ERR) ||
(e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR) ) (e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR) )
throw e; throw e;
} }
@ -549,7 +548,7 @@
results = query(q, resolver); results = query(q, resolver);
} catch(e) { } catch(e) {
pass = (e.message === "bad ERROR" || pass = (e.message === "bad ERROR" ||
(e.name == "NamespaceError" && e.code == DOMException.NAMESPACE_ERR)); (e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR));
} }
assert( pass, type + ": " + name + " Bad Resolver #" + (i+1) + " (" + nq + ")" + assert( pass, type + ": " + name + " Bad Resolver #" + (i+1) + " (" + nq + ")" +

View File

@ -302,6 +302,7 @@ NS_INTERFACE_MAP_BEGIN(nsTextMetrics)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
struct nsCanvasBidiProcessor; struct nsCanvasBidiProcessor;
class CanvasRenderingContext2DUserData;
/** /**
** nsCanvasRenderingContext2D ** nsCanvasRenderingContext2D
@ -381,6 +382,7 @@ public:
nsRefPtr<gfxPath> mPath; nsRefPtr<gfxPath> mPath;
}; };
friend class PathAutoSaveRestore; friend class PathAutoSaveRestore;
friend class CanvasRenderingContext2DUserData;
protected: protected:
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY, nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
@ -449,6 +451,7 @@ protected:
// If mCanvasElement is not provided, then a docshell is // If mCanvasElement is not provided, then a docshell is
nsCOMPtr<nsIDocShell> mDocShell; nsCOMPtr<nsIDocShell> mDocShell;
nsTArray<CanvasRenderingContext2DUserData*> mUserDatas;
// our drawing surfaces, contexts, and layers // our drawing surfaces, contexts, and layers
nsRefPtr<gfxContext> mThebes; nsRefPtr<gfxContext> mThebes;
@ -755,6 +758,40 @@ protected:
friend struct nsCanvasBidiProcessor; friend struct nsCanvasBidiProcessor;
}; };
class CanvasRenderingContext2DUserData : public LayerUserData {
public:
CanvasRenderingContext2DUserData(nsCanvasRenderingContext2D *aContext)
: mContext(aContext)
{
aContext->mUserDatas.AppendElement(this);
}
~CanvasRenderingContext2DUserData()
{
if (mContext) {
mContext->mUserDatas.RemoveElement(this);
}
}
static void DidTransactionCallback(void* aData)
{
CanvasRenderingContext2DUserData* self =
static_cast<CanvasRenderingContext2DUserData*>(aData);
if (self->mContext) {
self->mContext->MarkContextClean();
}
}
bool IsForContext(nsCanvasRenderingContext2D *aContext)
{
return mContext == aContext;
}
void Forget()
{
mContext = nsnull;
}
private:
nsCanvasRenderingContext2D *mContext;
};
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCanvasRenderingContext2D) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCanvasRenderingContext2D)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCanvasRenderingContext2D) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCanvasRenderingContext2D)
@ -810,6 +847,10 @@ nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
nsCanvasRenderingContext2D::~nsCanvasRenderingContext2D() nsCanvasRenderingContext2D::~nsCanvasRenderingContext2D()
{ {
Reset(); Reset();
// Drop references from all CanvasRenderingContext2DUserDatas to this context
for (PRUint32 i = 0; i < mUserDatas.Length(); ++i) {
mUserDatas[i]->Forget();
}
sNumLivingContexts--; sNumLivingContexts--;
if (!sNumLivingContexts) { if (!sNumLivingContexts) {
delete[] sUnpremultiplyTable; delete[] sUnpremultiplyTable;
@ -4154,19 +4195,6 @@ nsCanvasRenderingContext2D::SetMozImageSmoothingEnabled(bool val)
static PRUint8 g2DContextLayerUserData; static PRUint8 g2DContextLayerUserData;
class CanvasRenderingContext2DUserData : public LayerUserData {
public:
CanvasRenderingContext2DUserData(nsHTMLCanvasElement *aContent)
: mContent(aContent) {}
static void DidTransactionCallback(void* aData)
{
static_cast<CanvasRenderingContext2DUserData*>(aData)->mContent->MarkContextClean();
}
private:
nsRefPtr<nsHTMLCanvasElement> mContent;
};
already_AddRefed<CanvasLayer> already_AddRefed<CanvasLayer>
nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder, nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
CanvasLayer *aOldLayer, CanvasLayer *aOldLayer,
@ -4175,10 +4203,14 @@ nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
if (!EnsureSurface()) if (!EnsureSurface())
return nsnull; return nsnull;
if (!mResetLayer && aOldLayer && if (!mResetLayer && aOldLayer) {
aOldLayer->HasUserData(&g2DContextLayerUserData)) { CanvasRenderingContext2DUserData* userData =
NS_ADDREF(aOldLayer); static_cast<CanvasRenderingContext2DUserData*>(
return aOldLayer; aOldLayer->GetUserData(&g2DContextLayerUserData));
if (userData && userData->IsForContext(this)) {
NS_ADDREF(aOldLayer);
return aOldLayer;
}
} }
nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer(); nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
@ -4200,7 +4232,7 @@ nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
// releasing the reference to the element. // releasing the reference to the element.
// The userData will receive DidTransactionCallbacks, which flush the // The userData will receive DidTransactionCallbacks, which flush the
// the invalidation state to indicate that the canvas is up to date. // the invalidation state to indicate that the canvas is up to date.
userData = new CanvasRenderingContext2DUserData(mCanvasElement); userData = new CanvasRenderingContext2DUserData(this);
canvasLayer->SetDidTransactionCallback( canvasLayer->SetDidTransactionCallback(
CanvasRenderingContext2DUserData::DidTransactionCallback, userData); CanvasRenderingContext2DUserData::DidTransactionCallback, userData);
} }

View File

@ -357,6 +357,7 @@ NS_INTERFACE_MAP_BEGIN(nsTextMetricsAzure)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
struct nsCanvasBidiProcessorAzure; struct nsCanvasBidiProcessorAzure;
class CanvasRenderingContext2DUserDataAzure;
// Cap sigma to avoid overly large temp surfaces. // Cap sigma to avoid overly large temp surfaces.
static const Float SIGMA_MAX = 100; static const Float SIGMA_MAX = 100;
@ -423,6 +424,8 @@ public:
nsresult LineTo(const Point& aPoint); nsresult LineTo(const Point& aPoint);
nsresult BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3); nsresult BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3);
friend class CanvasRenderingContext2DUserDataAzure;
protected: protected:
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY, nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
uint32_t aWidth, uint32_t aHeight, uint32_t aWidth, uint32_t aHeight,
@ -504,6 +507,8 @@ protected:
// This is needed for drawing in drawAsyncXULElement // This is needed for drawing in drawAsyncXULElement
bool mIPC; bool mIPC;
nsTArray<CanvasRenderingContext2DUserDataAzure*> mUserDatas;
// If mCanvasElement is not provided, then a docshell is // If mCanvasElement is not provided, then a docshell is
nsCOMPtr<nsIDocShell> mDocShell; nsCOMPtr<nsIDocShell> mDocShell;
@ -935,6 +940,40 @@ protected:
friend struct nsCanvasBidiProcessorAzure; friend struct nsCanvasBidiProcessorAzure;
}; };
class CanvasRenderingContext2DUserDataAzure : public LayerUserData {
public:
CanvasRenderingContext2DUserDataAzure(nsCanvasRenderingContext2DAzure *aContext)
: mContext(aContext)
{
aContext->mUserDatas.AppendElement(this);
}
~CanvasRenderingContext2DUserDataAzure()
{
if (mContext) {
mContext->mUserDatas.RemoveElement(this);
}
}
static void DidTransactionCallback(void* aData)
{
CanvasRenderingContext2DUserDataAzure* self =
static_cast<CanvasRenderingContext2DUserDataAzure*>(aData);
if (self->mContext) {
self->mContext->MarkContextClean();
}
}
bool IsForContext(nsCanvasRenderingContext2DAzure *aContext)
{
return mContext == aContext;
}
void Forget()
{
mContext = nsnull;
}
private:
nsCanvasRenderingContext2DAzure *mContext;
};
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCanvasRenderingContext2DAzure) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCanvasRenderingContext2DAzure)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCanvasRenderingContext2DAzure) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCanvasRenderingContext2DAzure)
@ -1029,6 +1068,10 @@ nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
nsCanvasRenderingContext2DAzure::~nsCanvasRenderingContext2DAzure() nsCanvasRenderingContext2DAzure::~nsCanvasRenderingContext2DAzure()
{ {
Reset(); Reset();
// Drop references from all CanvasRenderingContext2DUserDataAzure to this context
for (PRUint32 i = 0; i < mUserDatas.Length(); ++i) {
mUserDatas[i]->Forget();
}
sNumLivingContexts--; sNumLivingContexts--;
if (!sNumLivingContexts) { if (!sNumLivingContexts) {
delete[] sUnpremultiplyTable; delete[] sUnpremultiplyTable;
@ -4399,19 +4442,6 @@ nsCanvasRenderingContext2DAzure::SetMozImageSmoothingEnabled(bool val)
static PRUint8 g2DContextLayerUserData; static PRUint8 g2DContextLayerUserData;
class CanvasRenderingContext2DUserData : public LayerUserData {
public:
CanvasRenderingContext2DUserData(nsHTMLCanvasElement *aContent)
: mContent(aContent) {}
static void DidTransactionCallback(void* aData)
{
static_cast<CanvasRenderingContext2DUserData*>(aData)->mContent->MarkContextClean();
}
private:
nsRefPtr<nsHTMLCanvasElement> mContent;
};
already_AddRefed<CanvasLayer> already_AddRefed<CanvasLayer>
nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder, nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
CanvasLayer *aOldLayer, CanvasLayer *aOldLayer,
@ -4425,18 +4455,22 @@ nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
mTarget->Flush(); mTarget->Flush();
} }
if (!mResetLayer && aOldLayer && if (!mResetLayer && aOldLayer) {
aOldLayer->HasUserData(&g2DContextLayerUserData)) { CanvasRenderingContext2DUserDataAzure* userData =
static_cast<CanvasRenderingContext2DUserDataAzure*>(
aOldLayer->GetUserData(&g2DContextLayerUserData));
if (userData && userData->IsForContext(this)) {
NS_ADDREF(aOldLayer); NS_ADDREF(aOldLayer);
return aOldLayer; return aOldLayer;
}
} }
nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer(); nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
if (!canvasLayer) { if (!canvasLayer) {
NS_WARNING("CreateCanvasLayer returned null!"); NS_WARNING("CreateCanvasLayer returned null!");
return nsnull; return nsnull;
} }
CanvasRenderingContext2DUserData *userData = nsnull; CanvasRenderingContext2DUserDataAzure *userData = nsnull;
if (aBuilder->IsPaintingToWindow()) { if (aBuilder->IsPaintingToWindow()) {
// Make the layer tell us whenever a transaction finishes (including // Make the layer tell us whenever a transaction finishes (including
// the current transaction), so we can clear our invalidation state and // the current transaction), so we can clear our invalidation state and
@ -4450,9 +4484,9 @@ nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
// releasing the reference to the element. // releasing the reference to the element.
// The userData will receive DidTransactionCallbacks, which flush the // The userData will receive DidTransactionCallbacks, which flush the
// the invalidation state to indicate that the canvas is up to date. // the invalidation state to indicate that the canvas is up to date.
userData = new CanvasRenderingContext2DUserData(mCanvasElement); userData = new CanvasRenderingContext2DUserDataAzure(this);
canvasLayer->SetDidTransactionCallback( canvasLayer->SetDidTransactionCallback(
CanvasRenderingContext2DUserData::DidTransactionCallback, userData); CanvasRenderingContext2DUserDataAzure::DidTransactionCallback, userData);
} }
canvasLayer->SetUserData(&g2DContextLayerUserData, userData); canvasLayer->SetUserData(&g2DContextLayerUserData, userData);

View File

@ -96,6 +96,7 @@ nsDOMKeyboardEvent::GetCharCode(PRUint32* aCharCode)
*aCharCode = ((nsKeyEvent*)mEvent)->charCode; *aCharCode = ((nsKeyEvent*)mEvent)->charCode;
break; break;
default: default:
*aCharCode = 0;
break; break;
} }
return NS_OK; return NS_OK;

View File

@ -1678,10 +1678,10 @@ nsEventStateManager::IsRemoteTarget(nsIContent* target) {
// <frame/iframe mozbrowser> // <frame/iframe mozbrowser>
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(target); nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(target);
if (browserFrame) { if (browserFrame) {
bool isRemote = false; bool isBrowser = false;
browserFrame->GetReallyIsBrowser(&isRemote); browserFrame->GetReallyIsBrowser(&isBrowser);
if (isRemote) { if (isBrowser) {
return true; return !!TabParent::GetFrom(target);
} }
} }

View File

@ -549,6 +549,7 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
{ {
if (aStream->mFinished) if (aStream->mFinished)
return; return;
printf("MediaStreamGraphImpl::FinishStream\n");
LOG(PR_LOG_DEBUG, ("MediaStream %p will finish", aStream)); LOG(PR_LOG_DEBUG, ("MediaStream %p will finish", aStream));
aStream->mFinished = true; aStream->mFinished = true;
// Force at least one more iteration of the control loop, since we rely // Force at least one more iteration of the control loop, since we rely

View File

@ -929,15 +929,22 @@ nsFocusManager::WindowHidden(nsIDOMWindow* aWindow)
nsCOMPtr<nsIContent> oldFocusedContent = mFocusedContent.forget(); nsCOMPtr<nsIContent> oldFocusedContent = mFocusedContent.forget();
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
nsCOMPtr<nsIPresShell> presShell;
focusedDocShell->GetPresShell(getter_AddRefs(presShell));
if (oldFocusedContent && oldFocusedContent->IsInDoc()) { if (oldFocusedContent && oldFocusedContent->IsInDoc()) {
NotifyFocusStateChange(oldFocusedContent, NotifyFocusStateChange(oldFocusedContent,
mFocusedWindow->ShouldShowFocusRing(), mFocusedWindow->ShouldShowFocusRing(),
false); false);
} window->UpdateCommands(NS_LITERAL_STRING("focus"));
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell(); if (presShell) {
nsCOMPtr<nsIPresShell> presShell; SendFocusOrBlurEvent(NS_BLUR_CONTENT, presShell,
focusedDocShell->GetPresShell(getter_AddRefs(presShell)); oldFocusedContent->GetCurrentDoc(),
oldFocusedContent, 1, false);
}
}
nsIMEStateManager::OnTextStateBlur(nsnull, nsnull); nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
if (presShell) { if (presShell) {
@ -1563,8 +1570,7 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
} }
// if the object being blurred is a remote browser, deactivate remote content // if the object being blurred is a remote browser, deactivate remote content
TabParent* remote = GetRemoteForContent(content); if (TabParent* remote = TabParent::GetFrom(content)) {
if (remote) {
remote->Deactivate(); remote->Deactivate();
#ifdef DEBUG_FOCUS #ifdef DEBUG_FOCUS
printf("*Remote browser deactivated\n"); printf("*Remote browser deactivated\n");
@ -1775,8 +1781,7 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
objectFrameWidget->SetFocus(false); objectFrameWidget->SetFocus(false);
// if the object being focused is a remote browser, activate remote content // if the object being focused is a remote browser, activate remote content
TabParent* remote = GetRemoteForContent(aContent); if (TabParent* remote = TabParent::GetFrom(aContent)) {
if (remote) {
remote->Activate(); remote->Activate();
#ifdef DEBUG_FOCUS #ifdef DEBUG_FOCUS
printf("*Remote browser activated\n"); printf("*Remote browser activated\n");
@ -3006,29 +3011,6 @@ nsFocusManager::GetRootForFocus(nsPIDOMWindow* aWindow,
return rootElement; return rootElement;
} }
TabParent*
nsFocusManager::GetRemoteForContent(nsIContent* aContent) {
if (!aContent ||
(aContent->Tag() != nsGkAtoms::browser &&
aContent->Tag() != nsGkAtoms::iframe) ||
!aContent->IsXUL() ||
!aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
nsGkAtoms::_true, eIgnoreCase))
return nsnull;
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
if (!loaderOwner)
return nsnull;
nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
if (!frameLoader)
return nsnull;
PBrowserParent* remoteBrowser = frameLoader->GetRemoteBrowser();
TabParent* remote = static_cast<TabParent*>(remoteBrowser);
return remote;
}
void void
nsFocusManager::GetLastDocShell(nsIDocShellTreeItem* aItem, nsFocusManager::GetLastDocShell(nsIDocShellTreeItem* aItem,
nsIDocShellTreeItem** aResult) nsIDocShellTreeItem** aResult)

View File

@ -21,12 +21,6 @@
class nsIDocShellTreeItem; class nsIDocShellTreeItem;
class nsPIDOMWindow; class nsPIDOMWindow;
namespace mozilla {
namespace dom {
class TabParent;
}
}
struct nsDelayedBlurOrFocusEvent; struct nsDelayedBlurOrFocusEvent;
/** /**
@ -414,12 +408,6 @@ protected:
bool aIsForDocNavigation, bool aIsForDocNavigation,
bool aCheckVisibility); bool aCheckVisibility);
/**
* Get the TabParent associated with aContent if it is a remote browser,
* or null in all other cases.
*/
mozilla::dom::TabParent* GetRemoteForContent(nsIContent* aContent);
/** /**
* Get the last docshell child of aItem and return it in aResult. * Get the last docshell child of aItem and return it in aResult.
*/ */

View File

@ -176,6 +176,7 @@ DOMInterfaces = {
'WebGLRenderingContext': { 'WebGLRenderingContext': {
'nativeType': 'mozilla::WebGLContext', 'nativeType': 'mozilla::WebGLContext',
'headerFile': 'WebGLContext.h',
'prefable': True, 'prefable': True,
'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension', 'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
'getAttachedShaders' ], 'getAttachedShaders' ],
@ -356,8 +357,7 @@ def addExternalHTMLElement(element):
addExternalHTMLElement('HTMLCanvasElement') addExternalHTMLElement('HTMLCanvasElement')
addExternalHTMLElement('HTMLImageElement') addExternalHTMLElement('HTMLImageElement')
addExternalHTMLElement('HTMLVideoElement') addExternalHTMLElement('HTMLVideoElement')
addExternalIface('ImageData', nativeType='mozilla::dom::ImageData', addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
headerFile='mozilla/dom/ImageData.h')
addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo', addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
headerFile='WebGLContext.h') headerFile='WebGLContext.h')
addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer', addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',

View File

@ -1858,11 +1858,11 @@ for (uint32_t i = 0; i < length; ++i) {
elif descriptor.workers: elif descriptor.workers:
templateBody += "${declName} = &${val}.toObject();" templateBody += "${declName} = &${val}.toObject();"
else: else:
# External interface. We always have a holder for these, # Either external, or new-binding non-castable. We always have a
# because we don't actually know whether we have to addref # holder for these, because we don't actually know whether we have
# when unwrapping or not. So we just pass an # to addref when unwrapping or not. So we just pass an
# getter_AddRefs(nsRefPtr) to XPConnect and if we'll need # getter_AddRefs(nsRefPtr) to XPConnect and if we'll need a release
# a release it'll put a non-null pointer in there. # it'll put a non-null pointer in there.
if forceOwningType: if forceOwningType:
# Don't return a holderType in this case; our declName # Don't return a holderType in this case; our declName
# will just own stuff. # will just own stuff.
@ -2779,29 +2779,6 @@ class CGMethodCall(CGThing):
requiredArgs -= 1 requiredArgs -= 1
return requiredArgs return requiredArgs
def maxSigLength(signatures):
return max([len(s[1]) for s in signatures])
def signaturesForArgCount(i, signatures):
return filter(
lambda s: len(s[1]) == i or (len(s[1]) > i and
s[1][i].optional),
signatures)
def findDistinguishingIndex(argCount, signatures):
def isValidDistinguishingIndex(idx, signatures):
for firstSigIndex in range(0, len(signatures)):
for secondSigIndex in range(0, firstSigIndex):
firstType = signatures[firstSigIndex][1][idx].type
secondType = signatures[secondSigIndex][1][idx].type
if not firstType.isDistinguishableFrom(secondType):
return False
return True
for idx in range(0, argCount):
if isValidDistinguishingIndex(idx, signatures):
return idx
return -1
def getPerSignatureCall(signature, argConversionStartsAt=0): def getPerSignatureCall(signature, argConversionStartsAt=0):
return CGPerSignatureCall(signature[0], argsPre, signature[1], return CGPerSignatureCall(signature[0], argsPre, signature[1],
nativeMethodName, static, descriptor, nativeMethodName, static, descriptor,
@ -2831,13 +2808,12 @@ class CGMethodCall(CGThing):
return return
# Need to find the right overload # Need to find the right overload
maxSigArgs = maxSigLength(signatures) maxArgCount = method.maxArgCount
allowedArgCounts = [ i for i in range(0, maxSigArgs+1) allowedArgCounts = method.allowedArgCounts
if len(signaturesForArgCount(i, signatures)) != 0 ]
argCountCases = [] argCountCases = []
for argCount in allowedArgCounts: for argCount in allowedArgCounts:
possibleSignatures = signaturesForArgCount(argCount, signatures) possibleSignatures = method.signaturesForArgCount(argCount)
if len(possibleSignatures) == 1: if len(possibleSignatures) == 1:
# easy case! # easy case!
signature = possibleSignatures[0] signature = possibleSignatures[0]
@ -2850,7 +2826,7 @@ class CGMethodCall(CGThing):
if (len(signature[1]) > argCount and if (len(signature[1]) > argCount and
signature[1][argCount].optional and signature[1][argCount].optional and
(argCount+1) in allowedArgCounts and (argCount+1) in allowedArgCounts and
len(signaturesForArgCount(argCount+1, signatures)) == 1): len(method.signaturesForArgCount(argCount+1)) == 1):
argCountCases.append( argCountCases.append(
CGCase(str(argCount), None, True)) CGCase(str(argCount), None, True))
else: else:
@ -2858,28 +2834,7 @@ class CGMethodCall(CGThing):
CGCase(str(argCount), getPerSignatureCall(signature))) CGCase(str(argCount), getPerSignatureCall(signature)))
continue continue
distinguishingIndex = findDistinguishingIndex(argCount, distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
possibleSignatures)
if distinguishingIndex == -1:
raise TypeError(("Signatures with %s arguments for " +
descriptor.interface.identifier.name + "." +
method.identifier.name +
" are not distinguishable") % argCount)
for idx in range(0, distinguishingIndex):
firstSigType = possibleSignatures[0][1][idx].type
for sigIdx in range(1, len(possibleSignatures)):
if possibleSignatures[sigIdx][1][idx].type != firstSigType:
raise TypeError(("Signatures with %d arguments for " +
descriptor.interface.identifier.name +
"." + method.identifier.name +
" have different types at index %d" +
" which is before distinguishing" +
" index %d. Types are %s and %s") %
(argCount, idx,
distinguishingIndex,
str(possibleSignatures[sigIdx][1][idx].type),
str(firstSigType)))
# Convert all our arguments up to the distinguishing index. # Convert all our arguments up to the distinguishing index.
# Doesn't matter which of the possible signatures we use, since # Doesn't matter which of the possible signatures we use, since
@ -3019,7 +2974,7 @@ class CGMethodCall(CGThing):
overloadCGThings = [] overloadCGThings = []
overloadCGThings.append( overloadCGThings.append(
CGGeneric("unsigned argcount = NS_MIN(argc, %du);" % CGGeneric("unsigned argcount = NS_MIN(argc, %du);" %
maxSigArgs)) maxArgCount))
overloadCGThings.append( overloadCGThings.append(
CGSwitch("argcount", CGSwitch("argcount",
argCountCases, argCountCases,

View File

@ -131,7 +131,7 @@ class Descriptor(DescriptorProvider):
self.hasInstanceInterface = desc.get('hasInstanceInterface', None) self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
headerDefault = self.nativeType headerDefault = self.nativeType
headerDefault = headerDefault.split("::")[-1] + ".h" headerDefault = headerDefault.replace("::", "/") + ".h"
self.headerFile = desc.get('headerFile', headerDefault) self.headerFile = desc.get('headerFile', headerDefault)
castableDefault = not self.interface.isCallback() castableDefault = not self.interface.isCallback()

View File

@ -51,19 +51,21 @@ def enum(*names):
return Foo() return Foo()
class WebIDLError(Exception): class WebIDLError(Exception):
def __init__(self, message, location, warning=False, extraLocation=""): def __init__(self, message, location, warning=False, extraLocations=[]):
self.message = message self.message = message
self.location = location self.location = location
self.warning = warning self.warning = warning
self.extraLocation = extraLocation self.extraLocations = [str(loc) for loc in extraLocations]
def __str__(self): def __str__(self):
return "%s: %s%s%s%s%s" % (self.warning and 'warning' or 'error', extraLocationsStr = (
self.message, "" if len(self.extraLocations) == 0 else
", " if self.location else "", "\n" + "\n".join(self.extraLocations))
self.location, return "%s: %s%s%s%s" % (self.warning and 'warning' or 'error',
"\n" if self.extraLocation else "", self.message,
self.extraLocation) ", " if self.location else "",
self.location,
extraLocationsStr)
class Location(object): class Location(object):
def __init__(self, lexer, lineno, lexpos, filename): def __init__(self, lexer, lineno, lexpos, filename):
@ -348,12 +350,18 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
def finish(self, scope): def finish(self, scope):
pass pass
def validate(self):
pass
def isExternal(self): def isExternal(self):
return True return True
def isInterface(self): def isInterface(self):
return True return True
def isConsequential(self):
return False
def addExtendedAttributes(self, attrs): def addExtendedAttributes(self, attrs):
assert len(attrs) == 0 assert len(attrs) == 0
@ -371,6 +379,11 @@ class IDLInterface(IDLObjectWithScope):
self._finished = False self._finished = False
self.members = list(members) # clone the list self.members = list(members) # clone the list
self.implementedInterfaces = set() self.implementedInterfaces = set()
self._consequential = False
# self.interfacesBasedOnSelf is the set of interfaces that inherit from
# self or have self as a consequential interface, including self itself.
# Used for distinguishability checking.
self.interfacesBasedOnSelf = set([self])
IDLObjectWithScope.__init__(self, location, parentScope, name) IDLObjectWithScope.__init__(self, location, parentScope, name)
@ -422,9 +435,23 @@ class IDLInterface(IDLObjectWithScope):
# Callbacks must not inherit from non-callbacks or inherit from # Callbacks must not inherit from non-callbacks or inherit from
# anything that has consequential interfaces. # anything that has consequential interfaces.
# XXXbz Can non-callbacks inherit from callbacks? Spec issue pending.
# XXXbz Can callbacks have consequential interfaces? Spec issue pending
if self.isCallback(): if self.isCallback():
assert(self.parent.isCallback()) if not self.parent.isCallback():
assert(len(self.parent.getConsequentialInterfaces()) == 0) raise WebIDLError("Callback interface %s inheriting from "
"non-callback interface %s" %
(self.identifier.name,
self.parent.identifier.name),
self.location,
extraLocations=[self.parent.location])
elif self.parent.isCallback():
raise WebIDLError("Non-callback interface %s inheriting from "
"callback interface %s" %
(self.identifier.name,
self.parent.identifier.name),
self.location,
extraLocations=[self.parent.location])
for iface in self.implementedInterfaces: for iface in self.implementedInterfaces:
iface.finish(scope) iface.finish(scope)
@ -434,7 +461,14 @@ class IDLInterface(IDLObjectWithScope):
raise WebIDLError("Interface %s has itself as ancestor or " raise WebIDLError("Interface %s has itself as ancestor or "
"implemented interface" % self.identifier.name, "implemented interface" % self.identifier.name,
self.location, self.location,
extraLocation=cycleInGraph.location) extraLocations=[cycleInGraph.location])
if self.isCallback():
# "implements" should have made sure we have no
# consequential interfaces.
assert len(self.getConsequentialInterfaces()) == 0
# And that we're not consequential.
assert not self.isConsequential()
# 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.
@ -462,6 +496,8 @@ class IDLInterface(IDLObjectWithScope):
for iface in sorted(self.getConsequentialInterfaces(), for iface in sorted(self.getConsequentialInterfaces(),
cmp=cmp, cmp=cmp,
key=lambda x: x.identifier.name): key=lambda x: x.identifier.name):
# Flag the interface as being someone's consequential interface
iface.setIsConsequentialInterfaceOf(self)
additionalMembers = iface.originalMembers; additionalMembers = iface.originalMembers;
for additionalMember in additionalMembers: for additionalMember in additionalMembers:
for member in self.members: for member in self.members:
@ -470,9 +506,14 @@ class IDLInterface(IDLObjectWithScope):
"Multiple definitions of %s on %s coming from 'implements' statements" % "Multiple definitions of %s on %s coming from 'implements' statements" %
(member.identifier.name, self), (member.identifier.name, self),
additionalMember.location, additionalMember.location,
extraLocation=member.location) extraLocations=[member.location])
self.members.extend(additionalMembers) self.members.extend(additionalMembers)
for ancestor in self.getInheritedInterfaces():
ancestor.interfacesBasedOnSelf.add(self)
for ancestorConsequential in ancestor.getConsequentialInterfaces():
ancestorConsequential.interfacesBasedOnSelf.add(self)
# Ensure that there's at most one of each {named,indexed} # Ensure that there's at most one of each {named,indexed}
# {getter,setter,creator,deleter}. # {getter,setter,creator,deleter}.
specialMembersSeen = set() specialMembersSeen = set()
@ -504,12 +545,23 @@ class IDLInterface(IDLObjectWithScope):
specialMembersSeen.add(memberType) specialMembersSeen.add(memberType)
def validate(self):
for member in self.members:
member.validate()
def isInterface(self): def isInterface(self):
return True return True
def isExternal(self): def isExternal(self):
return False return False
def setIsConsequentialInterfaceOf(self, other):
self._consequential = True
self.interfacesBasedOnSelf.add(other)
def isConsequential(self):
return self._consequential
def setCallback(self, value): def setCallback(self, value):
self._callback = value self._callback = value
@ -656,7 +708,7 @@ class IDLDictionary(IDLObjectWithScope):
raise WebIDLError("Dictionary %s has parent that is not a dictionary" % raise WebIDLError("Dictionary %s has parent that is not a dictionary" %
self.identifier.name, self.identifier.name,
oldParent.location, oldParent.location,
extraLocation=self.parent.location) extraLocations=[self.parent.location])
# Make sure the parent resolves all its members before we start # Make sure the parent resolves all its members before we start
# looking at them. # looking at them.
@ -690,7 +742,10 @@ class IDLDictionary(IDLObjectWithScope):
raise WebIDLError("Dictionary %s has two members with name %s" % raise WebIDLError("Dictionary %s has two members with name %s" %
(self.identifier.name, member.identifier.name), (self.identifier.name, member.identifier.name),
member.location, member.location,
extraLocation=inheritedMember.location) extraLocations=[inheritedMember.location])
def validate(self):
pass
def addExtendedAttributes(self, attrs): def addExtendedAttributes(self, attrs):
assert len(attrs) == 0 assert len(attrs) == 0
@ -713,6 +768,9 @@ class IDLEnum(IDLObjectWithIdentifier):
def finish(self, scope): def finish(self, scope):
pass pass
def validate(self):
pass
def isEnum(self): def isEnum(self):
return True return True
@ -1353,23 +1411,34 @@ class IDLWrapperType(IDLType):
other.isCallback() or other.isDictionary() or other.isCallback() or other.isDictionary() or
other.isSequence() or other.isArray() or other.isSequence() or other.isArray() or
other.isDate()) other.isDate())
if other.isPrimitive() or other.isString() or other.isEnum(): if other.isPrimitive() or other.isString() or other.isEnum() or other.isDate():
return True return True
if self.isDictionary(): if self.isDictionary():
return (other.isNonCallbackInterface() or other.isSequence() or return (other.isNonCallbackInterface() or other.isSequence() or
other.isArray() or other.isDate()) other.isArray())
assert self.isInterface() 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 if other.isSpiderMonkeyInterface():
# Just let |other| handle things
return other.isDistinguishableFrom(self)
assert self.isGeckoInterface() and other.isGeckoInterface()
if self.inner.isExternal() or other.unroll().inner.isExternal():
return self != other
return (len(self.inner.interfacesBasedOnSelf &
other.unroll().inner.interfacesBasedOnSelf) == 0 and
(self.isNonCallbackInterface() or (self.isNonCallbackInterface() or
other.isNonCallbackInterface())) other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or if (other.isDictionary() or other.isCallback() or
other.isSequence() or other.isArray()): other.isSequence() or other.isArray()):
return self.isNonCallbackInterface() return self.isNonCallbackInterface()
# Not much else |other| can be
assert other.isObject()
return False
class IDLBuiltinType(IDLType): class IDLBuiltinType(IDLType):
Types = enum( Types = enum(
@ -1736,6 +1805,9 @@ class IDLConst(IDLInterfaceMember):
def finish(self, scope): def finish(self, scope):
assert self.type.isComplete() assert self.type.isComplete()
def validate(self):
pass
class IDLAttribute(IDLInterfaceMember): class IDLAttribute(IDLInterfaceMember):
def __init__(self, location, identifier, type, readonly, inherit): def __init__(self, location, identifier, type, readonly, inherit):
IDLInterfaceMember.__init__(self, location, identifier, IDLInterfaceMember.__init__(self, location, identifier,
@ -1858,6 +1930,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
assert not isinstance(type.name, IDLUnresolvedIdentifier) assert not isinstance(type.name, IDLUnresolvedIdentifier)
argument.type = type argument.type = type
def validate(self):
pass
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.isNonCallbackInterface() or other.isDate()) other.isNonCallbackInterface() or other.isDate())
@ -1899,6 +1974,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert isinstance(returnType, IDLType) assert isinstance(returnType, IDLType)
self._returnType = [returnType] self._returnType = [returnType]
# We store a list of all the overload locations, matching our
# signature list.
self._location = [location]
assert isinstance(static, bool) assert isinstance(static, bool)
self._static = static self._static = static
@ -1944,20 +2022,32 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert self._returnType[0] == BuiltinTypes[IDLBuiltinType.Types.domstring] assert self._returnType[0] == BuiltinTypes[IDLBuiltinType.Types.domstring]
inOptionalArguments = False inOptionalArguments = False
sawVariadicArgument = False variadicArgument = None
sawOptionalWithNoDefault = False
assert len(self._arguments) == 1 assert len(self._arguments) == 1
arguments = self._arguments[0] arguments = self._arguments[0]
for argument in arguments: for argument in arguments:
# Only the last argument can be variadic # Only the last argument can be variadic
assert not sawVariadicArgument if variadicArgument:
raise WebIDLError("Variadic argument is not last argument",
variadicArgument.location)
# Once we see an optional argument, there can't be any non-optional # Once we see an optional argument, there can't be any non-optional
# arguments. # arguments.
if inOptionalArguments: if inOptionalArguments and not argument.optional:
assert argument.optional raise WebIDLError("Non-optional argument after optional arguments",
argument.location)
# Once we see an argument with no default value, there can
# be no more default values.
if sawOptionalWithNoDefault and argument.defaultValue:
raise WebIDLError("Argument with default value after optional "
"arguments with no default values",
argument.location)
inOptionalArguments = argument.optional inOptionalArguments = argument.optional
sawVariadicArgument = argument.variadic if argument.variadic:
variadicArgument = argument
sawOptionalWithNoDefault = argument.optional and not argument.defaultValue
def isStatic(self): def isStatic(self):
return self._static return self._static
@ -2006,9 +2096,11 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert len(method._returnType) == 1 assert len(method._returnType) == 1
assert len(method._arguments) == 1 assert len(method._arguments) == 1
assert len(method._location) == 1
self._returnType.extend(method._returnType) self._returnType.extend(method._returnType)
self._arguments.extend(method._arguments) self._arguments.extend(method._arguments)
self._location.extend(method._location)
self._hasOverloads = True self._hasOverloads = True
@ -2060,6 +2152,64 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert not isinstance(type.name, IDLUnresolvedIdentifier) assert not isinstance(type.name, IDLUnresolvedIdentifier)
argument.type = type argument.type = type
# Now compute various information that will be used by the
# WebIDL overload resolution algorithm.
self.maxArgCount = max(len(s[1]) for s in self.signatures())
self.allowedArgCounts = [ i for i in range(self.maxArgCount+1)
if len(self.signaturesForArgCount(i)) != 0 ]
def validate(self):
# Make sure our overloads are properly distinguishable and don't have
# different argument types before the distinguishing args.
for argCount in self.allowedArgCounts:
possibleSignatures = self.signaturesForArgCount(argCount)
if len(possibleSignatures) == 1:
continue
distinguishingIndex = self.distinguishingIndexForArgCount(argCount)
arglists = [ s[1] for s in possibleSignatures ]
for idx in range(distinguishingIndex):
firstSigType = arglists[0][idx].type
for (otherArgList, location) in zip(arglists[1:],
self._location[1:]):
if otherArgList[idx].type != firstSigType:
raise WebIDLError(
"Signatures for method '%s' with %d arguments have "
"different types of arguments at index %d, which "
"is before distinguishing index %d" %
(self.identifier.name, argCount, idx,
distinguishingIndex),
self.location,
extraLocations=[location])
def signaturesForArgCount(self, argc):
return [(retval, args) for (retval, args) in self.signatures() if
len(args) == argc or (len(args) > argc and args[argc].optional)]
def locationsForArgCount(self, argc):
return [ self._location[i] for (i, args) in enumerate(self._arguments) if
len(args) == argc or
(len(args) > argc and args[argc].optional)]
def distinguishingIndexForArgCount(self, argc):
def isValidDistinguishingIndex(idx, signatures):
for (firstSigIndex, (firstRetval, firstArgs)) in enumerate(signatures[:-1]):
for (secondRetval, secondArgs) in signatures[firstSigIndex+1:]:
firstType = firstArgs[idx].type
secondType = secondArgs[idx].type
if not firstType.isDistinguishableFrom(secondType):
return False
return True
signatures = self.signaturesForArgCount(argc)
for idx in range(argc):
if isValidDistinguishingIndex(idx, signatures):
return idx
# No valid distinguishing index. Time to throw
locations = self.locationsForArgCount(argc)
raise WebIDLError("Signatures with %d arguments for method '%s' are not "
"distinguishable" % (argc, self.identifier.name),
locations[0],
extraLocations=locations[1:])
class IDLImplementsStatement(IDLObject): class IDLImplementsStatement(IDLObject):
def __init__(self, location, implementor, implementee): def __init__(self, location, implementor, implementee):
IDLObject.__init__(self, location) IDLObject.__init__(self, location)
@ -2071,8 +2221,30 @@ class IDLImplementsStatement(IDLObject):
assert(isinstance(self.implementee, IDLIdentifierPlaceholder)) assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
implementor = self.implementor.finish(scope) implementor = self.implementor.finish(scope)
implementee = self.implementee.finish(scope) implementee = self.implementee.finish(scope)
# NOTE: we depend on not setting self.implementor and
# self.implementee here to keep track of the original
# locations.
if not isinstance(implementor, IDLInterface):
raise WebIDLError("Left-hand side of 'implements' is not an "
"interface",
self.implementor.location)
if implementor.isCallback():
raise WebIDLError("Left-hand side of 'implements' is a callback "
"interface",
self.implementor.location)
if not isinstance(implementee, IDLInterface):
raise WebIDLError("Right-hand side of 'implements' is not an "
"interface",
self.implementee.location)
if implementee.isCallback():
raise WebIDLError("Right-hand side of 'implements' is a callback "
"interface",
self.implementee.location)
implementor.addImplementedInterface(implementee) implementor.addImplementedInterface(implementee)
def validate(self):
pass
def addExtendedAttributes(self, attrs): def addExtendedAttributes(self, attrs):
assert len(attrs) == 0 assert len(attrs) == 0
@ -3349,6 +3521,10 @@ class Parser(Tokenizer):
for production in otherStatements: for production in otherStatements:
production.finish(self.globalScope()) production.finish(self.globalScope())
# Do any post-finish validation we need to do
for production in self._productions:
production.validate()
# De-duplicate self._productions, without modifying its order. # De-duplicate self._productions, without modifying its order.
seen = set() seen = set()
result = [] result = []

View File

@ -52,7 +52,6 @@ def WebIDLTest(parser, harness):
harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod") harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod")
harness.check(str(attr.type), t, "Expect an ArrayBuffer type") harness.check(str(attr.type), t, "Expect an ArrayBuffer type")
print type(attr.type)
harness.ok(attr.type.isSpiderMonkeyInterface(), "Should test as a js interface") harness.ok(attr.type.isSpiderMonkeyInterface(), "Should test as a js interface")
(retType, arguments) = method.signatures()[0] (retType, arguments) = method.signatures()[0]

View File

@ -12,3 +12,36 @@ def WebIDLTest(parser, harness):
iface = results[0] iface = results[0]
harness.ok(iface.isCallback(), "Interface should be a callback") harness.ok(iface.isCallback(), "Interface should be a callback")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
callback interface TestCallbackInterface : TestInterface {
attribute boolean bool;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow non-callback parent of callback interface")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface : TestCallbackInterface {
};
callback interface TestCallbackInterface {
attribute boolean bool;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow callback parent of non-callback interface")

View File

@ -1,3 +1,6 @@
def firstArgType(method):
return method.signatures()[0][1][0].type
def WebIDLTest(parser, harness): def WebIDLTest(parser, harness):
parser.parse(""" parser.parse("""
dictionary Dict { dictionary Dict {

View File

@ -17,7 +17,6 @@ interface ?"""
except WebIDL.WebIDLError, e: except WebIDL.WebIDLError, e:
threw = True threw = True
lines = str(e).split('\n') lines = str(e).split('\n')
print lines
harness.check(len(lines), 3, 'Expected number of lines in error message') harness.check(len(lines), 3, 'Expected number of lines in error message')
harness.ok(lines[0].endswith('line 6:10'), 'First line of error should end with "line 6:10", but was "%s".' % lines[0]) harness.ok(lines[0].endswith('line 6:10'), 'First line of error should end with "line 6:10", but was "%s".' % lines[0])

View File

@ -115,7 +115,7 @@ def WebIDLTest(parser, harness):
# Reset the parser so we can actually find things where we expect # Reset the parser so we can actually find things where we expect
# them in the list # them in the list
parser = WebIDL.Parser() parser = parser.reset()
# Diamonds should be allowed # Diamonds should be allowed
threw = False threw = False
@ -141,3 +141,76 @@ def WebIDLTest(parser, harness):
harness.check(len(results[6].members), 1, "S should have one member") harness.check(len(results[6].members), 1, "S should have one member")
harness.check(results[6].members[0].identifier.name, "x", harness.check(results[6].members[0].identifier.name, "x",
"S's member should be 'x'") "S's member should be 'x'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
callback interface TestCallbackInterface {
};
TestInterface implements TestCallbackInterface;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow callback interfaces on the right-hand side "
"of 'implements'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
callback interface TestCallbackInterface {
};
TestCallbackInterface implements TestInterface;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow callback interfaces on the left-hand side of "
"'implements'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
dictionary Dict {
};
Dict implements TestInterface;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow non-interfaces on the left-hand side "
"of 'implements'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
dictionary Dict {
};
TestInterface implements Dict;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow non-interfaces on the right-hand side "
"of 'implements'")

View File

@ -5,9 +5,9 @@ def WebIDLTest(parser, harness):
interface TestOverloads { interface TestOverloads {
void basic(); void basic();
void basic(long arg1); void basic(long arg1);
boolean abitharder(unsigned long foo); boolean abitharder(TestOverloads foo);
boolean abitharder(boolean foo); boolean abitharder(boolean foo);
void abitharder(long? foo); void abitharder(ArrayBuffer? foo);
}; };
""") """)

View File

@ -71,3 +71,7 @@ libs:: $(_TEST_FILES)
check:: check::
PYTHONDONTWRITEBYTECODE=1 $(PYTHON_PATH) $(PLY_INCLUDE) \ PYTHONDONTWRITEBYTECODE=1 $(PYTHON_PATH) $(PLY_INCLUDE) \
$(srcdir)/../parser/runtests.py $(srcdir)/../parser/runtests.py
check-interactive:
PYTHONDONTWRITEBYTECODE=1 $(PYTHON_PATH) $(PLY_INCLUDE) \
$(srcdir)/../parser/runtests.py -q

View File

@ -501,7 +501,7 @@ class ThreadLocalJSRuntime
JSAutoRequest ar(mContext); JSAutoRequest ar(mContext);
mGlobal = JS_NewCompartmentAndGlobalObject(mContext, &sGlobalClass, NULL); mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, NULL);
NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);
JS_SetGlobalObject(mContext, mGlobal); JS_SetGlobalObject(mContext, mGlobal);

View File

@ -523,6 +523,27 @@ TabParent::SendSelectionEvent(nsSelectionEvent& event)
return PBrowserParent::SendSelectionEvent(event); return PBrowserParent::SendSelectionEvent(event);
} }
/*static*/ TabParent*
TabParent::GetFrom(nsFrameLoader* aFrameLoader)
{
if (!aFrameLoader) {
return nsnull;
}
PBrowserParent* remoteBrowser = aFrameLoader->GetRemoteBrowser();
return static_cast<TabParent*>(remoteBrowser);
}
/*static*/ TabParent*
TabParent::GetFrom(nsIContent* aContent)
{
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
if (!loaderOwner) {
return nsnull;
}
nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
return GetFrom(frameLoader);
}
bool bool
TabParent::RecvEndIMEComposition(const bool& aCancel, TabParent::RecvEndIMEComposition(const bool& aCancel,
nsString* aComposition) nsString* aComposition)

View File

@ -7,26 +7,26 @@
#ifndef mozilla_tabs_TabParent_h #ifndef mozilla_tabs_TabParent_h
#define mozilla_tabs_TabParent_h #define mozilla_tabs_TabParent_h
#include "base/basictypes.h"
#include "jsapi.h"
#include "mozilla/dom/PBrowserParent.h" #include "mozilla/dom/PBrowserParent.h"
#include "mozilla/dom/PContentDialogParent.h" #include "mozilla/dom/PContentDialogParent.h"
#include "mozilla/ipc/GeckoChildProcessHost.h" #include "mozilla/ipc/GeckoChildProcessHost.h"
#include "jsapi.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsITabParent.h"
#include "nsIBrowserDOMWindow.h"
#include "nsWeakReference.h"
#include "nsIDialogParamBlock.h"
#include "nsIAuthPromptProvider.h" #include "nsIAuthPromptProvider.h"
#include "nsIBrowserDOMWindow.h"
#include "nsIDialogParamBlock.h"
#include "nsISecureBrowserUI.h" #include "nsISecureBrowserUI.h"
#include "nsITabParent.h"
#include "nsWeakReference.h"
class nsFrameLoader;
class nsIURI;
class nsIDOMElement;
struct gfxMatrix; struct gfxMatrix;
struct JSContext; struct JSContext;
struct JSObject; struct JSObject;
class nsFrameLoader;
class nsIDOMElement;
class nsIURI;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -154,6 +154,10 @@ public:
bool SendCompositionEvent(nsCompositionEvent& event); bool SendCompositionEvent(nsCompositionEvent& event);
bool SendTextEvent(nsTextEvent& event); bool SendTextEvent(nsTextEvent& event);
bool SendSelectionEvent(nsSelectionEvent& event); bool SendSelectionEvent(nsSelectionEvent& event);
static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
static TabParent* GetFrom(nsIContent* aContent);
protected: protected:
bool ReceiveMessage(const nsString& aMessage, bool ReceiveMessage(const nsString& aMessage,
bool aSync, bool aSync,

View File

@ -261,6 +261,10 @@ static dom::ConstantSpec gWinProperties[] =
// SetFilePointer error constant // SetFilePointer error constant
INT_CONSTANT(INVALID_SET_FILE_POINTER), INT_CONSTANT(INVALID_SET_FILE_POINTER),
// MoveFile flags
INT_CONSTANT(MOVEFILE_COPY_ALLOWED),
INT_CONSTANT(MOVEFILE_REPLACE_EXISTING),
// Errors // Errors
INT_CONSTANT(ERROR_FILE_EXISTS), INT_CONSTANT(ERROR_FILE_EXISTS),
INT_CONSTANT(ERROR_FILE_NOT_FOUND), INT_CONSTANT(ERROR_FILE_NOT_FOUND),

View File

@ -909,8 +909,8 @@ CreateDedicatedWorkerGlobalScope(JSContext* aCx)
JS_ASSERT(worker); JS_ASSERT(worker);
JSObject* global = JSObject* global =
JS_NewCompartmentAndGlobalObject(aCx, DedicatedWorkerGlobalScope::Class(), JS_NewGlobalObject(aCx, DedicatedWorkerGlobalScope::Class(),
GetWorkerPrincipal()); GetWorkerPrincipal());
if (!global) { if (!global) {
return NULL; return NULL;
} }

View File

@ -127,7 +127,7 @@ nsresult CentralizedAdminPrefManagerInit()
static_cast<nsIXPCSecurityManager*>(new AutoConfigSecMan()); static_cast<nsIXPCSecurityManager*>(new AutoConfigSecMan());
xpc->SetSecurityManagerForJSContext(autoconfig_cx, secman, 0); xpc->SetSecurityManagerForJSContext(autoconfig_cx, secman, 0);
autoconfig_glob = JS_NewCompartmentAndGlobalObject(autoconfig_cx, &global_class, NULL); autoconfig_glob = JS_NewGlobalObject(autoconfig_cx, &global_class, NULL);
if (autoconfig_glob) { if (autoconfig_glob) {
JSAutoEnterCompartment ac; JSAutoEnterCompartment ac;
if(!ac.enter(autoconfig_cx, autoconfig_glob)) if(!ac.enter(autoconfig_cx, autoconfig_glob))

View File

@ -2263,7 +2263,6 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
} }
GLenum format; GLenum format;
GLenum internalformat;
GLenum type; GLenum type;
PRInt32 pixelSize = gfxASurface::BytePerPixelFromFormat(imageSurface->Format()); PRInt32 pixelSize = gfxASurface::BytePerPixelFromFormat(imageSurface->Format());
ShaderProgramType shader; ShaderProgramType shader;
@ -2301,8 +2300,6 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
PRInt32 stride = imageSurface->Stride(); PRInt32 stride = imageSurface->Stride();
internalformat = mIsGLES2 ? format : LOCAL_GL_RGBA;
nsIntRegionRectIterator iter(paintRegion); nsIntRegionRectIterator iter(paintRegion);
const nsIntRect *iterRect; const nsIntRect *iterRect;
@ -2334,7 +2331,7 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
} else { } else {
TexImage2D(LOCAL_GL_TEXTURE_2D, TexImage2D(LOCAL_GL_TEXTURE_2D,
0, 0,
internalformat, format,
iterRect->width, iterRect->width,
iterRect->height, iterRect->height,
stride, stride,

View File

@ -44,8 +44,6 @@ static inline CGImageRef SkCreateCGImageRef(const SkBitmap& bm) {
*/ */
void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y); void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y);
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output);
/** /**
* Return a provider that wraps the specified stream. It will become an * Return a provider that wraps the specified stream. It will become an
* owner of the stream, so the caller must still manage its ownership. * owner of the stream, so the caller must still manage its ownership.

View File

@ -0,0 +1,865 @@
From: David Zbarsky <dzbarsky@gmail.com>
Bug 766017 - Fix some skia warnings r=gw280
diff --git a/gfx/skia/include/utils/mac/SkCGUtils.h b/gfx/skia/include/utils/mac/SkCGUtils.h
--- a/gfx/skia/include/utils/mac/SkCGUtils.h
+++ b/gfx/skia/include/utils/mac/SkCGUtils.h
@@ -39,18 +39,16 @@ static inline CGImageRef SkCreateCGImage
/**
* Draw the bitmap into the specified CG context. The bitmap will be converted
* to a CGImage using the generic RGB colorspace. (x,y) specifies the position
* of the top-left corner of the bitmap. The bitmap is converted using the
* colorspace returned by CGColorSpaceCreateDeviceRGB()
*/
void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y);
-bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output);
-
/**
* Return a provider that wraps the specified stream. It will become an
* owner of the stream, so the caller must still manage its ownership.
*
* To hand-off ownership of the stream to the provider, the caller must do
* something like the following:
*
* SkStream* stream = new ...;
diff --git a/gfx/skia/src/core/SkAAClip.cpp b/gfx/skia/src/core/SkAAClip.cpp
--- a/gfx/skia/src/core/SkAAClip.cpp
+++ b/gfx/skia/src/core/SkAAClip.cpp
@@ -246,17 +246,17 @@ static void count_left_right_zeros(const
zeros = 0;
}
row += 2;
width -= n;
}
*riteZ = zeros;
}
-#ifdef SK_DEBUG
+#if 0
static void test_count_left_right_zeros() {
static bool gOnce;
if (gOnce) {
return;
}
gOnce = true;
const uint8_t data0[] = { 0, 0, 10, 0xFF };
@@ -1319,22 +1319,16 @@ bool SkAAClip::setPath(const SkPath& pat
}
///////////////////////////////////////////////////////////////////////////////
typedef void (*RowProc)(SkAAClip::Builder&, int bottom,
const uint8_t* rowA, const SkIRect& rectA,
const uint8_t* rowB, const SkIRect& rectB);
-static void sectRowProc(SkAAClip::Builder& builder, int bottom,
- const uint8_t* rowA, const SkIRect& rectA,
- const uint8_t* rowB, const SkIRect& rectB) {
-
-}
-
typedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB);
static U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) {
// Multiply
return SkMulDiv255Round(alphaA, alphaB);
}
static U8CPU unionAlphaProc(U8CPU alphaA, U8CPU alphaB) {
@@ -1429,31 +1423,16 @@ private:
static void adjust_row(RowIter& iter, int& leftA, int& riteA, int rite) {
if (rite == riteA) {
iter.next();
leftA = iter.left();
riteA = iter.right();
}
}
-static bool intersect(int& min, int& max, int boundsMin, int boundsMax) {
- SkASSERT(min < max);
- SkASSERT(boundsMin < boundsMax);
- if (min >= boundsMax || max <= boundsMin) {
- return false;
- }
- if (min < boundsMin) {
- min = boundsMin;
- }
- if (max > boundsMax) {
- max = boundsMax;
- }
- return true;
-}
-
static void operatorX(SkAAClip::Builder& builder, int lastY,
RowIter& iterA, RowIter& iterB,
AlphaProc proc, const SkIRect& bounds) {
int leftA = iterA.left();
int riteA = iterA.right();
int leftB = iterB.left();
int riteB = iterB.right();
@@ -1970,34 +1949,33 @@ static void small_bzero(void* dst, size_
static inline uint8_t mergeOne(uint8_t value, unsigned alpha) {
return SkMulDiv255Round(value, alpha);
}
static inline uint16_t mergeOne(uint16_t value, unsigned alpha) {
unsigned r = SkGetPackedR16(value);
unsigned g = SkGetPackedG16(value);
unsigned b = SkGetPackedB16(value);
return SkPackRGB16(SkMulDiv255Round(r, alpha),
- SkMulDiv255Round(r, alpha),
- SkMulDiv255Round(r, alpha));
+ SkMulDiv255Round(g, alpha),
+ SkMulDiv255Round(b, alpha));
}
static inline SkPMColor mergeOne(SkPMColor value, unsigned alpha) {
unsigned a = SkGetPackedA32(value);
unsigned r = SkGetPackedR32(value);
unsigned g = SkGetPackedG32(value);
unsigned b = SkGetPackedB32(value);
return SkPackARGB32(SkMulDiv255Round(a, alpha),
SkMulDiv255Round(r, alpha),
SkMulDiv255Round(g, alpha),
SkMulDiv255Round(b, alpha));
}
template <typename T> void mergeT(const T* SK_RESTRICT src, int srcN,
const uint8_t* SK_RESTRICT row, int rowN,
T* SK_RESTRICT dst) {
- SkDEBUGCODE(int accumulated = 0;)
for (;;) {
SkASSERT(rowN > 0);
SkASSERT(srcN > 0);
int n = SkMin32(rowN, srcN);
unsigned rowA = row[1];
if (0xFF == rowA) {
small_memcpy(dst, src, n * sizeof(T));
diff --git a/gfx/skia/src/core/SkBlitMask_D32.cpp b/gfx/skia/src/core/SkBlitMask_D32.cpp
--- a/gfx/skia/src/core/SkBlitMask_D32.cpp
+++ b/gfx/skia/src/core/SkBlitMask_D32.cpp
@@ -268,107 +268,49 @@ bool SkBlitMask::BlitColor(const SkBitma
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
- const uint8_t* SK_RESTRICT mask,
- const SkPMColor* SK_RESTRICT src, int count) {
- int i, octuple = (count + 7) >> 3;
- for (i = 0; i < octuple; ++i) {
- int m = *mask++;
- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
- if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); }
- if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); }
- if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); }
- if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); }
- if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); }
- if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); }
- if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); }
- src += 8;
- dst += 8;
- }
- count &= 7;
- if (count > 0) {
- int m = *mask;
- do {
- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
- m <<= 1;
- src += 1;
- dst += 1;
- } while (--count > 0);
- }
-}
-
-static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
- const uint8_t* SK_RESTRICT mask,
- const SkPMColor* SK_RESTRICT src, int count) {
- int i, octuple = (count + 7) >> 3;
- for (i = 0; i < octuple; ++i) {
- int m = *mask++;
- if (m & 0x80) { dst[0] = src[0]; }
- if (m & 0x40) { dst[1] = src[1]; }
- if (m & 0x20) { dst[2] = src[2]; }
- if (m & 0x10) { dst[3] = src[3]; }
- if (m & 0x08) { dst[4] = src[4]; }
- if (m & 0x04) { dst[5] = src[5]; }
- if (m & 0x02) { dst[6] = src[6]; }
- if (m & 0x01) { dst[7] = src[7]; }
- src += 8;
- dst += 8;
- }
- count &= 7;
- if (count > 0) {
- int m = *mask;
- do {
- if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
- m <<= 1;
- src += 1;
- dst += 1;
- } while (--count > 0);
- }
-}
-
static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) {
for (int i = 0; i < count; ++i) {
if (mask[i]) {
dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]);
}
}
}
// expand the steps that SkAlphaMulQ performs, but this way we can
-// exand.. add.. combine
+// expand.. add.. combine
// instead of
// expand..combine add expand..combine
//
#define EXPAND0(v, m, s) ((v) & (m)) * (s)
#define EXPAND1(v, m, s) (((v) >> 8) & (m)) * (s)
#define COMBINE(e0, e1, m) ((((e0) >> 8) & (m)) | ((e1) & ~(m)))
static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) {
- const uint32_t rbmask = gMask_00FF00FF;
for (int i = 0; i < count; ++i) {
int m = mask[i];
if (m) {
m += (m >> 7);
#if 1
// this is slightly slower than the expand/combine version, but it
// is much closer to the old results, so we use it for now to reduce
// rebaselining.
dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m);
#else
+ const uint32_t rbmask = gMask_00FF00FF;
uint32_t v = src[i];
uint32_t s0 = EXPAND0(v, rbmask, m);
uint32_t s1 = EXPAND1(v, rbmask, m);
v = dst[i];
uint32_t d0 = EXPAND0(v, rbmask, m);
uint32_t d1 = EXPAND1(v, rbmask, m);
dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask);
#endif
@@ -559,17 +501,17 @@ SkBlitMask::RowProc SkBlitMask::RowFacto
// make this opt-in until chrome can rebaseline
RowProc proc = PlatformRowProcs(config, format, flags);
if (proc) {
return proc;
}
static const RowProc gProcs[] = {
// need X coordinate to handle BW
- NULL, NULL, //(RowProc)BW_RowProc_Blend, (RowProc)BW_RowProc_Opaque,
+ NULL, NULL,
(RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque,
(RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque,
(RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque,
};
int index;
switch (config) {
case SkBitmap::kARGB_8888_Config:
diff --git a/gfx/skia/src/core/SkConcaveToTriangles.cpp b/gfx/skia/src/core/SkConcaveToTriangles.cpp
--- a/gfx/skia/src/core/SkConcaveToTriangles.cpp
+++ b/gfx/skia/src/core/SkConcaveToTriangles.cpp
@@ -37,17 +37,16 @@
#include "SkTDArray.h"
#include "SkGeometry.h"
#include "SkTSort.h"
// This is used to prevent runaway code bugs, and can probably be removed after
// the code has been proven robust.
#define kMaxCount 1000
-#define DEBUG
#ifdef DEBUG
//------------------------------------------------------------------------------
// Debugging support
//------------------------------------------------------------------------------
#include <cstdio>
#include <stdarg.h>
diff --git a/gfx/skia/src/core/SkPath.cpp b/gfx/skia/src/core/SkPath.cpp
--- a/gfx/skia/src/core/SkPath.cpp
+++ b/gfx/skia/src/core/SkPath.cpp
@@ -469,17 +469,16 @@ void SkPath::incReserve(U16CPU inc) {
fPts.setReserve(fPts.count() + inc);
SkDEBUGCODE(this->validate();)
}
void SkPath::moveTo(SkScalar x, SkScalar y) {
SkDEBUGCODE(this->validate();)
- int vc = fVerbs.count();
SkPoint* pt;
// remember our index
fLastMoveToIndex = fPts.count();
pt = fPts.append();
*fVerbs.append() = kMove_Verb;
pt->set(x, y);
@@ -1163,17 +1162,16 @@ void SkPath::reversePathTo(const SkPath&
}
pts -= gPtsInVerb[verbs[i]];
}
}
void SkPath::reverseAddPath(const SkPath& src) {
this->incReserve(src.fPts.count());
- const SkPoint* startPts = src.fPts.begin();
const SkPoint* pts = src.fPts.end();
const uint8_t* startVerbs = src.fVerbs.begin();
const uint8_t* verbs = src.fVerbs.end();
fIsOval = false;
bool needMove = true;
bool needClose = false;
diff --git a/gfx/skia/src/core/SkRegion.cpp b/gfx/skia/src/core/SkRegion.cpp
--- a/gfx/skia/src/core/SkRegion.cpp
+++ b/gfx/skia/src/core/SkRegion.cpp
@@ -920,20 +920,16 @@ static int operate(const SkRegion::RunTy
/* Given count RunTypes in a complex region, return the worst case number of
logical intervals that represents (i.e. number of rects that would be
returned from the iterator).
We could just return count/2, since there must be at least 2 values per
interval, but we can first trim off the const overhead of the initial TOP
value, plus the final BOTTOM + 2 sentinels.
*/
-static int count_to_intervals(int count) {
- SkASSERT(count >= 6); // a single rect is 6 values
- return (count - 4) >> 1;
-}
/* Given a number of intervals, what is the worst case representation of that
many intervals?
Worst case (from a storage perspective), is a vertical stack of single
intervals: TOP + N * (BOTTOM INTERVALCOUNT LEFT RIGHT SENTINEL) + SENTINEL
*/
static int intervals_to_count(int intervals) {
diff --git a/gfx/skia/src/core/SkScalerContext.cpp b/gfx/skia/src/core/SkScalerContext.cpp
--- a/gfx/skia/src/core/SkScalerContext.cpp
+++ b/gfx/skia/src/core/SkScalerContext.cpp
@@ -336,44 +336,16 @@ SK_ERROR:
glyph->fTop = 0;
glyph->fWidth = 0;
glyph->fHeight = 0;
// put a valid value here, in case it was earlier set to
// MASK_FORMAT_JUST_ADVANCE
glyph->fMaskFormat = fRec.fMaskFormat;
}
-static bool isLCD(const SkScalerContext::Rec& rec) {
- return SkMask::kLCD16_Format == rec.fMaskFormat ||
- SkMask::kLCD32_Format == rec.fMaskFormat;
-}
-
-static uint16_t a8_to_rgb565(unsigned a8) {
- return SkPackRGB16(a8 >> 3, a8 >> 2, a8 >> 3);
-}
-
-static void copyToLCD16(const SkBitmap& src, const SkMask& dst) {
- SkASSERT(SkBitmap::kA8_Config == src.config());
- SkASSERT(SkMask::kLCD16_Format == dst.fFormat);
-
- const int width = dst.fBounds.width();
- const int height = dst.fBounds.height();
- const uint8_t* srcP = src.getAddr8(0, 0);
- size_t srcRB = src.rowBytes();
- uint16_t* dstP = (uint16_t*)dst.fImage;
- size_t dstRB = dst.fRowBytes;
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- dstP[x] = a8_to_rgb565(srcP[x]);
- }
- srcP += srcRB;
- dstP = (uint16_t*)((char*)dstP + dstRB);
- }
-}
-
#define SK_FREETYPE_LCD_LERP 160
static int lerp(int start, int end) {
SkASSERT((unsigned)SK_FREETYPE_LCD_LERP <= 256);
return start + ((end - start) * (SK_FREETYPE_LCD_LERP) >> 8);
}
static uint16_t packLCD16(unsigned r, unsigned g, unsigned b) {
diff --git a/gfx/skia/src/core/SkScan_AntiPath.cpp b/gfx/skia/src/core/SkScan_AntiPath.cpp
--- a/gfx/skia/src/core/SkScan_AntiPath.cpp
+++ b/gfx/skia/src/core/SkScan_AntiPath.cpp
@@ -230,52 +230,16 @@ void SuperBlitter::blitH(int x, int y, i
fOffsetX);
#ifdef SK_DEBUG
fRuns.assertValid(y & MASK, (1 << (8 - SHIFT)));
fCurrX = x + width;
#endif
}
-static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
- int n, U8CPU riteA) {
- SkASSERT(leftA <= 0xFF);
- SkASSERT(riteA <= 0xFF);
-
- int16_t* run = runs.fRuns;
- uint8_t* aa = runs.fAlpha;
-
- if (ileft > 0) {
- run[0] = ileft;
- aa[0] = 0;
- run += ileft;
- aa += ileft;
- }
-
- SkASSERT(leftA < 0xFF);
- if (leftA > 0) {
- *run++ = 1;
- *aa++ = leftA;
- }
-
- if (n > 0) {
- run[0] = n;
- aa[0] = 0xFF;
- run += n;
- aa += n;
- }
-
- SkASSERT(riteA < 0xFF);
- if (riteA > 0) {
- *run++ = 1;
- *aa++ = riteA;
- }
- run[0] = 0;
-}
-
void SuperBlitter::blitRect(int x, int y, int width, int height) {
SkASSERT(width > 0);
SkASSERT(height > 0);
// blit leading rows
while ((y & MASK)) {
this->blitH(x, y++, width);
if (--height <= 0) {
diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
--- a/gfx/skia/src/effects/SkGradientShader.cpp
+++ b/gfx/skia/src/effects/SkGradientShader.cpp
@@ -865,45 +865,16 @@ bool Linear_Gradient::setContext(const S
} while (0)
namespace {
typedef void (*LinearShadeProc)(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* dstC, const SkPMColor* cache,
int toggle, int count);
-// This function is deprecated, and will be replaced by
-// shadeSpan_linear_vertical_lerp() once Chrome has been weaned off of it.
-void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
- SkPMColor* SK_RESTRICT dstC,
- const SkPMColor* SK_RESTRICT cache,
- int toggle, int count) {
- if (proc == clamp_tileproc) {
- // Read out clamp values from beginning/end of the cache. No need to lerp
- // or dither
- if (fx < 0) {
- sk_memset32(dstC, cache[-1], count);
- return;
- } else if (fx > 0xFFFF) {
- sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
- return;
- }
- }
-
- // We're a vertical gradient, so no change in a span.
- // If colors change sharply across the gradient, dithering is
- // insufficient (it subsamples the color space) and we need to lerp.
- unsigned fullIndex = proc(fx);
- unsigned fi = fullIndex >> (16 - Gradient_Shader::kCache32Bits);
- sk_memset32_dither(dstC,
- cache[toggle + fi],
- cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi],
- count);
-}
-
// Linear interpolation (lerp) is unnecessary if there are no sharp
// discontinuities in the gradient - which must be true if there are
// only 2 colors - but it's cheap.
void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
if (proc == clamp_tileproc) {
@@ -2131,16 +2102,18 @@ protected:
buffer.writePoint(fCenter);
}
private:
typedef Gradient_Shader INHERITED;
const SkPoint fCenter;
};
+#ifndef SK_SCALAR_IS_FLOAT
+
#ifdef COMPUTE_SWEEP_TABLE
#define PI 3.14159265
static bool gSweepTableReady;
static uint8_t gSweepTable[65];
/* Our table stores precomputed values for atan: [0...1] -> [0..PI/4]
We scale the results to [0..32]
*/
@@ -2168,20 +2141,23 @@ static const uint8_t gSweepTable[] = {
10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18,
19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26,
26, 27, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32,
32
};
static const uint8_t* build_sweep_table() { return gSweepTable; }
#endif
+#endif
+
// divide numer/denom, with a bias of 6bits. Assumes numer <= denom
// and denom != 0. Since our table is 6bits big (+1), this is a nice fit.
// Same as (but faster than) SkFixedDiv(numer, denom) >> 10
+#ifndef SK_SCALAR_IS_FLOAT
//unsigned div_64(int numer, int denom);
static unsigned div_64(int numer, int denom) {
SkASSERT(numer <= denom);
SkASSERT(numer > 0);
SkASSERT(denom > 0);
int nbits = SkCLZ(numer);
int dbits = SkCLZ(denom);
@@ -2294,16 +2270,17 @@ static unsigned atan_0_90(SkFixed y, SkF
result = 64 - result;
// pin to 63
result -= result >> 6;
}
SkASSERT(result <= 63);
return result;
}
+#endif
// returns angle in a circle [0..2PI) -> [0..255]
#ifdef SK_SCALAR_IS_FLOAT
static unsigned SkATan2_255(float y, float x) {
// static const float g255Over2PI = 255 / (2 * SK_ScalarPI);
static const float g255Over2PI = 40.584510488433314f;
float result = sk_float_atan2(y, x);
diff --git a/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp b/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp
--- a/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp
+++ b/gfx/skia/src/opts/SkBlitRect_opts_SSE2.cpp
@@ -112,17 +112,17 @@ void BlitRect32_OpaqueWide_SSE2(SkPMColo
}
void ColorRect32_SSE2(SkPMColor* destination,
int width, int height,
size_t rowBytes, uint32_t color) {
if (0 == height || 0 == width || 0 == color) {
return;
}
- unsigned colorA = SkGetPackedA32(color);
+ //unsigned colorA = SkGetPackedA32(color);
//if (255 == colorA) {
//if (width < 31) {
//BlitRect32_OpaqueNarrow_SSE2(destination, width, height,
//rowBytes, color);
//} else {
//BlitRect32_OpaqueWide_SSE2(destination, width, height,
//rowBytes, color);
//}
diff --git a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
--- a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
+++ b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
@@ -75,20 +75,16 @@ static CGFloat CGRectGetMinY_inline(cons
static CGFloat CGRectGetMaxY_inline(const CGRect& rect) {
return rect.origin.y + rect.size.height;
}
static CGFloat CGRectGetWidth_inline(const CGRect& rect) {
return rect.size.width;
}
-static CGFloat CGRectGetHeight(const CGRect& rect) {
- return rect.size.height;
-}
-
///////////////////////////////////////////////////////////////////////////////
static void sk_memset_rect32(uint32_t* ptr, uint32_t value, size_t width,
size_t height, size_t rowBytes) {
SkASSERT(width);
SkASSERT(width * sizeof(uint32_t) <= rowBytes);
if (width >= 32) {
@@ -125,28 +121,30 @@ static void sk_memset_rect32(uint32_t* p
*ptr++ = value;
} while (--w > 0);
ptr = (uint32_t*)((char*)ptr + rowBytes);
height -= 1;
}
}
}
+#if 0
// Potentially this should be made (1) public (2) optimized when width is small.
// Also might want 16 and 32 bit version
//
static void sk_memset_rect(void* ptr, U8CPU byte, size_t width, size_t height,
size_t rowBytes) {
uint8_t* dst = (uint8_t*)ptr;
while (height) {
memset(dst, byte, width);
dst += rowBytes;
height -= 1;
}
}
+#endif
#include <sys/utsname.h>
typedef uint32_t CGRGBPixel;
static unsigned CGRGBPixel_getAlpha(CGRGBPixel pixel) {
return pixel & 0xFF;
}
@@ -250,23 +248,16 @@ static CGAffineTransform MatrixToCGAffin
return CGAffineTransformMake(ScalarToCG(matrix[SkMatrix::kMScaleX]) * sx,
-ScalarToCG(matrix[SkMatrix::kMSkewY]) * sy,
-ScalarToCG(matrix[SkMatrix::kMSkewX]) * sx,
ScalarToCG(matrix[SkMatrix::kMScaleY]) * sy,
ScalarToCG(matrix[SkMatrix::kMTransX]) * sx,
ScalarToCG(matrix[SkMatrix::kMTransY]) * sy);
}
-static void CGAffineTransformToMatrix(const CGAffineTransform& xform, SkMatrix* matrix) {
- matrix->setAll(
- CGToScalar(xform.a), CGToScalar(xform.c), CGToScalar(xform.tx),
- CGToScalar(xform.b), CGToScalar(xform.d), CGToScalar(xform.ty),
- 0, 0, SK_Scalar1);
-}
-
static SkScalar getFontScale(CGFontRef cgFont) {
int unitsPerEm = CGFontGetUnitsPerEm(cgFont);
return SkScalarInvert(SkIntToScalar(unitsPerEm));
}
///////////////////////////////////////////////////////////////////////////////
#define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
@@ -1075,16 +1066,17 @@ static const uint8_t* getInverseTable(bo
if (!gInited) {
build_power_table(gWhiteTable, 1.5f);
build_power_table(gTable, 2.2f);
gInited = true;
}
return isWhite ? gWhiteTable : gTable;
}
+#ifdef SK_USE_COLOR_LUMINANCE
static const uint8_t* getGammaTable(U8CPU luminance) {
static uint8_t gGammaTables[4][256];
static bool gInited;
if (!gInited) {
#if 1
float start = 1.1;
float stop = 2.1;
for (int i = 0; i < 4; ++i) {
@@ -1097,45 +1089,49 @@ static const uint8_t* getGammaTable(U8CP
build_power_table(gGammaTables[2], 1);
build_power_table(gGammaTables[3], 1);
#endif
gInited = true;
}
SkASSERT(0 == (luminance >> 8));
return gGammaTables[luminance >> 6];
}
+#endif
+#ifndef SK_USE_COLOR_LUMINANCE
static void invertGammaMask(bool isWhite, CGRGBPixel rgb[], int width,
int height, size_t rb) {
const uint8_t* table = getInverseTable(isWhite);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
uint32_t c = rgb[x];
int r = (c >> 16) & 0xFF;
int g = (c >> 8) & 0xFF;
int b = (c >> 0) & 0xFF;
rgb[x] = (table[r] << 16) | (table[g] << 8) | table[b];
}
rgb = (CGRGBPixel*)((char*)rgb + rb);
}
}
+#endif
static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) {
while (count > 0) {
uint8_t mask = 0;
for (int i = 7; i >= 0; --i) {
mask |= (CGRGBPixel_getAlpha(*src++) >> 7) << i;
if (0 == --count) {
break;
}
}
*dst++ = mask;
}
}
+#ifdef SK_USE_COLOR_LUMINANCE
static int lerpScale(int dst, int src, int scale) {
return dst + (scale * (src - dst) >> 23);
}
static CGRGBPixel lerpPixel(CGRGBPixel dst, CGRGBPixel src,
int scaleR, int scaleG, int scaleB) {
int sr = (src >> 16) & 0xFF;
int sg = (src >> 8) & 0xFF;
@@ -1147,37 +1143,31 @@ static CGRGBPixel lerpPixel(CGRGBPixel d
int rr = lerpScale(dr, sr, scaleR);
int rg = lerpScale(dg, sg, scaleG);
int rb = lerpScale(db, sb, scaleB);
return (rr << 16) | (rg << 8) | rb;
}
static void lerpPixels(CGRGBPixel dst[], const CGRGBPixel src[], int width,
int height, int rowBytes, int lumBits) {
-#ifdef SK_USE_COLOR_LUMINANCE
int scaleR = (1 << 23) * SkColorGetR(lumBits) / 0xFF;
int scaleG = (1 << 23) * SkColorGetG(lumBits) / 0xFF;
int scaleB = (1 << 23) * SkColorGetB(lumBits) / 0xFF;
-#else
- int scale = (1 << 23) * lumBits / SkScalerContext::kLuminance_Max;
- int scaleR = scale;
- int scaleG = scale;
- int scaleB = scale;
-#endif
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// bit-not the src, since it was drawn from black, so we need the
// compliment of those bits
dst[x] = lerpPixel(dst[x], ~src[x], scaleR, scaleG, scaleB);
}
src = (CGRGBPixel*)((char*)src + rowBytes);
dst = (CGRGBPixel*)((char*)dst + rowBytes);
}
}
+#endif
#if 1
static inline int r32_to_16(int x) { return SkR32ToR16(x); }
static inline int g32_to_16(int x) { return SkG32ToG16(x); }
static inline int b32_to_16(int x) { return SkB32ToB16(x); }
#else
static inline int round8to5(int x) {
return (x + 3 - (x >> 5) + (x >> 7)) >> 3;
@@ -1212,22 +1202,21 @@ static inline uint32_t rgb_to_lcd32(CGRG
return SkPackARGB32(0xFF, r, g, b);
}
#define BLACK_LUMINANCE_LIMIT 0x40
#define WHITE_LUMINANCE_LIMIT 0xA0
void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount);
-
const bool isLCD = isLCDFormat(glyph.fMaskFormat);
+#ifdef SK_USE_COLOR_LUMINANCE
const bool isBW = SkMask::kBW_Format == glyph.fMaskFormat;
const bool isA8 = !isLCD && !isBW;
-
-#ifdef SK_USE_COLOR_LUMINANCE
+
unsigned lumBits = fRec.getLuminanceColor();
uint32_t xorMask = 0;
if (isA8) {
// for A8, we just want a component (they're all the same)
lumBits = SkColorGetR(lumBits);
}
#else
diff --git a/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp b/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp
--- a/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp
+++ b/gfx/skia/src/utils/mac/SkCreateCGImageRef.cpp
@@ -163,59 +163,8 @@ private:
CGPDFDocumentRef fDoc;
};
static void CGDataProviderReleaseData_FromMalloc(void*, const void* data,
size_t size) {
sk_free((void*)data);
}
-bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
- size_t size = stream->getLength();
- void* ptr = sk_malloc_throw(size);
- stream->read(ptr, size);
- CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size,
- CGDataProviderReleaseData_FromMalloc);
- if (NULL == data) {
- return false;
- }
-
- CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data);
- CGDataProviderRelease(data);
- if (NULL == pdf) {
- return false;
- }
- SkAutoPDFRelease releaseMe(pdf);
-
- CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
- if (NULL == page) {
- return false;
- }
-
- CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
-
- int w = (int)CGRectGetWidth(bounds);
- int h = (int)CGRectGetHeight(bounds);
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h);
- bitmap.allocPixels();
- bitmap.eraseColor(SK_ColorWHITE);
-
- size_t bitsPerComponent;
- CGBitmapInfo info;
- getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL);
-
- CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
- CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h,
- bitsPerComponent, bitmap.rowBytes(),
- cs, info);
- CGColorSpaceRelease(cs);
-
- if (ctx) {
- CGContextDrawPDFPage(ctx, page);
- CGContextRelease(ctx);
- }
-
- output->swap(bitmap);
- return true;
-}
-

View File

@ -17,3 +17,4 @@ See the relevant bugs in bugzilla for information on these patches:
0012-Bug-759683-make-ssse3-conditional.patch 0012-Bug-759683-make-ssse3-conditional.patch
0013-Bug-761890-fonts.patch 0013-Bug-761890-fonts.patch
0014-Bug-765038-Fix-clang-build.patch 0014-Bug-765038-Fix-clang-build.patch
0015-Bug-766017-warnings.patch

View File

@ -251,7 +251,7 @@ static void count_left_right_zeros(const uint8_t* row, int width,
*riteZ = zeros; *riteZ = zeros;
} }
#ifdef SK_DEBUG #if 0
static void test_count_left_right_zeros() { static void test_count_left_right_zeros() {
static bool gOnce; static bool gOnce;
if (gOnce) { if (gOnce) {
@ -1324,12 +1324,6 @@ typedef void (*RowProc)(SkAAClip::Builder&, int bottom,
const uint8_t* rowA, const SkIRect& rectA, const uint8_t* rowA, const SkIRect& rectA,
const uint8_t* rowB, const SkIRect& rectB); const uint8_t* rowB, const SkIRect& rectB);
static void sectRowProc(SkAAClip::Builder& builder, int bottom,
const uint8_t* rowA, const SkIRect& rectA,
const uint8_t* rowB, const SkIRect& rectB) {
}
typedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB); typedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB);
static U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) { static U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) {
@ -1434,21 +1428,6 @@ static void adjust_row(RowIter& iter, int& leftA, int& riteA, int rite) {
} }
} }
static bool intersect(int& min, int& max, int boundsMin, int boundsMax) {
SkASSERT(min < max);
SkASSERT(boundsMin < boundsMax);
if (min >= boundsMax || max <= boundsMin) {
return false;
}
if (min < boundsMin) {
min = boundsMin;
}
if (max > boundsMax) {
max = boundsMax;
}
return true;
}
static void operatorX(SkAAClip::Builder& builder, int lastY, static void operatorX(SkAAClip::Builder& builder, int lastY,
RowIter& iterA, RowIter& iterB, RowIter& iterA, RowIter& iterB,
AlphaProc proc, const SkIRect& bounds) { AlphaProc proc, const SkIRect& bounds) {
@ -1975,8 +1954,8 @@ static inline uint16_t mergeOne(uint16_t value, unsigned alpha) {
unsigned g = SkGetPackedG16(value); unsigned g = SkGetPackedG16(value);
unsigned b = SkGetPackedB16(value); unsigned b = SkGetPackedB16(value);
return SkPackRGB16(SkMulDiv255Round(r, alpha), return SkPackRGB16(SkMulDiv255Round(r, alpha),
SkMulDiv255Round(r, alpha), SkMulDiv255Round(g, alpha),
SkMulDiv255Round(r, alpha)); SkMulDiv255Round(b, alpha));
} }
static inline SkPMColor mergeOne(SkPMColor value, unsigned alpha) { static inline SkPMColor mergeOne(SkPMColor value, unsigned alpha) {
unsigned a = SkGetPackedA32(value); unsigned a = SkGetPackedA32(value);
@ -1992,7 +1971,6 @@ static inline SkPMColor mergeOne(SkPMColor value, unsigned alpha) {
template <typename T> void mergeT(const T* SK_RESTRICT src, int srcN, template <typename T> void mergeT(const T* SK_RESTRICT src, int srcN,
const uint8_t* SK_RESTRICT row, int rowN, const uint8_t* SK_RESTRICT row, int rowN,
T* SK_RESTRICT dst) { T* SK_RESTRICT dst) {
SkDEBUGCODE(int accumulated = 0;)
for (;;) { for (;;) {
SkASSERT(rowN > 0); SkASSERT(rowN > 0);
SkASSERT(srcN > 0); SkASSERT(srcN > 0);

View File

@ -273,64 +273,6 @@ bool SkBlitMask::BlitColor(const SkBitmap& device, const SkMask& mask,
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) {
int i, octuple = (count + 7) >> 3;
for (i = 0; i < octuple; ++i) {
int m = *mask++;
if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); }
if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); }
if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); }
if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); }
if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); }
if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); }
if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); }
src += 8;
dst += 8;
}
count &= 7;
if (count > 0) {
int m = *mask;
do {
if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
m <<= 1;
src += 1;
dst += 1;
} while (--count > 0);
}
}
static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) {
int i, octuple = (count + 7) >> 3;
for (i = 0; i < octuple; ++i) {
int m = *mask++;
if (m & 0x80) { dst[0] = src[0]; }
if (m & 0x40) { dst[1] = src[1]; }
if (m & 0x20) { dst[2] = src[2]; }
if (m & 0x10) { dst[3] = src[3]; }
if (m & 0x08) { dst[4] = src[4]; }
if (m & 0x04) { dst[5] = src[5]; }
if (m & 0x02) { dst[6] = src[6]; }
if (m & 0x01) { dst[7] = src[7]; }
src += 8;
dst += 8;
}
count &= 7;
if (count > 0) {
int m = *mask;
do {
if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
m <<= 1;
src += 1;
dst += 1;
} while (--count > 0);
}
}
static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst, static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask, const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) { const SkPMColor* SK_RESTRICT src, int count) {
@ -342,7 +284,7 @@ static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
} }
// expand the steps that SkAlphaMulQ performs, but this way we can // expand the steps that SkAlphaMulQ performs, but this way we can
// exand.. add.. combine // expand.. add.. combine
// instead of // instead of
// expand..combine add expand..combine // expand..combine add expand..combine
// //
@ -353,7 +295,6 @@ static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask, const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) { const SkPMColor* SK_RESTRICT src, int count) {
const uint32_t rbmask = gMask_00FF00FF;
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
int m = mask[i]; int m = mask[i];
if (m) { if (m) {
@ -364,6 +305,7 @@ static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
// rebaselining. // rebaselining.
dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m); dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m);
#else #else
const uint32_t rbmask = gMask_00FF00FF;
uint32_t v = src[i]; uint32_t v = src[i];
uint32_t s0 = EXPAND0(v, rbmask, m); uint32_t s0 = EXPAND0(v, rbmask, m);
uint32_t s1 = EXPAND1(v, rbmask, m); uint32_t s1 = EXPAND1(v, rbmask, m);
@ -564,7 +506,7 @@ SkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config,
static const RowProc gProcs[] = { static const RowProc gProcs[] = {
// need X coordinate to handle BW // need X coordinate to handle BW
NULL, NULL, //(RowProc)BW_RowProc_Blend, (RowProc)BW_RowProc_Opaque, NULL, NULL,
(RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque, (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque,
(RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque, (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque,
(RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque, (RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque,

View File

@ -42,7 +42,6 @@
// the code has been proven robust. // the code has been proven robust.
#define kMaxCount 1000 #define kMaxCount 1000
#define DEBUG
#ifdef DEBUG #ifdef DEBUG
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Debugging support // Debugging support

View File

@ -474,7 +474,6 @@ void SkPath::incReserve(U16CPU inc) {
void SkPath::moveTo(SkScalar x, SkScalar y) { void SkPath::moveTo(SkScalar x, SkScalar y) {
SkDEBUGCODE(this->validate();) SkDEBUGCODE(this->validate();)
int vc = fVerbs.count();
SkPoint* pt; SkPoint* pt;
// remember our index // remember our index
@ -1168,7 +1167,6 @@ void SkPath::reversePathTo(const SkPath& path) {
void SkPath::reverseAddPath(const SkPath& src) { void SkPath::reverseAddPath(const SkPath& src) {
this->incReserve(src.fPts.count()); this->incReserve(src.fPts.count());
const SkPoint* startPts = src.fPts.begin();
const SkPoint* pts = src.fPts.end(); const SkPoint* pts = src.fPts.end();
const uint8_t* startVerbs = src.fVerbs.begin(); const uint8_t* startVerbs = src.fVerbs.begin();
const uint8_t* verbs = src.fVerbs.end(); const uint8_t* verbs = src.fVerbs.end();

View File

@ -925,10 +925,6 @@ static int operate(const SkRegion::RunType a_runs[],
interval, but we can first trim off the const overhead of the initial TOP interval, but we can first trim off the const overhead of the initial TOP
value, plus the final BOTTOM + 2 sentinels. value, plus the final BOTTOM + 2 sentinels.
*/ */
static int count_to_intervals(int count) {
SkASSERT(count >= 6); // a single rect is 6 values
return (count - 4) >> 1;
}
/* Given a number of intervals, what is the worst case representation of that /* Given a number of intervals, what is the worst case representation of that
many intervals? many intervals?

View File

@ -341,34 +341,6 @@ SK_ERROR:
glyph->fMaskFormat = fRec.fMaskFormat; glyph->fMaskFormat = fRec.fMaskFormat;
} }
static bool isLCD(const SkScalerContext::Rec& rec) {
return SkMask::kLCD16_Format == rec.fMaskFormat ||
SkMask::kLCD32_Format == rec.fMaskFormat;
}
static uint16_t a8_to_rgb565(unsigned a8) {
return SkPackRGB16(a8 >> 3, a8 >> 2, a8 >> 3);
}
static void copyToLCD16(const SkBitmap& src, const SkMask& dst) {
SkASSERT(SkBitmap::kA8_Config == src.config());
SkASSERT(SkMask::kLCD16_Format == dst.fFormat);
const int width = dst.fBounds.width();
const int height = dst.fBounds.height();
const uint8_t* srcP = src.getAddr8(0, 0);
size_t srcRB = src.rowBytes();
uint16_t* dstP = (uint16_t*)dst.fImage;
size_t dstRB = dst.fRowBytes;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
dstP[x] = a8_to_rgb565(srcP[x]);
}
srcP += srcRB;
dstP = (uint16_t*)((char*)dstP + dstRB);
}
}
#define SK_FREETYPE_LCD_LERP 160 #define SK_FREETYPE_LCD_LERP 160
static int lerp(int start, int end) { static int lerp(int start, int end) {

View File

@ -235,42 +235,6 @@ void SuperBlitter::blitH(int x, int y, int width) {
#endif #endif
} }
static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
int n, U8CPU riteA) {
SkASSERT(leftA <= 0xFF);
SkASSERT(riteA <= 0xFF);
int16_t* run = runs.fRuns;
uint8_t* aa = runs.fAlpha;
if (ileft > 0) {
run[0] = ileft;
aa[0] = 0;
run += ileft;
aa += ileft;
}
SkASSERT(leftA < 0xFF);
if (leftA > 0) {
*run++ = 1;
*aa++ = leftA;
}
if (n > 0) {
run[0] = n;
aa[0] = 0xFF;
run += n;
aa += n;
}
SkASSERT(riteA < 0xFF);
if (riteA > 0) {
*run++ = 1;
*aa++ = riteA;
}
run[0] = 0;
}
void SuperBlitter::blitRect(int x, int y, int width, int height) { void SuperBlitter::blitRect(int x, int y, int width, int height) {
SkASSERT(width > 0); SkASSERT(width > 0);
SkASSERT(height > 0); SkASSERT(height > 0);

View File

@ -870,35 +870,6 @@ typedef void (*LinearShadeProc)(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* dstC, const SkPMColor* cache, SkPMColor* dstC, const SkPMColor* cache,
int toggle, int count); int toggle, int count);
// This function is deprecated, and will be replaced by
// shadeSpan_linear_vertical_lerp() once Chrome has been weaned off of it.
void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
if (proc == clamp_tileproc) {
// Read out clamp values from beginning/end of the cache. No need to lerp
// or dither
if (fx < 0) {
sk_memset32(dstC, cache[-1], count);
return;
} else if (fx > 0xFFFF) {
sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
return;
}
}
// We're a vertical gradient, so no change in a span.
// If colors change sharply across the gradient, dithering is
// insufficient (it subsamples the color space) and we need to lerp.
unsigned fullIndex = proc(fx);
unsigned fi = fullIndex >> (16 - Gradient_Shader::kCache32Bits);
sk_memset32_dither(dstC,
cache[toggle + fi],
cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi],
count);
}
// Linear interpolation (lerp) is unnecessary if there are no sharp // Linear interpolation (lerp) is unnecessary if there are no sharp
// discontinuities in the gradient - which must be true if there are // discontinuities in the gradient - which must be true if there are
// only 2 colors - but it's cheap. // only 2 colors - but it's cheap.
@ -2136,6 +2107,8 @@ private:
const SkPoint fCenter; const SkPoint fCenter;
}; };
#ifndef SK_SCALAR_IS_FLOAT
#ifdef COMPUTE_SWEEP_TABLE #ifdef COMPUTE_SWEEP_TABLE
#define PI 3.14159265 #define PI 3.14159265
static bool gSweepTableReady; static bool gSweepTableReady;
@ -2173,10 +2146,13 @@ static const uint8_t gSweepTable[] = {
static const uint8_t* build_sweep_table() { return gSweepTable; } static const uint8_t* build_sweep_table() { return gSweepTable; }
#endif #endif
#endif
// divide numer/denom, with a bias of 6bits. Assumes numer <= denom // divide numer/denom, with a bias of 6bits. Assumes numer <= denom
// and denom != 0. Since our table is 6bits big (+1), this is a nice fit. // and denom != 0. Since our table is 6bits big (+1), this is a nice fit.
// Same as (but faster than) SkFixedDiv(numer, denom) >> 10 // Same as (but faster than) SkFixedDiv(numer, denom) >> 10
#ifndef SK_SCALAR_IS_FLOAT
//unsigned div_64(int numer, int denom); //unsigned div_64(int numer, int denom);
static unsigned div_64(int numer, int denom) { static unsigned div_64(int numer, int denom) {
SkASSERT(numer <= denom); SkASSERT(numer <= denom);
@ -2299,6 +2275,7 @@ static unsigned atan_0_90(SkFixed y, SkFixed x) {
SkASSERT(result <= 63); SkASSERT(result <= 63);
return result; return result;
} }
#endif
// returns angle in a circle [0..2PI) -> [0..255] // returns angle in a circle [0..2PI) -> [0..255]
#ifdef SK_SCALAR_IS_FLOAT #ifdef SK_SCALAR_IS_FLOAT

View File

@ -117,7 +117,7 @@ void ColorRect32_SSE2(SkPMColor* destination,
if (0 == height || 0 == width || 0 == color) { if (0 == height || 0 == width || 0 == color) {
return; return;
} }
unsigned colorA = SkGetPackedA32(color); //unsigned colorA = SkGetPackedA32(color);
//if (255 == colorA) { //if (255 == colorA) {
//if (width < 31) { //if (width < 31) {
//BlitRect32_OpaqueNarrow_SSE2(destination, width, height, //BlitRect32_OpaqueNarrow_SSE2(destination, width, height,

View File

@ -80,10 +80,6 @@ static CGFloat CGRectGetWidth_inline(const CGRect& rect) {
return rect.size.width; return rect.size.width;
} }
static CGFloat CGRectGetHeight(const CGRect& rect) {
return rect.size.height;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
static void sk_memset_rect32(uint32_t* ptr, uint32_t value, size_t width, static void sk_memset_rect32(uint32_t* ptr, uint32_t value, size_t width,
@ -130,6 +126,7 @@ static void sk_memset_rect32(uint32_t* ptr, uint32_t value, size_t width,
} }
} }
#if 0
// Potentially this should be made (1) public (2) optimized when width is small. // Potentially this should be made (1) public (2) optimized when width is small.
// Also might want 16 and 32 bit version // Also might want 16 and 32 bit version
// //
@ -142,6 +139,7 @@ static void sk_memset_rect(void* ptr, U8CPU byte, size_t width, size_t height,
height -= 1; height -= 1;
} }
} }
#endif
#include <sys/utsname.h> #include <sys/utsname.h>
@ -255,13 +253,6 @@ static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix,
ScalarToCG(matrix[SkMatrix::kMTransY]) * sy); ScalarToCG(matrix[SkMatrix::kMTransY]) * sy);
} }
static void CGAffineTransformToMatrix(const CGAffineTransform& xform, SkMatrix* matrix) {
matrix->setAll(
CGToScalar(xform.a), CGToScalar(xform.c), CGToScalar(xform.tx),
CGToScalar(xform.b), CGToScalar(xform.d), CGToScalar(xform.ty),
0, 0, SK_Scalar1);
}
static SkScalar getFontScale(CGFontRef cgFont) { static SkScalar getFontScale(CGFontRef cgFont) {
int unitsPerEm = CGFontGetUnitsPerEm(cgFont); int unitsPerEm = CGFontGetUnitsPerEm(cgFont);
return SkScalarInvert(SkIntToScalar(unitsPerEm)); return SkScalarInvert(SkIntToScalar(unitsPerEm));
@ -1080,6 +1071,7 @@ static const uint8_t* getInverseTable(bool isWhite) {
return isWhite ? gWhiteTable : gTable; return isWhite ? gWhiteTable : gTable;
} }
#ifdef SK_USE_COLOR_LUMINANCE
static const uint8_t* getGammaTable(U8CPU luminance) { static const uint8_t* getGammaTable(U8CPU luminance) {
static uint8_t gGammaTables[4][256]; static uint8_t gGammaTables[4][256];
static bool gInited; static bool gInited;
@ -1102,7 +1094,9 @@ static const uint8_t* getGammaTable(U8CPU luminance) {
SkASSERT(0 == (luminance >> 8)); SkASSERT(0 == (luminance >> 8));
return gGammaTables[luminance >> 6]; return gGammaTables[luminance >> 6];
} }
#endif
#ifndef SK_USE_COLOR_LUMINANCE
static void invertGammaMask(bool isWhite, CGRGBPixel rgb[], int width, static void invertGammaMask(bool isWhite, CGRGBPixel rgb[], int width,
int height, size_t rb) { int height, size_t rb) {
const uint8_t* table = getInverseTable(isWhite); const uint8_t* table = getInverseTable(isWhite);
@ -1117,6 +1111,7 @@ static void invertGammaMask(bool isWhite, CGRGBPixel rgb[], int width,
rgb = (CGRGBPixel*)((char*)rgb + rb); rgb = (CGRGBPixel*)((char*)rgb + rb);
} }
} }
#endif
static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) { static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) {
while (count > 0) { while (count > 0) {
@ -1131,6 +1126,7 @@ static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) {
} }
} }
#ifdef SK_USE_COLOR_LUMINANCE
static int lerpScale(int dst, int src, int scale) { static int lerpScale(int dst, int src, int scale) {
return dst + (scale * (src - dst) >> 23); return dst + (scale * (src - dst) >> 23);
} }
@ -1152,16 +1148,9 @@ static CGRGBPixel lerpPixel(CGRGBPixel dst, CGRGBPixel src,
static void lerpPixels(CGRGBPixel dst[], const CGRGBPixel src[], int width, static void lerpPixels(CGRGBPixel dst[], const CGRGBPixel src[], int width,
int height, int rowBytes, int lumBits) { int height, int rowBytes, int lumBits) {
#ifdef SK_USE_COLOR_LUMINANCE
int scaleR = (1 << 23) * SkColorGetR(lumBits) / 0xFF; int scaleR = (1 << 23) * SkColorGetR(lumBits) / 0xFF;
int scaleG = (1 << 23) * SkColorGetG(lumBits) / 0xFF; int scaleG = (1 << 23) * SkColorGetG(lumBits) / 0xFF;
int scaleB = (1 << 23) * SkColorGetB(lumBits) / 0xFF; int scaleB = (1 << 23) * SkColorGetB(lumBits) / 0xFF;
#else
int scale = (1 << 23) * lumBits / SkScalerContext::kLuminance_Max;
int scaleR = scale;
int scaleG = scale;
int scaleB = scale;
#endif
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
@ -1173,6 +1162,7 @@ static void lerpPixels(CGRGBPixel dst[], const CGRGBPixel src[], int width,
dst = (CGRGBPixel*)((char*)dst + rowBytes); dst = (CGRGBPixel*)((char*)dst + rowBytes);
} }
} }
#endif
#if 1 #if 1
static inline int r32_to_16(int x) { return SkR32ToR16(x); } static inline int r32_to_16(int x) { return SkR32ToR16(x); }
@ -1217,12 +1207,11 @@ static inline uint32_t rgb_to_lcd32(CGRGBPixel rgb) {
void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) { void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount); CGGlyph cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount);
const bool isLCD = isLCDFormat(glyph.fMaskFormat); const bool isLCD = isLCDFormat(glyph.fMaskFormat);
#ifdef SK_USE_COLOR_LUMINANCE
const bool isBW = SkMask::kBW_Format == glyph.fMaskFormat; const bool isBW = SkMask::kBW_Format == glyph.fMaskFormat;
const bool isA8 = !isLCD && !isBW; const bool isA8 = !isLCD && !isBW;
#ifdef SK_USE_COLOR_LUMINANCE
unsigned lumBits = fRec.getLuminanceColor(); unsigned lumBits = fRec.getLuminanceColor();
uint32_t xorMask = 0; uint32_t xorMask = 0;

View File

@ -168,54 +168,3 @@ static void CGDataProviderReleaseData_FromMalloc(void*, const void* data,
sk_free((void*)data); sk_free((void*)data);
} }
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
size_t size = stream->getLength();
void* ptr = sk_malloc_throw(size);
stream->read(ptr, size);
CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size,
CGDataProviderReleaseData_FromMalloc);
if (NULL == data) {
return false;
}
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data);
CGDataProviderRelease(data);
if (NULL == pdf) {
return false;
}
SkAutoPDFRelease releaseMe(pdf);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
if (NULL == page) {
return false;
}
CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
int w = (int)CGRectGetWidth(bounds);
int h = (int)CGRectGetHeight(bounds);
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h);
bitmap.allocPixels();
bitmap.eraseColor(SK_ColorWHITE);
size_t bitsPerComponent;
CGBitmapInfo info;
getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL);
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h,
bitsPerComponent, bitmap.rowBytes(),
cs, info);
CGColorSpaceRelease(cs);
if (ctx) {
CGContextDrawPDFPage(ctx, page);
CGContextRelease(ctx);
}
output->swap(bitmap);
return true;
}

View File

@ -7,11 +7,12 @@
#define COMPONENTS_JSDEBUGGER_H #define COMPONENTS_JSDEBUGGER_H
#include "IJSDebugger.h" #include "IJSDebugger.h"
#include "mozilla/Attributes.h"
namespace mozilla { namespace mozilla {
namespace jsdebugger { namespace jsdebugger {
class JSDebugger : public IJSDebugger class JSDebugger MOZ_FINAL : public IJSDebugger
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS

View File

@ -108,7 +108,7 @@ _newJSDContext(JSRuntime* jsrt,
JS_BeginRequest(jsdc->dumbContext); JS_BeginRequest(jsdc->dumbContext);
JS_SetOptions(jsdc->dumbContext, JS_GetOptions(jsdc->dumbContext)); JS_SetOptions(jsdc->dumbContext, JS_GetOptions(jsdc->dumbContext));
jsdc->glob = JS_NewCompartmentAndGlobalObject(jsdc->dumbContext, &global_class, NULL); jsdc->glob = JS_NewGlobalObject(jsdc->dumbContext, &global_class, NULL);
if( ! jsdc->glob ) if( ! jsdc->glob )
goto label_newJSDContext_failure; goto label_newJSDContext_failure;

View File

@ -98,6 +98,7 @@ case "$target" in
fi fi
dnl set up compilers dnl set up compilers
TOOLCHAIN_PREFIX="$android_toolchain/bin/$android_tool_prefix-"
AS="$android_toolchain"/bin/"$android_tool_prefix"-as AS="$android_toolchain"/bin/"$android_tool_prefix"-as
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++ CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++

View File

@ -736,8 +736,8 @@ OPTIMIZE_JARS_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/optimizeja
CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py) CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(basename $(@F)).pp --target $@) EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp --target $@)
EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(basename $(@F)).pp) EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp)
EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR) EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC) EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC) EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC)

View File

@ -286,7 +286,7 @@ endif
ifndef MOZ_AUTO_DEPS ifndef MOZ_AUTO_DEPS
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)) ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:.$(OBJ_SUFFIX)=.pp)) MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:=.pp))
ifndef NO_GEN_XPT ifndef NO_GEN_XPT
MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp)) MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
endif endif

View File

@ -4208,7 +4208,7 @@ MOZ_ARG_DISABLE_BOOL(md,
fi]) fi])
if test "$_cpp_md_flag"; then if test "$_cpp_md_flag"; then
COMPILER_DEPEND=1 COMPILER_DEPEND=1
_DEPEND_CFLAGS='$(filter-out %/.pp,-MD -MF $(MDDEPDIR)/$(basename $(@F)).pp)' _DEPEND_CFLAGS='$(filter-out %/.pp,-MD -MF $(MDDEPDIR)/$(@F).pp)'
dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
if test "$SOLARIS_SUNPRO_CC"; then if test "$SOLARIS_SUNPRO_CC"; then
_DEPEND_CFLAGS= _DEPEND_CFLAGS=
@ -4539,8 +4539,10 @@ elif test "$OS_ARCH" != "WINNT" -a "$OS_ARCH" != "OS2"; then
fi fi
AC_ARG_ENABLE(threadsafe, AC_ARG_ENABLE(threadsafe,
[ --enable-threadsafe Enable support for multiple threads.], [ --enable-threadsafe Enable support for multiple threads.],
[AC_DEFINE(JS_THREADSAFE)],) [if test "x$enableval" = "xyes"; then
AC_DEFINE(JS_THREADSAFE)
fi],)
if test "$MOZ_DEBUG"; then if test "$MOZ_DEBUG"; then
AC_DEFINE(MOZ_REFLOW_PERF) AC_DEFINE(MOZ_REFLOW_PERF)

View File

@ -822,7 +822,6 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
*/ */
ScopeCoordinate sc; ScopeCoordinate sc;
if (JOF_OPTYPE(pn->getOp()) == JOF_QARG) { if (JOF_OPTYPE(pn->getOp()) == JOF_QARG) {
JS_ASSERT(bce->sc->funIsHeavyweight());
sc.hops = ClonedBlockDepth(bce); sc.hops = ClonedBlockDepth(bce);
sc.slot = bce->sc->bindings.argToSlot(pn->pn_cookie.slot()); sc.slot = bce->sc->bindings.argToSlot(pn->pn_cookie.slot());
} else { } else {

View File

@ -1249,7 +1249,8 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
end = vp + obj->getDenseArrayInitializedLength(); end = vp + obj->getDenseArrayInitializedLength();
goto scan_value_array; goto scan_value_array;
} else { } else {
JS_ASSERT_IF(runtime->gcIncrementalState != NO_INCREMENTAL, JS_ASSERT_IF(runtime->gcMode == JSGC_MODE_INCREMENTAL &&
runtime->gcIncrementalEnabled,
clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS); clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS);
} }
clasp->trace(this, obj); clasp->trace(this, obj);

View File

@ -16,9 +16,6 @@
#include "js/Utility.h" #include "js/Utility.h"
#ifdef __cplusplus
namespace js { namespace js {
namespace gc { namespace gc {
struct Cell; struct Cell;

View File

@ -236,6 +236,13 @@ class StatisticsSerializer
} }
}; };
/*
* If this fails, then you can either delete this assertion and allow all
* larger-numbered reasons to pile up in the last telemetry bucket, or switch
* to GC_REASON_3 and bump the max value.
*/
JS_STATIC_ASSERT(gcreason::NUM_TELEMETRY_REASONS >= gcreason::NUM_REASONS);
static const char * static const char *
ExplainReason(gcreason::Reason reason) ExplainReason(gcreason::Reason reason)
{ {

View File

@ -0,0 +1,12 @@
function f( ) {
var [ [x], e ] = ["*", "/", "%"];
function h() {
for (var i = 0; i < 5; ++i) {
x = i * 2;
}
}
h();
assertEq(x, 8);
}
f();

View File

@ -0,0 +1,14 @@
function gen()
{
var local = new Date();
yield 1;
local = null;
gc();
gcslice(0);
yield 2;
}
var g = gen();
g.next();
g.next();
gcslice();

View File

@ -0,0 +1,7 @@
function loop(actual = 0) {
if (function() { actual++ })
{}
return actual;
}
assertEq(loop(), 0);

View File

@ -7,9 +7,6 @@ load(libdir + "asserts.js");
var dbg = new Debugger; var dbg = new Debugger;
assertThrowsInstanceOf(function () { dbg.addDebuggee(this); }, TypeError); assertThrowsInstanceOf(function () { dbg.addDebuggee(this); }, TypeError);
assertThrowsInstanceOf(function () { new Debugger(this); }, TypeError); assertThrowsInstanceOf(function () { new Debugger(this); }, TypeError);
var g = newGlobal('same-compartment');
assertThrowsInstanceOf(function () { dbg.addDebuggee(g); }, TypeError);
assertThrowsInstanceOf(function () { new Debugger(g); }, TypeError);
// cycles of length 2 // cycles of length 2
var d1 = newGlobal('new-compartment'); var d1 = newGlobal('new-compartment');

View File

@ -61,4 +61,3 @@ test("Object.create(null, {x: {value: 3}, y: {get: Math.min}})");
test("[]"); test("[]");
test("[,,,,,]"); test("[,,,,,]");
test("[0, 1, 2]"); test("[0, 1, 2]");
test("newGlobal('same-compartment')");

View File

@ -32,8 +32,8 @@ for (var i = 0; i < N; i++) {
var obj = xarr[i]; var obj = xarr[i];
for (j = 0; j < M; j++) { for (j = 0; j < M; j++) {
assertEq(obj instanceof Debugger.Object, true); assertEq(obj instanceof Debugger.Object, true);
g2arr[i].eval("x = x.__proto__ = {};"); g2arr[i].eval("x = x.prop = {};");
obj = obj.proto; obj = obj.getOwnPropertyDescriptor("prop").value;;
assertEq("seen" in obj, false); assertEq("seen" in obj, false);
obj.seen = true; obj.seen = true;
gc(); gc();

View File

@ -63,9 +63,9 @@ BEGIN_TEST(testBug604087)
{ {
JSObject *outerObj = js::Wrapper::New(cx, global, global->getProto(), global, JSObject *outerObj = js::Wrapper::New(cx, global, global->getProto(), global,
&OuterWrapper::singleton); &OuterWrapper::singleton);
JSObject *compartment2 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL); JSObject *compartment2 = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
JSObject *compartment3 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL); JSObject *compartment3 = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
JSObject *compartment4 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL); JSObject *compartment4 = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
JSObject *c2wrapper = wrap(cx, outerObj, compartment2); JSObject *c2wrapper = wrap(cx, outerObj, compartment2);
CHECK(c2wrapper); CHECK(c2wrapper);

View File

@ -35,7 +35,7 @@ CustomMethod(JSContext *cx, unsigned argc, Value *vp)
BEGIN_TEST(test_CallNonGenericMethodOnProxy) BEGIN_TEST(test_CallNonGenericMethodOnProxy)
{ {
// Create the first global object and compartment // Create the first global object and compartment
JSObject *globalA = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL); JSObject *globalA = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
CHECK(globalA); CHECK(globalA);
JSObject *customA = JS_NewObject(cx, &CustomClass, NULL, NULL); JSObject *customA = JS_NewObject(cx, &CustomClass, NULL, NULL);
@ -51,7 +51,7 @@ BEGIN_TEST(test_CallNonGenericMethodOnProxy)
// Now create the second global object and compartment... // Now create the second global object and compartment...
{ {
JSObject *globalB = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL); JSObject *globalB = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
CHECK(globalB); CHECK(globalB);
// ...and enter it. // ...and enter it.

View File

@ -49,7 +49,7 @@ BEGIN_TEST(testChromeBuffer)
JSFunction *fun; JSFunction *fun;
JSObject *o; JSObject *o;
CHECK(o = JS_NewCompartmentAndGlobalObject(cx, &global_class, &system_principals)); CHECK(o = JS_NewGlobalObject(cx, &global_class, &system_principals));
trusted_glob.set(o); trusted_glob.set(o);
/* /*

View File

@ -150,7 +150,7 @@ END_TEST(testDebugger_throwHook)
BEGIN_TEST(testDebugger_debuggerObjectVsDebugMode) BEGIN_TEST(testDebugger_debuggerObjectVsDebugMode)
{ {
CHECK(JS_DefineDebuggerObject(cx, global)); CHECK(JS_DefineDebuggerObject(cx, global));
JSObject *debuggee = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL); JSObject *debuggee = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
CHECK(debuggee); CHECK(debuggee);
{ {
@ -192,51 +192,36 @@ BEGIN_TEST(testDebugger_newScriptHook)
{ {
// Test that top-level indirect eval fires the newScript hook. // Test that top-level indirect eval fires the newScript hook.
CHECK(JS_DefineDebuggerObject(cx, global)); CHECK(JS_DefineDebuggerObject(cx, global));
JSObject *g1, *g2; JSObject *g;
g1 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL); g = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
CHECK(g1); CHECK(g);
{ {
JSAutoEnterCompartment ae; JSAutoEnterCompartment ae;
CHECK(ae.enter(cx, g1)); CHECK(ae.enter(cx, g));
CHECK(JS_InitStandardClasses(cx, g1)); CHECK(JS_InitStandardClasses(cx, g));
g2 = JS_NewGlobalObject(cx, getGlobalClass());
CHECK(g2);
CHECK(JS_InitStandardClasses(cx, g2));
} }
JSObject *g1Wrapper = g1; JSObject *gWrapper = g;
CHECK(JS_WrapObject(cx, &g1Wrapper)); CHECK(JS_WrapObject(cx, &gWrapper));
jsval v = OBJECT_TO_JSVAL(g1Wrapper); jsval v = OBJECT_TO_JSVAL(gWrapper);
CHECK(JS_SetProperty(cx, global, "g1", &v)); CHECK(JS_SetProperty(cx, global, "g", &v));
JSObject *g2Wrapper = g2; EXEC("var dbg = Debugger(g);\n"
CHECK(JS_WrapObject(cx, &g2Wrapper));
v = OBJECT_TO_JSVAL(g2Wrapper);
CHECK(JS_SetProperty(cx, global, "g2", &v));
EXEC("var dbg = Debugger(g1);\n"
"var hits = 0;\n" "var hits = 0;\n"
"dbg.onNewScript = function (s) {\n" "dbg.onNewScript = function (s) {\n"
" hits += Number(s instanceof Debugger.Script);\n" " hits += Number(s instanceof Debugger.Script);\n"
"};\n"); "};\n");
// Since g1 is a debuggee and g2 is not, g1.eval should trigger newScript // Since g is a debuggee, g.eval should trigger newScript, regardless of
// and g2.eval should not, regardless of what scope object we use to enter // what scope object we use to enter the compartment.
// the compartment.
// //
// (Not all scripts are permanently associated with specific global // Scripts are associated with the global where they're compiled, so we
// objects, but eval scripts are, so we deliver them only to debuggers that // deliver them only to debuggers that are watching that particular global.
// are watching that particular global.)
// //
bool ok = true; return testIndirectEval(g, "Math.abs(0)");
ok = ok && testIndirectEval(g1, g1, "Math.abs(0)", 1);
ok = ok && testIndirectEval(g2, g1, "Math.abs(1)", 1);
ok = ok && testIndirectEval(g1, g2, "Math.abs(-1)", 0);
ok = ok && testIndirectEval(g2, g2, "Math.abs(-2)", 0);
return ok;
} }
bool testIndirectEval(JSObject *scope, JSObject *g, const char *code, int expectedHits) bool testIndirectEval(JSObject *scope, const char *code)
{ {
EXEC("hits = 0;"); EXEC("hits = 0;");
@ -247,12 +232,12 @@ bool testIndirectEval(JSObject *scope, JSObject *g, const char *code, int expect
CHECK(codestr); CHECK(codestr);
jsval argv[1] = { STRING_TO_JSVAL(codestr) }; jsval argv[1] = { STRING_TO_JSVAL(codestr) };
jsval v; jsval v;
CHECK(JS_CallFunctionName(cx, g, "eval", 1, argv, &v)); CHECK(JS_CallFunctionName(cx, scope, "eval", 1, argv, &v));
} }
jsval hitsv; jsval hitsv;
EVAL("hits", &hitsv); EVAL("hits", &hitsv);
CHECK_SAME(hitsv, INT_TO_JSVAL(expectedHits)); CHECK_SAME(hitsv, INT_TO_JSVAL(1));
return true; return true;
} }
END_TEST(testDebugger_newScriptHook) END_TEST(testDebugger_newScriptHook)

View File

@ -354,7 +354,7 @@ class JSAPITest
virtual JSObject * createGlobal(JSPrincipals *principals = NULL) { virtual JSObject * createGlobal(JSPrincipals *principals = NULL) {
/* Create the global object. */ /* Create the global object. */
JSObject *global = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), principals); JSObject *global = JS_NewGlobalObject(cx, getGlobalClass(), principals);
if (!global) if (!global)
return NULL; return NULL;

View File

@ -751,6 +751,7 @@ JSRuntime::JSRuntime()
gcZealFrequency(0), gcZealFrequency(0),
gcNextScheduled(0), gcNextScheduled(0),
gcDeterministicOnly(false), gcDeterministicOnly(false),
gcIncrementalLimit(0),
#endif #endif
gcCallback(NULL), gcCallback(NULL),
gcSliceCallback(NULL), gcSliceCallback(NULL),
@ -1404,14 +1405,8 @@ JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target)
{ {
AssertNoGC(cx); AssertNoGC(cx);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
GlobalObject *global = target->getGlobalObjectOrNull(); GlobalObject &global = target->compartment()->global();
if (!global) { return JS_EnterCrossCompartmentCall(cx, &global);
SwitchToCompartment sc(cx, target->compartment());
global = GlobalObject::create(cx, &dummy_class);
if (!global)
return NULL;
}
return JS_EnterCrossCompartmentCall(cx, global);
} }
JS_PUBLIC_API(JSCrossCompartmentCall *) JS_PUBLIC_API(JSCrossCompartmentCall *)
@ -3317,16 +3312,6 @@ JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
return JS_TRUE; return JS_TRUE;
} }
JS_PUBLIC_API(JSObject *)
JS_NewGlobalObject(JSContext *cx, JSClass *clasp)
{
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
AssertNoGC(cx);
CHECK_REQUEST(cx);
return GlobalObject::create(cx, Valueify(clasp));
}
class AutoHoldCompartment { class AutoHoldCompartment {
public: public:
explicit AutoHoldCompartment(JSCompartment *compartment JS_GUARD_OBJECT_NOTIFIER_PARAM) explicit AutoHoldCompartment(JSCompartment *compartment JS_GUARD_OBJECT_NOTIFIER_PARAM)
@ -3345,10 +3330,12 @@ class AutoHoldCompartment {
}; };
JS_PUBLIC_API(JSObject *) JS_PUBLIC_API(JSObject *)
JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals) JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals)
{ {
AssertNoGC(cx); AssertNoGC(cx);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
JSCompartment *compartment = NewCompartment(cx, principals); JSCompartment *compartment = NewCompartment(cx, principals);
if (!compartment) if (!compartment)
return NULL; return NULL;
@ -3357,10 +3344,10 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *pr
JSCompartment *saved = cx->compartment; JSCompartment *saved = cx->compartment;
cx->setCompartment(compartment); cx->setCompartment(compartment);
JSObject *obj = JS_NewGlobalObject(cx, clasp); GlobalObject *global = GlobalObject::create(cx, Valueify(clasp));
cx->setCompartment(saved); cx->setCompartment(saved);
return obj; return global;
} }
JS_PUBLIC_API(JSObject *) JS_PUBLIC_API(JSObject *)
@ -6693,7 +6680,10 @@ JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency)
" 4: Verify write barriers between instructions\n" " 4: Verify write barriers between instructions\n"
" 5: Verify write barriers between paints\n" " 5: Verify write barriers between paints\n"
" 6: Verify stack rooting (ignoring XML and Reflect)\n" " 6: Verify stack rooting (ignoring XML and Reflect)\n"
" 7: Verify stack rooting (all roots)\n"); " 7: Verify stack rooting (all roots)\n"
" 8: Incremental GC in two slices: 1) mark roots 2) finish collection\n"
" 9: Incremental GC in two slices: 1) mark all 2) new marking and finish\n"
" 10: Incremental GC in multiple slices\n");
} }
const char *p = strchr(env, ','); const char *p = strchr(env, ',');
zeal = atoi(env); zeal = atoi(env);

View File

@ -3935,10 +3935,7 @@ extern JS_PUBLIC_API(JSBool)
JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp); JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp);
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
JS_NewGlobalObject(JSContext *cx, JSClass *clasp); JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals);
extern JS_PUBLIC_API(JSObject *)
JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals);
extern JS_PUBLIC_API(JSObject *) extern JS_PUBLIC_API(JSObject *)
JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);

View File

@ -591,8 +591,9 @@ struct JSRuntime : js::RuntimeFriendFields
* gcNextScheduled is decremented. When it reaches zero, we do either a * gcNextScheduled is decremented. When it reaches zero, we do either a
* full or a compartmental GC, based on gcDebugCompartmentGC. * full or a compartmental GC, based on gcDebugCompartmentGC.
* *
* At this point, if gcZeal_ == 2 then gcNextScheduled is reset to the * At this point, if gcZeal_ is one of the types that trigger periodic
* value of gcZealFrequency. Otherwise, no additional GCs take place. * collection, then gcNextScheduled is reset to the value of
* gcZealFrequency. Otherwise, no additional GCs take place.
* *
* You can control these values in several ways: * You can control these values in several ways:
* - Pass the -Z flag to the shell (see the usage info for details) * - Pass the -Z flag to the shell (see the usage info for details)
@ -604,12 +605,16 @@ struct JSRuntime : js::RuntimeFriendFields
* *
* We use gcZeal_ == 4 to enable write barrier verification. See the comment * We use gcZeal_ == 4 to enable write barrier verification. See the comment
* in jsgc.cpp for more information about this. * in jsgc.cpp for more information about this.
*
* gcZeal_ values from 8 to 10 periodically run different types of
* incremental GC.
*/ */
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
int gcZeal_; int gcZeal_;
int gcZealFrequency; int gcZealFrequency;
int gcNextScheduled; int gcNextScheduled;
bool gcDeterministicOnly; bool gcDeterministicOnly;
int gcIncrementalLimit;
js::Vector<JSObject *, 0, js::SystemAllocPolicy> gcSelectedForMarking; js::Vector<JSObject *, 0, js::SystemAllocPolicy> gcSelectedForMarking;
@ -617,8 +622,12 @@ struct JSRuntime : js::RuntimeFriendFields
bool needZealousGC() { bool needZealousGC() {
if (gcNextScheduled > 0 && --gcNextScheduled == 0) { if (gcNextScheduled > 0 && --gcNextScheduled == 0) {
if (gcZeal() == js::gc::ZealAllocValue) if (gcZeal() == js::gc::ZealAllocValue ||
(gcZeal() >= js::gc::ZealIncrementalRootsThenFinish &&
gcZeal() <= js::gc::ZealIncrementalMultipleSlices))
{
gcNextScheduled = gcZealFrequency; gcNextScheduled = gcZealFrequency;
}
return true; return true;
} }
return false; return false;

View File

@ -224,8 +224,13 @@ class CompartmentChecker
JSCompartment *compartment; JSCompartment *compartment;
public: public:
explicit CompartmentChecker(JSContext *cx) : context(cx), compartment(cx->compartment) { explicit CompartmentChecker(JSContext *cx)
check(cx->hasfp() ? JS_GetGlobalForScopeChain(cx) : cx->globalObject); : context(cx), compartment(cx->compartment)
{
if (cx->compartment) {
GlobalObject *global = GetGlobalForScopeChain(cx);
JS_ASSERT(cx->compartment->global() == *global);
}
} }
/* /*

View File

@ -42,12 +42,14 @@ using namespace js::gc;
JSCompartment::JSCompartment(JSRuntime *rt) JSCompartment::JSCompartment(JSRuntime *rt)
: rt(rt), : rt(rt),
principals(NULL), principals(NULL),
global_(NULL),
needsBarrier_(false), needsBarrier_(false),
gcState(NoGCScheduled), gcState(NoGCScheduled),
gcPreserveCode(false), gcPreserveCode(false),
gcBytes(0), gcBytes(0),
gcTriggerBytes(0), gcTriggerBytes(0),
hold(false), hold(false),
isSystemCompartment(false),
lastCodeRelease(0), lastCodeRelease(0),
typeLifoAlloc(TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), typeLifoAlloc(TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
data(NULL), data(NULL),

View File

@ -122,6 +122,20 @@ struct JSCompartment
JSRuntime *rt; JSRuntime *rt;
JSPrincipals *principals; JSPrincipals *principals;
private:
js::GlobalObject *global_;
public:
js::GlobalObject &global() const {
JS_ASSERT(global_->compartment() == this);
return *global_;
}
void initGlobal(js::GlobalObject &global) {
JS_ASSERT(!global_);
global_ = &global;
}
public:
js::gc::ArenaLists arenas; js::gc::ArenaLists arenas;
private: private:

View File

@ -603,7 +603,15 @@ enum Reason {
GCREASONS(MAKE_REASON) GCREASONS(MAKE_REASON)
#undef MAKE_REASON #undef MAKE_REASON
NO_REASON, NO_REASON,
NUM_REASONS NUM_REASONS,
/*
* For telemetry, we want to keep a fixed max bucket size over time so we
* don't have to switch histograms. 100 is conservative; as of this writing
* there are 26. But the cost of extra buckets seems to be low while the
* cost of switching histograms is high.
*/
NUM_TELEMETRY_REASONS = 100
}; };
} /* namespace gcreason */ } /* namespace gcreason */

View File

@ -3487,19 +3487,6 @@ SweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool *startBackgroundSweep)
c->setGCLastBytes(c->gcBytes, c->gcMallocAndFreeBytes, gckind); c->setGCLastBytes(c->gcBytes, c->gcMallocAndFreeBytes, gckind);
} }
static void
NonIncrementalMark(JSRuntime *rt, JSGCInvocationKind gckind)
{
JS_ASSERT(rt->gcIncrementalState == NO_INCREMENTAL);
BeginMarkPhase(rt);
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK);
SliceBudget budget;
rt->gcMarker.drainMarkStack(budget);
}
EndMarkPhase(rt);
}
/* /*
* This class should be used by any code that needs to exclusive access to the * This class should be used by any code that needs to exclusive access to the
* heap in order to trace through it... * heap in order to trace through it...
@ -3654,12 +3641,23 @@ class AutoCopyFreeListToArenas {
}; };
static void static void
IncrementalMarkSlice(JSRuntime *rt, int64_t budget, JSGCInvocationKind gckind, bool *shouldSweep) IncrementalMarkSlice(JSRuntime *rt, int64_t budget, gcreason::Reason reason, bool *shouldSweep)
{ {
AutoGCSlice slice(rt); AutoGCSlice slice(rt);
gc::State initialState = rt->gcIncrementalState; gc::State initialState = rt->gcIncrementalState;
*shouldSweep = false;
int zeal = 0;
#ifdef JS_GC_ZEAL
if (reason == gcreason::DEBUG_GC) {
// Do the collection type specified by zeal mode only if the collection
// was triggered by RunDebugGC().
zeal = rt->gcZeal();
}
#endif
if (rt->gcIncrementalState == NO_INCREMENTAL) { if (rt->gcIncrementalState == NO_INCREMENTAL) {
rt->gcIncrementalState = MARK_ROOTS; rt->gcIncrementalState = MARK_ROOTS;
rt->gcLastMarkSlice = false; rt->gcLastMarkSlice = false;
@ -3668,9 +3666,11 @@ IncrementalMarkSlice(JSRuntime *rt, int64_t budget, JSGCInvocationKind gckind, b
if (rt->gcIncrementalState == MARK_ROOTS) { if (rt->gcIncrementalState == MARK_ROOTS) {
BeginMarkPhase(rt); BeginMarkPhase(rt);
rt->gcIncrementalState = MARK; rt->gcIncrementalState = MARK;
if (zeal == ZealIncrementalRootsThenFinish)
return;
} }
*shouldSweep = false;
if (rt->gcIncrementalState == MARK) { if (rt->gcIncrementalState == MARK) {
SliceBudget sliceBudget(budget); SliceBudget sliceBudget(budget);
@ -3695,7 +3695,11 @@ IncrementalMarkSlice(JSRuntime *rt, int64_t budget, JSGCInvocationKind gckind, b
} }
if (finished) { if (finished) {
JS_ASSERT(rt->gcMarker.isDrained()); JS_ASSERT(rt->gcMarker.isDrained());
if (initialState == MARK && !rt->gcLastMarkSlice && budget != SliceBudget::Unlimited) {
if (!rt->gcLastMarkSlice &&
((initialState == MARK && budget != SliceBudget::Unlimited) ||
zeal == ZealIncrementalMarkAllThenFinish))
{
rt->gcLastMarkSlice = true; rt->gcLastMarkSlice = true;
} else { } else {
EndMarkPhase(rt); EndMarkPhase(rt);
@ -3796,7 +3800,7 @@ BudgetIncrementalGC(JSRuntime *rt, int64_t *budget)
* the marking implementation. * the marking implementation.
*/ */
static JS_NEVER_INLINE void static JS_NEVER_INLINE void
GCCycle(JSRuntime *rt, bool incremental, int64_t budget, JSGCInvocationKind gckind) GCCycle(JSRuntime *rt, bool incremental, int64_t budget, JSGCInvocationKind gckind, gcreason::Reason reason)
{ {
#ifdef DEBUG #ifdef DEBUG
for (CompartmentsIter c(rt); !c.done(); c.next()) for (CompartmentsIter c(rt); !c.done(); c.next())
@ -3834,17 +3838,13 @@ GCCycle(JSRuntime *rt, bool incremental, int64_t budget, JSGCInvocationKind gcki
/* If non-incremental GC was requested, reset incremental GC. */ /* If non-incremental GC was requested, reset incremental GC. */
ResetIncrementalGC(rt, "requested"); ResetIncrementalGC(rt, "requested");
rt->gcStats.nonincremental("requested"); rt->gcStats.nonincremental("requested");
budget = SliceBudget::Unlimited;
} else { } else {
BudgetIncrementalGC(rt, &budget); BudgetIncrementalGC(rt, &budget);
} }
bool shouldSweep; bool shouldSweep;
if (budget == SliceBudget::Unlimited && rt->gcIncrementalState == NO_INCREMENTAL) { IncrementalMarkSlice(rt, budget, reason, &shouldSweep);
NonIncrementalMark(rt, gckind);
shouldSweep = true;
} else {
IncrementalMarkSlice(rt, budget, gckind, &shouldSweep);
}
#ifdef DEBUG #ifdef DEBUG
if (rt->gcIncrementalState == NO_INCREMENTAL) { if (rt->gcIncrementalState == NO_INCREMENTAL) {
@ -3903,7 +3903,8 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget,
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
bool restartVerify = rt->gcVerifyData && bool restartVerify = rt->gcVerifyData &&
rt->gcZeal() == ZealVerifierValue && rt->gcZeal() == ZealVerifierValue &&
reason != gcreason::CC_FORCED; reason != gcreason::CC_FORCED &&
rt->hasContexts();
struct AutoVerifyBarriers { struct AutoVerifyBarriers {
JSRuntime *runtime; JSRuntime *runtime;
@ -3954,7 +3955,7 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget,
} }
rt->gcPoke = false; rt->gcPoke = false;
GCCycle(rt, incremental, budget, gckind); GCCycle(rt, incremental, budget, gckind, reason);
if (rt->gcIncrementalState == NO_INCREMENTAL) { if (rt->gcIncrementalState == NO_INCREMENTAL) {
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_GC_END); gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_GC_END);
@ -4186,8 +4187,32 @@ void
RunDebugGC(JSContext *cx) RunDebugGC(JSContext *cx)
{ {
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
JSRuntime *rt = cx->runtime;
PrepareForDebugGC(cx->runtime); PrepareForDebugGC(cx->runtime);
RunLastDitchGC(cx, gcreason::DEBUG_GC);
int type = rt->gcZeal();
if (type == ZealIncrementalRootsThenFinish ||
type == ZealIncrementalMarkAllThenFinish ||
type == ZealIncrementalMultipleSlices)
{
int64_t budget;
if (type == ZealIncrementalMultipleSlices) {
// Start with a small slice limit and double it every slice. This ensure that we get
// multiple slices, and collection runs to completion.
if (rt->gcIncrementalState == NO_INCREMENTAL)
rt->gcIncrementalLimit = rt->gcZealFrequency / 2;
else
rt->gcIncrementalLimit *= 2;
budget = SliceBudget::WorkBudget(rt->gcIncrementalLimit);
} else {
// This triggers incremental GC but is actually ignored by IncrementalMarkSlice.
budget = SliceBudget::Unlimited;
}
Collect(rt, true, budget, GC_NORMAL, gcreason::DEBUG_GC);
} else {
Collect(rt, false, SliceBudget::Unlimited, GC_NORMAL, gcreason::DEBUG_GC);
}
#endif #endif
} }

View File

@ -1081,6 +1081,9 @@ const int ZealVerifierValue = 4;
const int ZealFrameVerifierValue = 5; const int ZealFrameVerifierValue = 5;
const int ZealStackRootingSafeValue = 6; const int ZealStackRootingSafeValue = 6;
const int ZealStackRootingValue = 7; const int ZealStackRootingValue = 7;
const int ZealIncrementalRootsThenFinish = 8;
const int ZealIncrementalMarkAllThenFinish = 9;
const int ZealIncrementalMultipleSlices = 10;
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL

View File

@ -1434,6 +1434,7 @@ JSScript::ensureHasTypes(JSContext *cx)
inline bool inline bool
JSScript::ensureRanAnalysis(JSContext *cx, JSObject *scope) JSScript::ensureRanAnalysis(JSContext *cx, JSObject *scope)
{ {
js::analyze::AutoEnterAnalysis aea(cx->compartment);
JSScript *self = this; JSScript *self = this;
JS::SkipRoot root(cx, &self); JS::SkipRoot root(cx, &self);

View File

@ -1366,8 +1366,8 @@ GeneratorWriteBarrierPre(JSContext *cx, JSGenerator *gen)
* stack or closed. Barriers when copying onto the stack or closing preserve * stack or closed. Barriers when copying onto the stack or closing preserve
* gc invariants. * gc invariants.
*/ */
static bool bool
GeneratorHasMarkableFrame(JSGenerator *gen) js::GeneratorHasMarkableFrame(JSGenerator *gen)
{ {
return gen->state == JSGEN_NEWBORN || gen->state == JSGEN_OPEN; return gen->state == JSGEN_NEWBORN || gen->state == JSGEN_OPEN;
} }
@ -1476,8 +1476,8 @@ js_NewGenerator(JSContext *cx)
/* Copy from the stack to the generator's floating frame. */ /* Copy from the stack to the generator's floating frame. */
gen->regs.rebaseFromTo(stackRegs, *genfp); gen->regs.rebaseFromTo(stackRegs, *genfp);
genfp->copyFrameAndValues<HeapValue, Value, StackFrame::DoPostBarrier>( genfp->copyFrameAndValues<StackFrame::DoPostBarrier>(cx, (Value *)genvp, stackfp,
cx, genvp, stackfp, stackvp, stackRegs.sp); stackvp, stackRegs.sp);
obj->setPrivate(gen); obj->setPrivate(gen);
return obj; return obj;

View File

@ -1,4 +1,4 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=78: * vim: set ts=8 sw=4 et tw=78:
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
@ -316,6 +316,13 @@ struct JSGenerator
extern JSObject * extern JSObject *
js_NewGenerator(JSContext *cx); js_NewGenerator(JSContext *cx);
namespace js {
bool
GeneratorHasMarkableFrame(JSGenerator *gen);
} /* namespace js */
#endif #endif
extern JSObject * extern JSObject *

View File

@ -2802,6 +2802,7 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
JS_ASSERT(clasp != &ArrayClass); JS_ASSERT(clasp != &ArrayClass);
JS_ASSERT_IF(clasp == &FunctionClass, JS_ASSERT_IF(clasp == &FunctionClass,
kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind); kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind);
JS_ASSERT_IF(parent, parent->global() == cx->compartment->global());
RootedTypeObject type(cx, type_); RootedTypeObject type(cx, type_);
@ -2815,8 +2816,10 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
return NULL; return NULL;
JSObject *obj = JSObject::create(cx, kind, shape, type, slots); JSObject *obj = JSObject::create(cx, kind, shape, type, slots);
if (!obj) if (!obj) {
cx->free_(slots);
return NULL; return NULL;
}
/* /*
* This will cancel an already-running incremental GC from doing any more * This will cancel an already-running incremental GC from doing any more

View File

@ -1223,6 +1223,7 @@ JSObject::global() const
JSObject *obj = const_cast<JSObject *>(this); JSObject *obj = const_cast<JSObject *>(this);
while (JSObject *parent = obj->getParent()) while (JSObject *parent = obj->getParent())
obj = parent; obj = parent;
JS_ASSERT(obj->asGlobal() == compartment()->global());
return obj->asGlobal(); return obj->asGlobal();
} }

View File

@ -2559,7 +2559,7 @@ static JSClass sandbox_class = {
static JSObject * static JSObject *
NewSandbox(JSContext *cx, bool lazy) NewSandbox(JSContext *cx, bool lazy)
{ {
RootedObject obj(cx, JS_NewCompartmentAndGlobalObject(cx, &sandbox_class, NULL)); RootedObject obj(cx, JS_NewGlobalObject(cx, &sandbox_class, NULL));
if (!obj) if (!obj)
return NULL; return NULL;
@ -3230,24 +3230,11 @@ Compile(JSContext *cx, unsigned argc, jsval *vp)
return false; return false;
} }
static JSClass dummy_class = { JSObject *global = JS_GetGlobalForScopeChain(cx);
"jdummy",
JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub
};
JSObject *fakeGlobal = JS_NewGlobalObject(cx, &dummy_class);
if (!fakeGlobal)
return false;
JSString *scriptContents = JSVAL_TO_STRING(arg0); JSString *scriptContents = JSVAL_TO_STRING(arg0);
unsigned oldopts = JS_GetOptions(cx); unsigned oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL); JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
bool ok = JS_CompileUCScript(cx, fakeGlobal, JS_GetStringCharsZ(cx, scriptContents), bool ok = JS_CompileUCScript(cx, global, JS_GetStringCharsZ(cx, scriptContents),
JS_GetStringLength(scriptContents), "<string>", 1); JS_GetStringLength(scriptContents), "<string>", 1);
JS_SetOptions(cx, oldopts); JS_SetOptions(cx, oldopts);
@ -3425,33 +3412,13 @@ Deserialize(JSContext *cx, unsigned argc, jsval *vp)
return true; return true;
} }
enum CompartmentKind { SAME_COMPARTMENT, NEW_COMPARTMENT };
static JSObject * static JSObject *
NewGlobalObject(JSContext *cx, CompartmentKind compartment); NewGlobalObject(JSContext *cx);
static JSBool static JSBool
NewGlobal(JSContext *cx, unsigned argc, jsval *vp) NewGlobal(JSContext *cx, unsigned argc, jsval *vp)
{ {
if (argc != 1 || !JSVAL_IS_STRING(JS_ARGV(cx, vp)[0])) { JSObject *global = NewGlobalObject(cx);
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "newGlobal");
return false;
}
JSString *str = JSVAL_TO_STRING(JS_ARGV(cx, vp)[0]);
JSBool equalSame = false, equalNew = false;
if (!JS_StringEqualsAscii(cx, str, "same-compartment", &equalSame) ||
!JS_StringEqualsAscii(cx, str, "new-compartment", &equalNew)) {
return false;
}
if (!equalSame && !equalNew) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "newGlobal");
return false;
}
JSObject *global = NewGlobalObject(cx, equalSame ? SAME_COMPARTMENT : NEW_COMPARTMENT);
if (!global) if (!global)
return false; return false;
@ -4589,13 +4556,9 @@ DestroyContext(JSContext *cx, bool withGC)
} }
static JSObject * static JSObject *
NewGlobalObject(JSContext *cx, CompartmentKind compartment) NewGlobalObject(JSContext *cx)
{ {
RootedObject glob(cx); RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, NULL));
glob = (compartment == NEW_COMPARTMENT)
? JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL)
: JS_NewGlobalObject(cx, &global_class);
if (!glob) if (!glob)
return NULL; return NULL;
@ -4640,7 +4603,7 @@ NewGlobalObject(JSContext *cx, CompartmentKind compartment)
return NULL; return NULL;
} }
if (compartment == NEW_COMPARTMENT && !JS_WrapObject(cx, glob.address())) if (!JS_WrapObject(cx, glob.address()))
return NULL; return NULL;
return glob; return glob;
@ -4846,7 +4809,7 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
} }
RootedObject glob(cx); RootedObject glob(cx);
glob = NewGlobalObject(cx, NEW_COMPARTMENT); glob = NewGlobalObject(cx);
if (!glob) if (!glob)
return 1; return 1;
@ -4865,7 +4828,7 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
class ShellWorkerHooks : public js::workers::WorkerHooks { class ShellWorkerHooks : public js::workers::WorkerHooks {
public: public:
JSObject *newGlobalObject(JSContext *cx) { JSObject *newGlobalObject(JSContext *cx) {
return NewGlobalObject(cx, NEW_COMPARTMENT); return NewGlobalObject(cx);
} }
}; };
ShellWorkerHooks hooks; ShellWorkerHooks hooks;

View File

@ -242,26 +242,27 @@ GlobalObject::create(JSContext *cx, Class *clasp)
{ {
JS_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL); JS_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
Rooted<GlobalObject*> obj(cx); JSObject *obj = NewObjectWithGivenProto(cx, clasp, NULL, NULL);
if (!obj)
JSObject *obj_ = NewObjectWithGivenProto(cx, clasp, NULL, NULL);
if (!obj_)
return NULL; return NULL;
obj = &obj_->asGlobal();
if (!obj->setSingletonType(cx) || !obj->setVarObj(cx)) Rooted<GlobalObject *> global(cx, &obj->asGlobal());
cx->compartment->initGlobal(*global);
if (!global->setSingletonType(cx) || !global->setVarObj(cx))
return NULL; return NULL;
if (!obj->setDelegate(cx)) if (!obj->setDelegate(cx))
return NULL; return NULL;
/* Construct a regexp statics object for this global object. */ /* Construct a regexp statics object for this global object. */
JSObject *res = RegExpStatics::create(cx, obj); JSObject *res = RegExpStatics::create(cx, global);
if (!res) if (!res)
return NULL; return NULL;
obj->initSlot(REGEXP_STATICS, ObjectValue(*res)); global->initSlot(REGEXP_STATICS, ObjectValue(*res));
obj->initFlags(0); global->initFlags(0);
return obj; return global;
} }
/* static */ bool /* static */ bool

View File

@ -97,30 +97,37 @@ StackFrame::initDummyFrame(JSContext *cx, JSObject &chain)
scopeChain_ = &chain; scopeChain_ = &chain;
} }
template <class T, class U, StackFrame::TriggerPostBarriers doPostBarrier> template <StackFrame::TriggerPostBarriers doPostBarrier>
void void
StackFrame::copyFrameAndValues(JSContext *cx, T *vp, StackFrame *otherfp, U *othervp, Value *othersp) StackFrame::copyFrameAndValues(JSContext *cx, Value *vp, StackFrame *otherfp,
const Value *othervp, Value *othersp)
{ {
JS_ASSERT((U *)vp == (U *)this - ((U *)otherfp - othervp)); JS_ASSERT(vp == (Value *)this - ((Value *)otherfp - othervp));
JS_ASSERT((Value *)othervp == otherfp->generatorArgsSnapshotBegin()); JS_ASSERT(othervp == otherfp->generatorArgsSnapshotBegin());
JS_ASSERT(othersp >= otherfp->slots()); JS_ASSERT(othersp >= otherfp->slots());
JS_ASSERT(othersp <= otherfp->generatorSlotsSnapshotBegin() + otherfp->script()->nslots); JS_ASSERT(othersp <= otherfp->generatorSlotsSnapshotBegin() + otherfp->script()->nslots);
JS_ASSERT((T *)this - vp == (U *)otherfp - othervp); JS_ASSERT((Value *)this - vp == (Value *)otherfp - othervp);
/* Copy args, StackFrame, and slots. */ /* Copy args, StackFrame, and slots. */
U *srcend = (U *)otherfp->generatorArgsSnapshotEnd(); const Value *srcend = otherfp->generatorArgsSnapshotEnd();
T *dst = vp; Value *dst = vp;
for (U *src = othervp; src < srcend; src++, dst++) for (const Value *src = othervp; src < srcend; src++, dst++) {
*dst = *src; *dst = *src;
if (doPostBarrier)
HeapValue::writeBarrierPost(*dst, dst);
}
*this = *otherfp; *this = *otherfp;
if (doPostBarrier) if (doPostBarrier)
writeBarrierPost(); writeBarrierPost();
srcend = (U *)othersp; srcend = othersp;
dst = (T *)slots(); dst = slots();
for (U *src = (U *)otherfp->slots(); src < srcend; src++, dst++) for (const Value *src = otherfp->slots(); src < srcend; src++, dst++) {
*dst = *src; *dst = *src;
if (doPostBarrier)
HeapValue::writeBarrierPost(*dst, dst);
}
if (cx->compartment->debugMode()) if (cx->compartment->debugMode())
cx->runtime->debugScopes->onGeneratorFrameChange(otherfp, this, cx); cx->runtime->debugScopes->onGeneratorFrameChange(otherfp, this, cx);
@ -128,11 +135,11 @@ StackFrame::copyFrameAndValues(JSContext *cx, T *vp, StackFrame *otherfp, U *oth
/* Note: explicit instantiation for js_NewGenerator located in jsiter.cpp. */ /* Note: explicit instantiation for js_NewGenerator located in jsiter.cpp. */
template template
void StackFrame::copyFrameAndValues<Value, HeapValue, StackFrame::NoPostBarrier>( void StackFrame::copyFrameAndValues<StackFrame::NoPostBarrier>(
JSContext *, Value *, StackFrame *, HeapValue *, Value *); JSContext *, Value *, StackFrame *, const Value *, Value *);
template template
void StackFrame::copyFrameAndValues<HeapValue, Value, StackFrame::DoPostBarrier>( void StackFrame::copyFrameAndValues<StackFrame::DoPostBarrier>(
JSContext *, HeapValue *, StackFrame *, Value *, Value *); JSContext *, Value *, StackFrame *, const Value *, Value *);
void void
StackFrame::writeBarrierPost() StackFrame::writeBarrierPost()
@ -1145,8 +1152,8 @@ ContextStack::pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrame
JSObject::writeBarrierPre(gen->obj); JSObject::writeBarrierPre(gen->obj);
/* Copy from the generator's floating frame to the stack. */ /* Copy from the generator's floating frame to the stack. */
stackfp->copyFrameAndValues<Value, HeapValue, StackFrame::NoPostBarrier>( stackfp->copyFrameAndValues<StackFrame::NoPostBarrier>(cx, stackvp, gen->fp,
cx, stackvp, gen->fp, genvp, gen->regs.sp); Valueify(genvp), gen->regs.sp);
stackfp->resetGeneratorPrev(cx); stackfp->resetGeneratorPrev(cx);
gfg->regs_.rebaseFromTo(gen->regs, *stackfp); gfg->regs_.rebaseFromTo(gen->regs, *stackfp);
@ -1169,9 +1176,15 @@ ContextStack::popGeneratorFrame(const GeneratorFrameGuard &gfg)
/* Copy from the stack to the generator's floating frame. */ /* Copy from the stack to the generator's floating frame. */
if (stackfp->isYielding()) { if (stackfp->isYielding()) {
/*
* Assert that the frame is not markable so that we don't need an
* incremental write barrier when updating the generator's saved slots.
*/
JS_ASSERT(!GeneratorHasMarkableFrame(gen));
gen->regs.rebaseFromTo(stackRegs, *gen->fp); gen->regs.rebaseFromTo(stackRegs, *gen->fp);
gen->fp->copyFrameAndValues<HeapValue, Value, StackFrame::DoPostBarrier>( gen->fp->copyFrameAndValues<StackFrame::DoPostBarrier>(cx_, (Value *)genvp, stackfp,
cx_, genvp, stackfp, stackvp, stackRegs.sp); stackvp, stackRegs.sp);
} }
/* ~FrameGuard/popFrame will finish the popping. */ /* ~FrameGuard/popFrame will finish the popping. */

View File

@ -999,8 +999,9 @@ class StackFrame
DoPostBarrier = true, DoPostBarrier = true,
NoPostBarrier = false NoPostBarrier = false
}; };
template <class T, class U, TriggerPostBarriers doPostBarrier> template <TriggerPostBarriers doPostBarrier>
void copyFrameAndValues(JSContext *cx, T *vp, StackFrame *otherfp, U *othervp, Value *othersp); void copyFrameAndValues(JSContext *cx, Value *vp, StackFrame *otherfp,
const Value *othervp, Value *othersp);
JSGenerator *maybeSuspendedGenerator(JSRuntime *rt); JSGenerator *maybeSuspendedGenerator(JSRuntime *rt);

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