mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-28 03:18:41 +00:00
Merge from mozilla-central.
--HG-- extra : rebase_source : 521cbf2f434cad88106f32be797faae4861afc39
This commit is contained in:
parent
b5f5c1ab01
commit
1222b46c77
@ -266,17 +266,14 @@ let MigratorPrototype = {
|
||||
getService(Ci.nsIObserver);
|
||||
browserGlue.observe(null, TOPIC_WILL_IMPORT_BOOKMARKS, "");
|
||||
|
||||
let bookmarksHTMLFile = Services.dirsvc.get("BMarks", Ci.nsIFile);
|
||||
if (bookmarksHTMLFile.exists()) {
|
||||
// Note doMigrate doesn't care about the success value of the
|
||||
// callback.
|
||||
BookmarkHTMLUtils.importFromURL(
|
||||
NetUtil.newURI(bookmarksHTMLFile).spec, true, function(a) {
|
||||
browserGlue.observe(null, TOPIC_DID_IMPORT_BOOKMARKS, "");
|
||||
doMigrate();
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Note doMigrate doesn't care about the success value of the
|
||||
// callback.
|
||||
BookmarkHTMLUtils.importFromURL(
|
||||
"resource:///defaults/profile/bookmarks.html", true, function(a) {
|
||||
browserGlue.observe(null, TOPIC_DID_IMPORT_BOOKMARKS, "");
|
||||
doMigrate();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
doMigrate();
|
||||
|
@ -250,9 +250,6 @@ let UI = {
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("tabviewframeinitialized", true, false);
|
||||
dispatchEvent(event);
|
||||
|
||||
// XXX this can be removed when bug 731868 is fixed
|
||||
event = null;
|
||||
} catch(e) {
|
||||
Utils.log(e);
|
||||
} finally {
|
||||
|
@ -42,10 +42,10 @@ let WebappsInstaller = {
|
||||
shell.install();
|
||||
} catch (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.appcacheDefined = (app.manifest.appcache_path != undefined);
|
||||
|
||||
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 = {
|
||||
"registryDir": this.profileFolder.path,
|
||||
"registryDir": this.registryFolder.path,
|
||||
"app": app
|
||||
};
|
||||
|
||||
@ -125,8 +129,8 @@ function NativeApp(aData) {
|
||||
*
|
||||
* The Windows installation process will generate the following files:
|
||||
*
|
||||
* ${FolderName} = app-origin;protocol;port
|
||||
* e.g.: subdomain.example.com;http;-1
|
||||
* ${FolderName} = protocol;app-origin[;port]
|
||||
* e.g.: subdomain.example.com;http;85
|
||||
*
|
||||
* %APPDATA%/${FolderName}
|
||||
* - webapp.ini
|
||||
@ -170,6 +174,7 @@ WinNativeApp.prototype = {
|
||||
this._createConfigFiles();
|
||||
this._createShortcutFiles();
|
||||
this._writeSystemKeys();
|
||||
this._createAppProfile();
|
||||
} catch (ex) {
|
||||
this._removeInstallation();
|
||||
throw(ex);
|
||||
@ -191,8 +196,8 @@ WinNativeApp.prototype = {
|
||||
}
|
||||
|
||||
// The ${InstallDir} format is as follows:
|
||||
// host of the app origin + ";" +
|
||||
// protocol
|
||||
// + ";" + host of the app origin
|
||||
// + ";" + port (only if port is not default)
|
||||
this.installDir = Services.dirsvc.get("AppData", Ci.nsIFile);
|
||||
let installDirLeaf = this.launchURI.scheme
|
||||
@ -280,6 +285,20 @@ WinNativeApp.prototype = {
|
||||
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.
|
||||
*/
|
||||
@ -495,6 +514,7 @@ MacNativeApp.prototype = {
|
||||
this._createDirectoryStructure();
|
||||
this._copyPrebuiltFiles();
|
||||
this._createConfigFiles();
|
||||
this._createAppProfile();
|
||||
} catch (ex) {
|
||||
this._removeInstallation(false);
|
||||
throw(ex);
|
||||
@ -533,6 +553,17 @@ MacNativeApp.prototype = {
|
||||
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() {
|
||||
let webapprt = this.runtimeFolder.clone();
|
||||
webapprt.append("webapprt-stub");
|
||||
@ -695,6 +726,7 @@ LinuxNativeApp.prototype = {
|
||||
this._createDirectoryStructure();
|
||||
this._copyPrebuiltFiles();
|
||||
this._createConfigFiles();
|
||||
this._createAppProfile();
|
||||
} catch (ex) {
|
||||
this._removeInstallation();
|
||||
throw(ex);
|
||||
@ -724,6 +756,17 @@ LinuxNativeApp.prototype = {
|
||||
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() {
|
||||
// ${InstallDir}/webapp.json
|
||||
let configJson = this.installDir.clone();
|
||||
|
@ -109,8 +109,14 @@ let webappsUI = {
|
||||
label: bundle.getString("webapps.install"),
|
||||
accessKey: bundle.getString("webapps.install.accesskey"),
|
||||
callback: function(notification) {
|
||||
if (WebappsInstaller.install(aData)) {
|
||||
DOMApplicationRegistry.confirmInstall(aData);
|
||||
let app = WebappsInstaller.install(aData);
|
||||
if (app) {
|
||||
let localDir = null;
|
||||
if (app.appcacheDefined && app.appProfile) {
|
||||
localDir = app.appProfile.localDir;
|
||||
}
|
||||
|
||||
DOMApplicationRegistry.confirmInstall(aData, false, localDir);
|
||||
} else {
|
||||
DOMApplicationRegistry.denyInstall(aData);
|
||||
}
|
||||
|
@ -1009,10 +1009,6 @@ toolbar[iconsize="small"] #feed-button {
|
||||
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 {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 515 B |
@ -26,7 +26,6 @@ browser.jar:
|
||||
skin/classic/browser/identity-icons-generic.png
|
||||
skin/classic/browser/identity-icons-https.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/KUI-close.png
|
||||
skin/classic/browser/monitor.png
|
||||
|
@ -1066,10 +1066,6 @@ toolbar[mode="icons"] #zoom-in-button {
|
||||
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[open=true] > #page-proxy-favicon {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 442 B |
@ -32,7 +32,6 @@ browser.jar:
|
||||
skin/classic/browser/identity-icons-generic.png
|
||||
skin/classic/browser/identity-icons-https.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/KUI-background.png
|
||||
skin/classic/browser/KUI-close.png
|
||||
|
@ -1446,10 +1446,6 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
|
||||
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 {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 515 B |
@ -32,7 +32,6 @@ browser.jar:
|
||||
skin/classic/browser/identity-icons-generic.png
|
||||
skin/classic/browser/identity-icons-https.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/KUI-background.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-https.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/KUI-background.png
|
||||
skin/classic/aero/browser/KUI-close.png
|
||||
|
@ -98,6 +98,7 @@ case "$target" in
|
||||
fi
|
||||
|
||||
dnl set up compilers
|
||||
TOOLCHAIN_PREFIX="$android_toolchain/bin/$android_tool_prefix-"
|
||||
AS="$android_toolchain"/bin/"$android_tool_prefix"-as
|
||||
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
|
||||
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++
|
||||
|
@ -105,7 +105,7 @@ public class DoCommand {
|
||||
String ffxProvider = "org.mozilla.ffxcp";
|
||||
String fenProvider = "org.mozilla.fencp";
|
||||
|
||||
private final String prgVersion = "SUTAgentAndroid Version 1.08";
|
||||
private final String prgVersion = "SUTAgentAndroid Version 1.09";
|
||||
|
||||
public enum Command
|
||||
{
|
||||
@ -162,6 +162,7 @@ public class DoCommand {
|
||||
INST ("inst"),
|
||||
UPDT ("updt"),
|
||||
UNINST ("uninst"),
|
||||
UNINSTALL ("uninstall"),
|
||||
TEST ("test"),
|
||||
DBG ("dbg"),
|
||||
TRACE ("trace"),
|
||||
@ -356,9 +357,16 @@ public class DoCommand {
|
||||
|
||||
case UNINST:
|
||||
if (Argc >= 2)
|
||||
strReturn = UnInstallApp(Argv[1], cmdOut);
|
||||
strReturn = UnInstallApp(Argv[1], cmdOut, true);
|
||||
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;
|
||||
|
||||
case ALRT:
|
||||
@ -3115,13 +3123,17 @@ private void CancelNotification()
|
||||
return theArgs;
|
||||
}
|
||||
|
||||
public String UnInstallApp(String sApp, OutputStream out)
|
||||
public String UnInstallApp(String sApp, OutputStream out, boolean reboot)
|
||||
{
|
||||
String sRet = "";
|
||||
|
||||
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);
|
||||
outThrd.start();
|
||||
@ -3762,7 +3774,8 @@ private void CancelNotification()
|
||||
"zip zipfile src - zip the source file/dir into zipfile\n" +
|
||||
"rebt - reboot device\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" +
|
||||
"clok - the current device time expressed as the" +
|
||||
" number of millisecs since epoch\n" +
|
||||
|
@ -357,6 +357,7 @@ HAVE_64BIT_OS = @HAVE_64BIT_OS@
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
CPP = @CPP@
|
||||
TOOLCHAIN_PREFIX = @TOOLCHAIN_PREFIX@
|
||||
|
||||
CC_VERSION = @CC_VERSION@
|
||||
CXX_VERSION = @CXX_VERSION@
|
||||
|
@ -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)
|
||||
|
||||
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_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(basename $(@F)).pp)
|
||||
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)/$(@F).pp)
|
||||
EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
|
||||
EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
|
||||
EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC)
|
||||
|
@ -286,7 +286,7 @@ endif
|
||||
|
||||
ifndef MOZ_AUTO_DEPS
|
||||
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
|
||||
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:.$(OBJ_SUFFIX)=.pp))
|
||||
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:=.pp))
|
||||
ifndef NO_GEN_XPT
|
||||
MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
|
||||
endif
|
||||
|
@ -171,6 +171,7 @@ if test -n "$gonkdir" ; then
|
||||
ANDROID_NDK="${ANDROID_SOURCE}/ndk"
|
||||
|
||||
dnl set up compilers
|
||||
TOOLCHAIN_PREFIX="$gonk_toolchain_prefix"
|
||||
AS="$gonk_toolchain_prefix"as
|
||||
CC="$gonk_toolchain_prefix"gcc
|
||||
CXX="$gonk_toolchain_prefix"g++
|
||||
@ -7762,7 +7763,7 @@ MOZ_ARG_DISABLE_BOOL(md,
|
||||
fi])
|
||||
if test "$_cpp_md_flag"; then
|
||||
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
|
||||
if test "$SOLARIS_SUNPRO_CC"; then
|
||||
_DEPEND_CFLAGS=
|
||||
@ -8320,6 +8321,7 @@ AC_SUBST(MOZ_FEEDS)
|
||||
AC_SUBST(NS_PRINTING)
|
||||
AC_SUBST(MOZ_WEBGL)
|
||||
AC_SUBST(MOZ_HELP_VIEWER)
|
||||
AC_SUBST(TOOLCHAIN_PREFIX)
|
||||
|
||||
AC_SUBST(JAVA)
|
||||
AC_SUBST(JAVAC)
|
||||
@ -8464,7 +8466,6 @@ AC_SUBST(MOZ_APP_UA_NAME)
|
||||
AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION")
|
||||
AC_SUBST(MOZ_APP_VERSION)
|
||||
AC_SUBST(MOZ_APP_MAXVERSION)
|
||||
AC_DEFINE_UNQUOTED(MOZ_UA_FIREFOX_VERSION, "$FIREFOX_VERSION")
|
||||
AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
|
||||
AC_SUBST(FIREFOX_VERSION)
|
||||
|
||||
|
@ -6251,6 +6251,12 @@ nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent)
|
||||
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?
|
||||
// sXBL/XBL2 issue!
|
||||
nsIDocument* subDoc = doc->GetSubDocumentFor(aContent);
|
||||
|
@ -201,13 +201,14 @@ GK_ATOM(commandupdater, "commandupdater")
|
||||
GK_ATOM(comment, "comment")
|
||||
GK_ATOM(compact, "compact")
|
||||
GK_ATOM(concat, "concat")
|
||||
GK_ATOM(contenteditable, "contenteditable")
|
||||
GK_ATOM(conditions, "conditions")
|
||||
GK_ATOM(constructor, "constructor")
|
||||
GK_ATOM(consumeoutsideclicks, "consumeoutsideclicks")
|
||||
GK_ATOM(container, "container")
|
||||
GK_ATOM(containment, "containment")
|
||||
GK_ATOM(contains, "contains")
|
||||
GK_ATOM(content, "content")
|
||||
GK_ATOM(contenteditable, "contenteditable")
|
||||
GK_ATOM(headerContentDisposition, "content-disposition")
|
||||
GK_ATOM(headerContentLanguage, "content-language")
|
||||
GK_ATOM(contentLocation, "content-location")
|
||||
|
@ -494,7 +494,6 @@
|
||||
return root[select](q, resolver);
|
||||
} catch(e){
|
||||
if ( e.message.indexOf("ERR") > -1 ||
|
||||
(e.name == "NamespaceError" && e.code == DOMException.NAMESPACE_ERR) ||
|
||||
(e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR) )
|
||||
throw e;
|
||||
}
|
||||
@ -549,7 +548,7 @@
|
||||
results = query(q, resolver);
|
||||
} catch(e) {
|
||||
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 + ")" +
|
||||
|
@ -302,6 +302,7 @@ NS_INTERFACE_MAP_BEGIN(nsTextMetrics)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
struct nsCanvasBidiProcessor;
|
||||
class CanvasRenderingContext2DUserData;
|
||||
|
||||
/**
|
||||
** nsCanvasRenderingContext2D
|
||||
@ -381,6 +382,7 @@ public:
|
||||
nsRefPtr<gfxPath> mPath;
|
||||
};
|
||||
friend class PathAutoSaveRestore;
|
||||
friend class CanvasRenderingContext2DUserData;
|
||||
|
||||
protected:
|
||||
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
|
||||
@ -449,6 +451,7 @@ protected:
|
||||
|
||||
// If mCanvasElement is not provided, then a docshell is
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
nsTArray<CanvasRenderingContext2DUserData*> mUserDatas;
|
||||
|
||||
// our drawing surfaces, contexts, and layers
|
||||
nsRefPtr<gfxContext> mThebes;
|
||||
@ -755,6 +758,40 @@ protected:
|
||||
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_RELEASE(nsCanvasRenderingContext2D)
|
||||
|
||||
@ -810,6 +847,10 @@ nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
||||
nsCanvasRenderingContext2D::~nsCanvasRenderingContext2D()
|
||||
{
|
||||
Reset();
|
||||
// Drop references from all CanvasRenderingContext2DUserDatas to this context
|
||||
for (PRUint32 i = 0; i < mUserDatas.Length(); ++i) {
|
||||
mUserDatas[i]->Forget();
|
||||
}
|
||||
sNumLivingContexts--;
|
||||
if (!sNumLivingContexts) {
|
||||
delete[] sUnpremultiplyTable;
|
||||
@ -4154,19 +4195,6 @@ nsCanvasRenderingContext2D::SetMozImageSmoothingEnabled(bool val)
|
||||
|
||||
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>
|
||||
nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
@ -4175,10 +4203,14 @@ nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
if (!EnsureSurface())
|
||||
return nsnull;
|
||||
|
||||
if (!mResetLayer && aOldLayer &&
|
||||
aOldLayer->HasUserData(&g2DContextLayerUserData)) {
|
||||
NS_ADDREF(aOldLayer);
|
||||
return aOldLayer;
|
||||
if (!mResetLayer && aOldLayer) {
|
||||
CanvasRenderingContext2DUserData* userData =
|
||||
static_cast<CanvasRenderingContext2DUserData*>(
|
||||
aOldLayer->GetUserData(&g2DContextLayerUserData));
|
||||
if (userData && userData->IsForContext(this)) {
|
||||
NS_ADDREF(aOldLayer);
|
||||
return aOldLayer;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
|
||||
@ -4200,7 +4232,7 @@ nsCanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
// releasing the reference to the element.
|
||||
// The userData will receive DidTransactionCallbacks, which flush the
|
||||
// the invalidation state to indicate that the canvas is up to date.
|
||||
userData = new CanvasRenderingContext2DUserData(mCanvasElement);
|
||||
userData = new CanvasRenderingContext2DUserData(this);
|
||||
canvasLayer->SetDidTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::DidTransactionCallback, userData);
|
||||
}
|
||||
|
@ -357,6 +357,7 @@ NS_INTERFACE_MAP_BEGIN(nsTextMetricsAzure)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
struct nsCanvasBidiProcessorAzure;
|
||||
class CanvasRenderingContext2DUserDataAzure;
|
||||
|
||||
// Cap sigma to avoid overly large temp surfaces.
|
||||
static const Float SIGMA_MAX = 100;
|
||||
@ -423,6 +424,8 @@ public:
|
||||
nsresult LineTo(const Point& aPoint);
|
||||
nsresult BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3);
|
||||
|
||||
friend class CanvasRenderingContext2DUserDataAzure;
|
||||
|
||||
protected:
|
||||
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
|
||||
uint32_t aWidth, uint32_t aHeight,
|
||||
@ -504,6 +507,8 @@ protected:
|
||||
// This is needed for drawing in drawAsyncXULElement
|
||||
bool mIPC;
|
||||
|
||||
nsTArray<CanvasRenderingContext2DUserDataAzure*> mUserDatas;
|
||||
|
||||
// If mCanvasElement is not provided, then a docshell is
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
|
||||
@ -935,6 +940,40 @@ protected:
|
||||
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_RELEASE(nsCanvasRenderingContext2DAzure)
|
||||
|
||||
@ -1029,6 +1068,10 @@ nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
|
||||
nsCanvasRenderingContext2DAzure::~nsCanvasRenderingContext2DAzure()
|
||||
{
|
||||
Reset();
|
||||
// Drop references from all CanvasRenderingContext2DUserDataAzure to this context
|
||||
for (PRUint32 i = 0; i < mUserDatas.Length(); ++i) {
|
||||
mUserDatas[i]->Forget();
|
||||
}
|
||||
sNumLivingContexts--;
|
||||
if (!sNumLivingContexts) {
|
||||
delete[] sUnpremultiplyTable;
|
||||
@ -4399,19 +4442,6 @@ nsCanvasRenderingContext2DAzure::SetMozImageSmoothingEnabled(bool val)
|
||||
|
||||
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>
|
||||
nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
@ -4425,18 +4455,22 @@ nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
mTarget->Flush();
|
||||
}
|
||||
|
||||
if (!mResetLayer && aOldLayer &&
|
||||
aOldLayer->HasUserData(&g2DContextLayerUserData)) {
|
||||
if (!mResetLayer && aOldLayer) {
|
||||
CanvasRenderingContext2DUserDataAzure* userData =
|
||||
static_cast<CanvasRenderingContext2DUserDataAzure*>(
|
||||
aOldLayer->GetUserData(&g2DContextLayerUserData));
|
||||
if (userData && userData->IsForContext(this)) {
|
||||
NS_ADDREF(aOldLayer);
|
||||
return aOldLayer;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
|
||||
if (!canvasLayer) {
|
||||
NS_WARNING("CreateCanvasLayer returned null!");
|
||||
return nsnull;
|
||||
NS_WARNING("CreateCanvasLayer returned null!");
|
||||
return nsnull;
|
||||
}
|
||||
CanvasRenderingContext2DUserData *userData = nsnull;
|
||||
CanvasRenderingContext2DUserDataAzure *userData = nsnull;
|
||||
if (aBuilder->IsPaintingToWindow()) {
|
||||
// Make the layer tell us whenever a transaction finishes (including
|
||||
// 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.
|
||||
// The userData will receive DidTransactionCallbacks, which flush the
|
||||
// the invalidation state to indicate that the canvas is up to date.
|
||||
userData = new CanvasRenderingContext2DUserData(mCanvasElement);
|
||||
userData = new CanvasRenderingContext2DUserDataAzure(this);
|
||||
canvasLayer->SetDidTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::DidTransactionCallback, userData);
|
||||
CanvasRenderingContext2DUserDataAzure::DidTransactionCallback, userData);
|
||||
}
|
||||
canvasLayer->SetUserData(&g2DContextLayerUserData, userData);
|
||||
|
||||
|
@ -96,6 +96,7 @@ nsDOMKeyboardEvent::GetCharCode(PRUint32* aCharCode)
|
||||
*aCharCode = ((nsKeyEvent*)mEvent)->charCode;
|
||||
break;
|
||||
default:
|
||||
*aCharCode = 0;
|
||||
break;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1678,10 +1678,10 @@ nsEventStateManager::IsRemoteTarget(nsIContent* target) {
|
||||
// <frame/iframe mozbrowser>
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(target);
|
||||
if (browserFrame) {
|
||||
bool isRemote = false;
|
||||
browserFrame->GetReallyIsBrowser(&isRemote);
|
||||
if (isRemote) {
|
||||
return true;
|
||||
bool isBrowser = false;
|
||||
browserFrame->GetReallyIsBrowser(&isBrowser);
|
||||
if (isBrowser) {
|
||||
return !!TabParent::GetFrom(target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,6 +549,7 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
|
||||
{
|
||||
if (aStream->mFinished)
|
||||
return;
|
||||
printf("MediaStreamGraphImpl::FinishStream\n");
|
||||
LOG(PR_LOG_DEBUG, ("MediaStream %p will finish", aStream));
|
||||
aStream->mFinished = true;
|
||||
// Force at least one more iteration of the control loop, since we rely
|
||||
|
@ -929,15 +929,22 @@ nsFocusManager::WindowHidden(nsIDOMWindow* aWindow)
|
||||
|
||||
nsCOMPtr<nsIContent> oldFocusedContent = mFocusedContent.forget();
|
||||
|
||||
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
focusedDocShell->GetPresShell(getter_AddRefs(presShell));
|
||||
|
||||
if (oldFocusedContent && oldFocusedContent->IsInDoc()) {
|
||||
NotifyFocusStateChange(oldFocusedContent,
|
||||
mFocusedWindow->ShouldShowFocusRing(),
|
||||
false);
|
||||
}
|
||||
window->UpdateCommands(NS_LITERAL_STRING("focus"));
|
||||
|
||||
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
focusedDocShell->GetPresShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
SendFocusOrBlurEvent(NS_BLUR_CONTENT, presShell,
|
||||
oldFocusedContent->GetCurrentDoc(),
|
||||
oldFocusedContent, 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
|
||||
if (presShell) {
|
||||
@ -1563,8 +1570,7 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
|
||||
}
|
||||
|
||||
// if the object being blurred is a remote browser, deactivate remote content
|
||||
TabParent* remote = GetRemoteForContent(content);
|
||||
if (remote) {
|
||||
if (TabParent* remote = TabParent::GetFrom(content)) {
|
||||
remote->Deactivate();
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("*Remote browser deactivated\n");
|
||||
@ -1775,8 +1781,7 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
||||
objectFrameWidget->SetFocus(false);
|
||||
|
||||
// if the object being focused is a remote browser, activate remote content
|
||||
TabParent* remote = GetRemoteForContent(aContent);
|
||||
if (remote) {
|
||||
if (TabParent* remote = TabParent::GetFrom(aContent)) {
|
||||
remote->Activate();
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("*Remote browser activated\n");
|
||||
@ -3006,29 +3011,6 @@ nsFocusManager::GetRootForFocus(nsPIDOMWindow* aWindow,
|
||||
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
|
||||
nsFocusManager::GetLastDocShell(nsIDocShellTreeItem* aItem,
|
||||
nsIDocShellTreeItem** aResult)
|
||||
|
@ -21,12 +21,6 @@
|
||||
class nsIDocShellTreeItem;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class TabParent;
|
||||
}
|
||||
}
|
||||
|
||||
struct nsDelayedBlurOrFocusEvent;
|
||||
|
||||
/**
|
||||
@ -414,12 +408,6 @@ protected:
|
||||
bool aIsForDocNavigation,
|
||||
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.
|
||||
*/
|
||||
|
@ -176,6 +176,7 @@ DOMInterfaces = {
|
||||
|
||||
'WebGLRenderingContext': {
|
||||
'nativeType': 'mozilla::WebGLContext',
|
||||
'headerFile': 'WebGLContext.h',
|
||||
'prefable': True,
|
||||
'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
|
||||
'getAttachedShaders' ],
|
||||
@ -356,8 +357,7 @@ def addExternalHTMLElement(element):
|
||||
addExternalHTMLElement('HTMLCanvasElement')
|
||||
addExternalHTMLElement('HTMLImageElement')
|
||||
addExternalHTMLElement('HTMLVideoElement')
|
||||
addExternalIface('ImageData', nativeType='mozilla::dom::ImageData',
|
||||
headerFile='mozilla/dom/ImageData.h')
|
||||
addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
|
||||
addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
|
||||
headerFile='WebGLContext.h')
|
||||
addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
|
||||
|
@ -1858,11 +1858,11 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
elif descriptor.workers:
|
||||
templateBody += "${declName} = &${val}.toObject();"
|
||||
else:
|
||||
# External interface. We always have a holder for these,
|
||||
# because we don't actually know whether we have to addref
|
||||
# when unwrapping or not. So we just pass an
|
||||
# getter_AddRefs(nsRefPtr) to XPConnect and if we'll need
|
||||
# a release it'll put a non-null pointer in there.
|
||||
# Either external, or new-binding non-castable. We always have a
|
||||
# holder for these, because we don't actually know whether we have
|
||||
# to addref when unwrapping or not. So we just pass an
|
||||
# getter_AddRefs(nsRefPtr) to XPConnect and if we'll need a release
|
||||
# it'll put a non-null pointer in there.
|
||||
if forceOwningType:
|
||||
# Don't return a holderType in this case; our declName
|
||||
# will just own stuff.
|
||||
@ -2779,29 +2779,6 @@ class CGMethodCall(CGThing):
|
||||
requiredArgs -= 1
|
||||
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):
|
||||
return CGPerSignatureCall(signature[0], argsPre, signature[1],
|
||||
nativeMethodName, static, descriptor,
|
||||
@ -2831,13 +2808,12 @@ class CGMethodCall(CGThing):
|
||||
return
|
||||
|
||||
# Need to find the right overload
|
||||
maxSigArgs = maxSigLength(signatures)
|
||||
allowedArgCounts = [ i for i in range(0, maxSigArgs+1)
|
||||
if len(signaturesForArgCount(i, signatures)) != 0 ]
|
||||
maxArgCount = method.maxArgCount
|
||||
allowedArgCounts = method.allowedArgCounts
|
||||
|
||||
argCountCases = []
|
||||
for argCount in allowedArgCounts:
|
||||
possibleSignatures = signaturesForArgCount(argCount, signatures)
|
||||
possibleSignatures = method.signaturesForArgCount(argCount)
|
||||
if len(possibleSignatures) == 1:
|
||||
# easy case!
|
||||
signature = possibleSignatures[0]
|
||||
@ -2850,7 +2826,7 @@ class CGMethodCall(CGThing):
|
||||
if (len(signature[1]) > argCount and
|
||||
signature[1][argCount].optional and
|
||||
(argCount+1) in allowedArgCounts and
|
||||
len(signaturesForArgCount(argCount+1, signatures)) == 1):
|
||||
len(method.signaturesForArgCount(argCount+1)) == 1):
|
||||
argCountCases.append(
|
||||
CGCase(str(argCount), None, True))
|
||||
else:
|
||||
@ -2858,28 +2834,7 @@ class CGMethodCall(CGThing):
|
||||
CGCase(str(argCount), getPerSignatureCall(signature)))
|
||||
continue
|
||||
|
||||
distinguishingIndex = findDistinguishingIndex(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)))
|
||||
distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
|
||||
|
||||
# Convert all our arguments up to the distinguishing index.
|
||||
# Doesn't matter which of the possible signatures we use, since
|
||||
@ -3019,7 +2974,7 @@ class CGMethodCall(CGThing):
|
||||
overloadCGThings = []
|
||||
overloadCGThings.append(
|
||||
CGGeneric("unsigned argcount = NS_MIN(argc, %du);" %
|
||||
maxSigArgs))
|
||||
maxArgCount))
|
||||
overloadCGThings.append(
|
||||
CGSwitch("argcount",
|
||||
argCountCases,
|
||||
|
@ -131,7 +131,7 @@ class Descriptor(DescriptorProvider):
|
||||
self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
|
||||
|
||||
headerDefault = self.nativeType
|
||||
headerDefault = headerDefault.split("::")[-1] + ".h"
|
||||
headerDefault = headerDefault.replace("::", "/") + ".h"
|
||||
self.headerFile = desc.get('headerFile', headerDefault)
|
||||
|
||||
castableDefault = not self.interface.isCallback()
|
||||
|
@ -51,19 +51,21 @@ def enum(*names):
|
||||
return Foo()
|
||||
|
||||
class WebIDLError(Exception):
|
||||
def __init__(self, message, location, warning=False, extraLocation=""):
|
||||
def __init__(self, message, location, warning=False, extraLocations=[]):
|
||||
self.message = message
|
||||
self.location = location
|
||||
self.warning = warning
|
||||
self.extraLocation = extraLocation
|
||||
self.extraLocations = [str(loc) for loc in extraLocations]
|
||||
|
||||
def __str__(self):
|
||||
return "%s: %s%s%s%s%s" % (self.warning and 'warning' or 'error',
|
||||
self.message,
|
||||
", " if self.location else "",
|
||||
self.location,
|
||||
"\n" if self.extraLocation else "",
|
||||
self.extraLocation)
|
||||
extraLocationsStr = (
|
||||
"" if len(self.extraLocations) == 0 else
|
||||
"\n" + "\n".join(self.extraLocations))
|
||||
return "%s: %s%s%s%s" % (self.warning and 'warning' or 'error',
|
||||
self.message,
|
||||
", " if self.location else "",
|
||||
self.location,
|
||||
extraLocationsStr)
|
||||
|
||||
class Location(object):
|
||||
def __init__(self, lexer, lineno, lexpos, filename):
|
||||
@ -348,12 +350,18 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
|
||||
def finish(self, scope):
|
||||
pass
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def isExternal(self):
|
||||
return True
|
||||
|
||||
def isInterface(self):
|
||||
return True
|
||||
|
||||
def isConsequential(self):
|
||||
return False
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
assert len(attrs) == 0
|
||||
|
||||
@ -371,6 +379,11 @@ class IDLInterface(IDLObjectWithScope):
|
||||
self._finished = False
|
||||
self.members = list(members) # clone the list
|
||||
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)
|
||||
|
||||
@ -422,9 +435,23 @@ class IDLInterface(IDLObjectWithScope):
|
||||
|
||||
# Callbacks must not inherit from non-callbacks or inherit from
|
||||
# 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():
|
||||
assert(self.parent.isCallback())
|
||||
assert(len(self.parent.getConsequentialInterfaces()) == 0)
|
||||
if not self.parent.isCallback():
|
||||
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:
|
||||
iface.finish(scope)
|
||||
@ -434,7 +461,14 @@ class IDLInterface(IDLObjectWithScope):
|
||||
raise WebIDLError("Interface %s has itself as ancestor or "
|
||||
"implemented interface" % self.identifier.name,
|
||||
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
|
||||
# ones from our implemented interfaces.
|
||||
@ -462,6 +496,8 @@ class IDLInterface(IDLObjectWithScope):
|
||||
for iface in sorted(self.getConsequentialInterfaces(),
|
||||
cmp=cmp,
|
||||
key=lambda x: x.identifier.name):
|
||||
# Flag the interface as being someone's consequential interface
|
||||
iface.setIsConsequentialInterfaceOf(self)
|
||||
additionalMembers = iface.originalMembers;
|
||||
for additionalMember in additionalMembers:
|
||||
for member in self.members:
|
||||
@ -470,9 +506,14 @@ class IDLInterface(IDLObjectWithScope):
|
||||
"Multiple definitions of %s on %s coming from 'implements' statements" %
|
||||
(member.identifier.name, self),
|
||||
additionalMember.location,
|
||||
extraLocation=member.location)
|
||||
extraLocations=[member.location])
|
||||
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}
|
||||
# {getter,setter,creator,deleter}.
|
||||
specialMembersSeen = set()
|
||||
@ -504,12 +545,23 @@ class IDLInterface(IDLObjectWithScope):
|
||||
|
||||
specialMembersSeen.add(memberType)
|
||||
|
||||
def validate(self):
|
||||
for member in self.members:
|
||||
member.validate()
|
||||
|
||||
def isInterface(self):
|
||||
return True
|
||||
|
||||
def isExternal(self):
|
||||
return False
|
||||
|
||||
def setIsConsequentialInterfaceOf(self, other):
|
||||
self._consequential = True
|
||||
self.interfacesBasedOnSelf.add(other)
|
||||
|
||||
def isConsequential(self):
|
||||
return self._consequential
|
||||
|
||||
def setCallback(self, value):
|
||||
self._callback = value
|
||||
|
||||
@ -656,7 +708,7 @@ class IDLDictionary(IDLObjectWithScope):
|
||||
raise WebIDLError("Dictionary %s has parent that is not a dictionary" %
|
||||
self.identifier.name,
|
||||
oldParent.location,
|
||||
extraLocation=self.parent.location)
|
||||
extraLocations=[self.parent.location])
|
||||
|
||||
# Make sure the parent resolves all its members before we start
|
||||
# looking at them.
|
||||
@ -690,7 +742,10 @@ class IDLDictionary(IDLObjectWithScope):
|
||||
raise WebIDLError("Dictionary %s has two members with name %s" %
|
||||
(self.identifier.name, member.identifier.name),
|
||||
member.location,
|
||||
extraLocation=inheritedMember.location)
|
||||
extraLocations=[inheritedMember.location])
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
assert len(attrs) == 0
|
||||
@ -713,6 +768,9 @@ class IDLEnum(IDLObjectWithIdentifier):
|
||||
def finish(self, scope):
|
||||
pass
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def isEnum(self):
|
||||
return True
|
||||
|
||||
@ -1353,23 +1411,34 @@ class IDLWrapperType(IDLType):
|
||||
other.isCallback() or other.isDictionary() or
|
||||
other.isSequence() or other.isArray() or
|
||||
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
|
||||
if self.isDictionary():
|
||||
return (other.isNonCallbackInterface() or other.isSequence() or
|
||||
other.isArray() or other.isDate())
|
||||
other.isArray())
|
||||
|
||||
assert self.isInterface()
|
||||
# XXXbz need to check that the interfaces can't be implemented
|
||||
# by the same object
|
||||
if other.isInterface():
|
||||
return (self != other and
|
||||
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
|
||||
other.isNonCallbackInterface()))
|
||||
if (other.isDictionary() or other.isCallback() or
|
||||
other.isSequence() or other.isArray()):
|
||||
return self.isNonCallbackInterface()
|
||||
|
||||
# Not much else |other| can be
|
||||
assert other.isObject()
|
||||
return False
|
||||
|
||||
class IDLBuiltinType(IDLType):
|
||||
|
||||
Types = enum(
|
||||
@ -1736,6 +1805,9 @@ class IDLConst(IDLInterfaceMember):
|
||||
def finish(self, scope):
|
||||
assert self.type.isComplete()
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
class IDLAttribute(IDLInterfaceMember):
|
||||
def __init__(self, location, identifier, type, readonly, inherit):
|
||||
IDLInterfaceMember.__init__(self, location, identifier,
|
||||
@ -1858,6 +1930,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
|
||||
assert not isinstance(type.name, IDLUnresolvedIdentifier)
|
||||
argument.type = type
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def isDistinguishableFrom(self, other):
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isNonCallbackInterface() or other.isDate())
|
||||
@ -1899,6 +1974,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
|
||||
assert isinstance(returnType, IDLType)
|
||||
self._returnType = [returnType]
|
||||
# We store a list of all the overload locations, matching our
|
||||
# signature list.
|
||||
self._location = [location]
|
||||
|
||||
assert isinstance(static, bool)
|
||||
self._static = static
|
||||
@ -1944,20 +2022,32 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
assert self._returnType[0] == BuiltinTypes[IDLBuiltinType.Types.domstring]
|
||||
|
||||
inOptionalArguments = False
|
||||
sawVariadicArgument = False
|
||||
variadicArgument = None
|
||||
sawOptionalWithNoDefault = False
|
||||
|
||||
assert len(self._arguments) == 1
|
||||
arguments = self._arguments[0]
|
||||
|
||||
for argument in arguments:
|
||||
# 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
|
||||
# arguments.
|
||||
if inOptionalArguments:
|
||||
assert argument.optional
|
||||
if inOptionalArguments and not 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
|
||||
sawVariadicArgument = argument.variadic
|
||||
if argument.variadic:
|
||||
variadicArgument = argument
|
||||
sawOptionalWithNoDefault = argument.optional and not argument.defaultValue
|
||||
|
||||
def isStatic(self):
|
||||
return self._static
|
||||
@ -2006,9 +2096,11 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
|
||||
assert len(method._returnType) == 1
|
||||
assert len(method._arguments) == 1
|
||||
assert len(method._location) == 1
|
||||
|
||||
self._returnType.extend(method._returnType)
|
||||
self._arguments.extend(method._arguments)
|
||||
self._location.extend(method._location)
|
||||
|
||||
self._hasOverloads = True
|
||||
|
||||
@ -2060,6 +2152,64 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
assert not isinstance(type.name, IDLUnresolvedIdentifier)
|
||||
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):
|
||||
def __init__(self, location, implementor, implementee):
|
||||
IDLObject.__init__(self, location)
|
||||
@ -2071,8 +2221,30 @@ class IDLImplementsStatement(IDLObject):
|
||||
assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
|
||||
implementor = self.implementor.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)
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
assert len(attrs) == 0
|
||||
|
||||
@ -3349,6 +3521,10 @@ class Parser(Tokenizer):
|
||||
for production in otherStatements:
|
||||
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.
|
||||
seen = set()
|
||||
result = []
|
||||
|
@ -52,7 +52,6 @@ def WebIDLTest(parser, harness):
|
||||
harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod")
|
||||
|
||||
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")
|
||||
|
||||
(retType, arguments) = method.signatures()[0]
|
||||
|
@ -12,3 +12,36 @@ def WebIDLTest(parser, harness):
|
||||
iface = results[0]
|
||||
|
||||
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")
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
def firstArgType(method):
|
||||
return method.signatures()[0][1][0].type
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
dictionary Dict {
|
||||
|
@ -17,7 +17,6 @@ interface ?"""
|
||||
except WebIDL.WebIDLError, e:
|
||||
threw = True
|
||||
lines = str(e).split('\n')
|
||||
print lines
|
||||
|
||||
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])
|
||||
|
@ -115,7 +115,7 @@ def WebIDLTest(parser, harness):
|
||||
|
||||
# Reset the parser so we can actually find things where we expect
|
||||
# them in the list
|
||||
parser = WebIDL.Parser()
|
||||
parser = parser.reset()
|
||||
|
||||
# Diamonds should be allowed
|
||||
threw = False
|
||||
@ -141,3 +141,76 @@ def WebIDLTest(parser, harness):
|
||||
harness.check(len(results[6].members), 1, "S should have one member")
|
||||
harness.check(results[6].members[0].identifier.name, "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'")
|
||||
|
||||
|
@ -5,9 +5,9 @@ def WebIDLTest(parser, harness):
|
||||
interface TestOverloads {
|
||||
void basic();
|
||||
void basic(long arg1);
|
||||
boolean abitharder(unsigned long foo);
|
||||
boolean abitharder(TestOverloads foo);
|
||||
boolean abitharder(boolean foo);
|
||||
void abitharder(long? foo);
|
||||
void abitharder(ArrayBuffer? foo);
|
||||
};
|
||||
""")
|
||||
|
||||
|
@ -71,3 +71,7 @@ libs:: $(_TEST_FILES)
|
||||
check::
|
||||
PYTHONDONTWRITEBYTECODE=1 $(PYTHON_PATH) $(PLY_INCLUDE) \
|
||||
$(srcdir)/../parser/runtests.py
|
||||
|
||||
check-interactive:
|
||||
PYTHONDONTWRITEBYTECODE=1 $(PYTHON_PATH) $(PLY_INCLUDE) \
|
||||
$(srcdir)/../parser/runtests.py -q
|
||||
|
@ -501,7 +501,7 @@ class ThreadLocalJSRuntime
|
||||
|
||||
JSAutoRequest ar(mContext);
|
||||
|
||||
mGlobal = JS_NewCompartmentAndGlobalObject(mContext, &sGlobalClass, NULL);
|
||||
mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, NULL);
|
||||
NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
JS_SetGlobalObject(mContext, mGlobal);
|
||||
|
@ -523,6 +523,27 @@ TabParent::SendSelectionEvent(nsSelectionEvent& 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
|
||||
TabParent::RecvEndIMEComposition(const bool& aCancel,
|
||||
nsString* aComposition)
|
||||
|
@ -7,26 +7,26 @@
|
||||
#ifndef mozilla_tabs_TabParent_h
|
||||
#define mozilla_tabs_TabParent_h
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
#include "mozilla/dom/PContentDialogParent.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITabParent.h"
|
||||
#include "nsIBrowserDOMWindow.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIDialogParamBlock.h"
|
||||
#include "nsIAuthPromptProvider.h"
|
||||
#include "nsIBrowserDOMWindow.h"
|
||||
#include "nsIDialogParamBlock.h"
|
||||
#include "nsISecureBrowserUI.h"
|
||||
#include "nsITabParent.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsFrameLoader;
|
||||
class nsIURI;
|
||||
class nsIDOMElement;
|
||||
struct gfxMatrix;
|
||||
|
||||
struct JSContext;
|
||||
struct JSObject;
|
||||
class nsFrameLoader;
|
||||
class nsIDOMElement;
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -154,6 +154,10 @@ public:
|
||||
bool SendCompositionEvent(nsCompositionEvent& event);
|
||||
bool SendTextEvent(nsTextEvent& event);
|
||||
bool SendSelectionEvent(nsSelectionEvent& event);
|
||||
|
||||
static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
|
||||
static TabParent* GetFrom(nsIContent* aContent);
|
||||
|
||||
protected:
|
||||
bool ReceiveMessage(const nsString& aMessage,
|
||||
bool aSync,
|
||||
|
@ -261,6 +261,10 @@ static dom::ConstantSpec gWinProperties[] =
|
||||
// SetFilePointer error constant
|
||||
INT_CONSTANT(INVALID_SET_FILE_POINTER),
|
||||
|
||||
// MoveFile flags
|
||||
INT_CONSTANT(MOVEFILE_COPY_ALLOWED),
|
||||
INT_CONSTANT(MOVEFILE_REPLACE_EXISTING),
|
||||
|
||||
// Errors
|
||||
INT_CONSTANT(ERROR_FILE_EXISTS),
|
||||
INT_CONSTANT(ERROR_FILE_NOT_FOUND),
|
||||
|
@ -909,8 +909,8 @@ CreateDedicatedWorkerGlobalScope(JSContext* aCx)
|
||||
JS_ASSERT(worker);
|
||||
|
||||
JSObject* global =
|
||||
JS_NewCompartmentAndGlobalObject(aCx, DedicatedWorkerGlobalScope::Class(),
|
||||
GetWorkerPrincipal());
|
||||
JS_NewGlobalObject(aCx, DedicatedWorkerGlobalScope::Class(),
|
||||
GetWorkerPrincipal());
|
||||
if (!global) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ nsresult CentralizedAdminPrefManagerInit()
|
||||
static_cast<nsIXPCSecurityManager*>(new AutoConfigSecMan());
|
||||
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) {
|
||||
JSAutoEnterCompartment ac;
|
||||
if(!ac.enter(autoconfig_cx, autoconfig_glob))
|
||||
|
@ -2263,7 +2263,6 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
}
|
||||
|
||||
GLenum format;
|
||||
GLenum internalformat;
|
||||
GLenum type;
|
||||
PRInt32 pixelSize = gfxASurface::BytePerPixelFromFormat(imageSurface->Format());
|
||||
ShaderProgramType shader;
|
||||
@ -2301,8 +2300,6 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
|
||||
PRInt32 stride = imageSurface->Stride();
|
||||
|
||||
internalformat = mIsGLES2 ? format : LOCAL_GL_RGBA;
|
||||
|
||||
nsIntRegionRectIterator iter(paintRegion);
|
||||
const nsIntRect *iterRect;
|
||||
|
||||
@ -2334,7 +2331,7 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
} else {
|
||||
TexImage2D(LOCAL_GL_TEXTURE_2D,
|
||||
0,
|
||||
internalformat,
|
||||
format,
|
||||
iterRect->width,
|
||||
iterRect->height,
|
||||
stride,
|
||||
|
@ -44,8 +44,6 @@ static inline CGImageRef SkCreateCGImageRef(const SkBitmap& bm) {
|
||||
*/
|
||||
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.
|
||||
|
865
gfx/skia/patches/0015-Bug-766017-warnings.patch
Normal file
865
gfx/skia/patches/0015-Bug-766017-warnings.patch
Normal 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;
|
||||
-}
|
||||
-
|
@ -17,3 +17,4 @@ See the relevant bugs in bugzilla for information on these patches:
|
||||
0012-Bug-759683-make-ssse3-conditional.patch
|
||||
0013-Bug-761890-fonts.patch
|
||||
0014-Bug-765038-Fix-clang-build.patch
|
||||
0015-Bug-766017-warnings.patch
|
||||
|
@ -251,7 +251,7 @@ static void count_left_right_zeros(const uint8_t* row, int width,
|
||||
*riteZ = zeros;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#if 0
|
||||
static void test_count_left_right_zeros() {
|
||||
static bool gOnce;
|
||||
if (gOnce) {
|
||||
@ -1324,12 +1324,6 @@ 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) {
|
||||
@ -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,
|
||||
RowIter& iterA, RowIter& iterB,
|
||||
AlphaProc proc, const SkIRect& bounds) {
|
||||
@ -1975,8 +1954,8 @@ static inline uint16_t mergeOne(uint16_t value, unsigned alpha) {
|
||||
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);
|
||||
@ -1992,7 +1971,6 @@ static inline SkPMColor mergeOne(SkPMColor value, unsigned 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);
|
||||
|
@ -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,
|
||||
const uint8_t* SK_RESTRICT mask,
|
||||
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
|
||||
// exand.. add.. combine
|
||||
// expand.. add.. combine
|
||||
// instead of
|
||||
// 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,
|
||||
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) {
|
||||
@ -364,6 +305,7 @@ static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
|
||||
// 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);
|
||||
@ -564,7 +506,7 @@ SkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config,
|
||||
|
||||
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,
|
||||
|
@ -42,7 +42,6 @@
|
||||
// the code has been proven robust.
|
||||
#define kMaxCount 1000
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
//------------------------------------------------------------------------------
|
||||
// Debugging support
|
||||
|
@ -474,7 +474,6 @@ void SkPath::incReserve(U16CPU inc) {
|
||||
void SkPath::moveTo(SkScalar x, SkScalar y) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
int vc = fVerbs.count();
|
||||
SkPoint* pt;
|
||||
|
||||
// remember our index
|
||||
@ -1168,7 +1167,6 @@ void SkPath::reversePathTo(const SkPath& path) {
|
||||
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();
|
||||
|
@ -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
|
||||
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?
|
||||
|
@ -341,34 +341,6 @@ SK_ERROR:
|
||||
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) {
|
||||
|
@ -235,42 +235,6 @@ void SuperBlitter::blitH(int x, int y, int 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);
|
||||
|
@ -870,35 +870,6 @@ 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.
|
||||
@ -2136,6 +2107,8 @@ private:
|
||||
const SkPoint fCenter;
|
||||
};
|
||||
|
||||
#ifndef SK_SCALAR_IS_FLOAT
|
||||
|
||||
#ifdef COMPUTE_SWEEP_TABLE
|
||||
#define PI 3.14159265
|
||||
static bool gSweepTableReady;
|
||||
@ -2173,10 +2146,13 @@ static const uint8_t gSweepTable[] = {
|
||||
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);
|
||||
@ -2299,6 +2275,7 @@ static unsigned atan_0_90(SkFixed y, SkFixed x) {
|
||||
SkASSERT(result <= 63);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
// returns angle in a circle [0..2PI) -> [0..255]
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
|
@ -117,7 +117,7 @@ void ColorRect32_SSE2(SkPMColor* destination,
|
||||
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,
|
||||
|
@ -80,10 +80,6 @@ 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,
|
||||
@ -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.
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
@ -255,13 +253,6 @@ static CGAffineTransform MatrixToCGAffineTransform(const SkMatrix& matrix,
|
||||
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));
|
||||
@ -1080,6 +1071,7 @@ static const uint8_t* getInverseTable(bool isWhite) {
|
||||
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;
|
||||
@ -1102,7 +1094,9 @@ static const uint8_t* getGammaTable(U8CPU luminance) {
|
||||
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);
|
||||
@ -1117,6 +1111,7 @@ static void invertGammaMask(bool isWhite, CGRGBPixel rgb[], int width,
|
||||
rgb = (CGRGBPixel*)((char*)rgb + rb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) {
|
||||
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) {
|
||||
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,
|
||||
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) {
|
||||
@ -1173,6 +1162,7 @@ static void lerpPixels(CGRGBPixel dst[], const CGRGBPixel src[], int width,
|
||||
dst = (CGRGBPixel*)((char*)dst + rowBytes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
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) {
|
||||
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;
|
||||
|
||||
|
@ -168,54 +168,3 @@ static void CGDataProviderReleaseData_FromMalloc(void*, const 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;
|
||||
}
|
||||
|
||||
|
@ -7,11 +7,12 @@
|
||||
#define COMPONENTS_JSDEBUGGER_H
|
||||
|
||||
#include "IJSDebugger.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace jsdebugger {
|
||||
|
||||
class JSDebugger : public IJSDebugger
|
||||
class JSDebugger MOZ_FINAL : public IJSDebugger
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -108,7 +108,7 @@ _newJSDContext(JSRuntime* jsrt,
|
||||
JS_BeginRequest(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 )
|
||||
goto label_newJSDContext_failure;
|
||||
|
@ -98,6 +98,7 @@ case "$target" in
|
||||
fi
|
||||
|
||||
dnl set up compilers
|
||||
TOOLCHAIN_PREFIX="$android_toolchain/bin/$android_tool_prefix-"
|
||||
AS="$android_toolchain"/bin/"$android_tool_prefix"-as
|
||||
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
|
||||
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++
|
||||
|
@ -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)
|
||||
|
||||
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_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(basename $(@F)).pp)
|
||||
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)/$(@F).pp)
|
||||
EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
|
||||
EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
|
||||
EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC)
|
||||
|
@ -286,7 +286,7 @@ endif
|
||||
|
||||
ifndef MOZ_AUTO_DEPS
|
||||
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
|
||||
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:.$(OBJ_SUFFIX)=.pp))
|
||||
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:=.pp))
|
||||
ifndef NO_GEN_XPT
|
||||
MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
|
||||
endif
|
||||
|
@ -4208,7 +4208,7 @@ MOZ_ARG_DISABLE_BOOL(md,
|
||||
fi])
|
||||
if test "$_cpp_md_flag"; then
|
||||
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
|
||||
if test "$SOLARIS_SUNPRO_CC"; then
|
||||
_DEPEND_CFLAGS=
|
||||
@ -4539,8 +4539,10 @@ elif test "$OS_ARCH" != "WINNT" -a "$OS_ARCH" != "OS2"; then
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(threadsafe,
|
||||
[ --enable-threadsafe Enable support for multiple threads.],
|
||||
[AC_DEFINE(JS_THREADSAFE)],)
|
||||
[ --enable-threadsafe Enable support for multiple threads.],
|
||||
[if test "x$enableval" = "xyes"; then
|
||||
AC_DEFINE(JS_THREADSAFE)
|
||||
fi],)
|
||||
|
||||
if test "$MOZ_DEBUG"; then
|
||||
AC_DEFINE(MOZ_REFLOW_PERF)
|
||||
|
@ -822,7 +822,6 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
|
||||
*/
|
||||
ScopeCoordinate sc;
|
||||
if (JOF_OPTYPE(pn->getOp()) == JOF_QARG) {
|
||||
JS_ASSERT(bce->sc->funIsHeavyweight());
|
||||
sc.hops = ClonedBlockDepth(bce);
|
||||
sc.slot = bce->sc->bindings.argToSlot(pn->pn_cookie.slot());
|
||||
} else {
|
||||
|
@ -1249,7 +1249,8 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
|
||||
end = vp + obj->getDenseArrayInitializedLength();
|
||||
goto scan_value_array;
|
||||
} else {
|
||||
JS_ASSERT_IF(runtime->gcIncrementalState != NO_INCREMENTAL,
|
||||
JS_ASSERT_IF(runtime->gcMode == JSGC_MODE_INCREMENTAL &&
|
||||
runtime->gcIncrementalEnabled,
|
||||
clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS);
|
||||
}
|
||||
clasp->trace(this, obj);
|
||||
|
@ -16,9 +16,6 @@
|
||||
|
||||
#include "js/Utility.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
struct Cell;
|
||||
|
@ -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 *
|
||||
ExplainReason(gcreason::Reason reason)
|
||||
{
|
||||
|
12
js/src/jit-test/tests/basic/bug719750.js
Normal file
12
js/src/jit-test/tests/basic/bug719750.js
Normal 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();
|
||||
|
14
js/src/jit-test/tests/basic/bug767234.js
Normal file
14
js/src/jit-test/tests/basic/bug767234.js
Normal 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();
|
7
js/src/jit-test/tests/basic/testBug766064.js
Normal file
7
js/src/jit-test/tests/basic/testBug766064.js
Normal file
@ -0,0 +1,7 @@
|
||||
function loop(actual = 0) {
|
||||
if (function() { actual++ })
|
||||
{}
|
||||
return actual;
|
||||
}
|
||||
|
||||
assertEq(loop(), 0);
|
@ -7,9 +7,6 @@ load(libdir + "asserts.js");
|
||||
var dbg = new Debugger;
|
||||
assertThrowsInstanceOf(function () { dbg.addDebuggee(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
|
||||
var d1 = newGlobal('new-compartment');
|
||||
|
@ -61,4 +61,3 @@ test("Object.create(null, {x: {value: 3}, y: {get: Math.min}})");
|
||||
test("[]");
|
||||
test("[,,,,,]");
|
||||
test("[0, 1, 2]");
|
||||
test("newGlobal('same-compartment')");
|
||||
|
@ -32,8 +32,8 @@ for (var i = 0; i < N; i++) {
|
||||
var obj = xarr[i];
|
||||
for (j = 0; j < M; j++) {
|
||||
assertEq(obj instanceof Debugger.Object, true);
|
||||
g2arr[i].eval("x = x.__proto__ = {};");
|
||||
obj = obj.proto;
|
||||
g2arr[i].eval("x = x.prop = {};");
|
||||
obj = obj.getOwnPropertyDescriptor("prop").value;;
|
||||
assertEq("seen" in obj, false);
|
||||
obj.seen = true;
|
||||
gc();
|
||||
|
@ -63,9 +63,9 @@ BEGIN_TEST(testBug604087)
|
||||
{
|
||||
JSObject *outerObj = js::Wrapper::New(cx, global, global->getProto(), global,
|
||||
&OuterWrapper::singleton);
|
||||
JSObject *compartment2 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *compartment3 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *compartment4 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *compartment2 = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *compartment3 = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *compartment4 = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
|
||||
|
||||
JSObject *c2wrapper = wrap(cx, outerObj, compartment2);
|
||||
CHECK(c2wrapper);
|
||||
|
@ -35,7 +35,7 @@ CustomMethod(JSContext *cx, unsigned argc, Value *vp)
|
||||
BEGIN_TEST(test_CallNonGenericMethodOnProxy)
|
||||
{
|
||||
// Create the first global object and compartment
|
||||
JSObject *globalA = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *globalA = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
|
||||
CHECK(globalA);
|
||||
|
||||
JSObject *customA = JS_NewObject(cx, &CustomClass, NULL, NULL);
|
||||
@ -51,7 +51,7 @@ BEGIN_TEST(test_CallNonGenericMethodOnProxy)
|
||||
|
||||
// Now create the second global object and compartment...
|
||||
{
|
||||
JSObject *globalB = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *globalB = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
|
||||
CHECK(globalB);
|
||||
|
||||
// ...and enter it.
|
||||
|
@ -49,7 +49,7 @@ BEGIN_TEST(testChromeBuffer)
|
||||
JSFunction *fun;
|
||||
JSObject *o;
|
||||
|
||||
CHECK(o = JS_NewCompartmentAndGlobalObject(cx, &global_class, &system_principals));
|
||||
CHECK(o = JS_NewGlobalObject(cx, &global_class, &system_principals));
|
||||
trusted_glob.set(o);
|
||||
|
||||
/*
|
||||
|
@ -150,7 +150,7 @@ END_TEST(testDebugger_throwHook)
|
||||
BEGIN_TEST(testDebugger_debuggerObjectVsDebugMode)
|
||||
{
|
||||
CHECK(JS_DefineDebuggerObject(cx, global));
|
||||
JSObject *debuggee = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
JSObject *debuggee = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
|
||||
CHECK(debuggee);
|
||||
|
||||
{
|
||||
@ -192,51 +192,36 @@ BEGIN_TEST(testDebugger_newScriptHook)
|
||||
{
|
||||
// Test that top-level indirect eval fires the newScript hook.
|
||||
CHECK(JS_DefineDebuggerObject(cx, global));
|
||||
JSObject *g1, *g2;
|
||||
g1 = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
CHECK(g1);
|
||||
JSObject *g;
|
||||
g = JS_NewGlobalObject(cx, getGlobalClass(), NULL);
|
||||
CHECK(g);
|
||||
{
|
||||
JSAutoEnterCompartment ae;
|
||||
CHECK(ae.enter(cx, g1));
|
||||
CHECK(JS_InitStandardClasses(cx, g1));
|
||||
g2 = JS_NewGlobalObject(cx, getGlobalClass());
|
||||
CHECK(g2);
|
||||
CHECK(JS_InitStandardClasses(cx, g2));
|
||||
CHECK(ae.enter(cx, g));
|
||||
CHECK(JS_InitStandardClasses(cx, g));
|
||||
}
|
||||
|
||||
JSObject *g1Wrapper = g1;
|
||||
CHECK(JS_WrapObject(cx, &g1Wrapper));
|
||||
jsval v = OBJECT_TO_JSVAL(g1Wrapper);
|
||||
CHECK(JS_SetProperty(cx, global, "g1", &v));
|
||||
JSObject *gWrapper = g;
|
||||
CHECK(JS_WrapObject(cx, &gWrapper));
|
||||
jsval v = OBJECT_TO_JSVAL(gWrapper);
|
||||
CHECK(JS_SetProperty(cx, global, "g", &v));
|
||||
|
||||
JSObject *g2Wrapper = g2;
|
||||
CHECK(JS_WrapObject(cx, &g2Wrapper));
|
||||
v = OBJECT_TO_JSVAL(g2Wrapper);
|
||||
CHECK(JS_SetProperty(cx, global, "g2", &v));
|
||||
|
||||
EXEC("var dbg = Debugger(g1);\n"
|
||||
EXEC("var dbg = Debugger(g);\n"
|
||||
"var hits = 0;\n"
|
||||
"dbg.onNewScript = function (s) {\n"
|
||||
" hits += Number(s instanceof Debugger.Script);\n"
|
||||
"};\n");
|
||||
|
||||
// Since g1 is a debuggee and g2 is not, g1.eval should trigger newScript
|
||||
// and g2.eval should not, regardless of what scope object we use to enter
|
||||
// the compartment.
|
||||
// Since g is a debuggee, g.eval should trigger newScript, regardless of
|
||||
// what scope object we use to enter the compartment.
|
||||
//
|
||||
// (Not all scripts are permanently associated with specific global
|
||||
// objects, but eval scripts are, so we deliver them only to debuggers that
|
||||
// are watching that particular global.)
|
||||
// Scripts are associated with the global where they're compiled, so we
|
||||
// deliver them only to debuggers that are watching that particular global.
|
||||
//
|
||||
bool ok = true;
|
||||
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;
|
||||
return testIndirectEval(g, "Math.abs(0)");
|
||||
}
|
||||
|
||||
bool testIndirectEval(JSObject *scope, JSObject *g, const char *code, int expectedHits)
|
||||
bool testIndirectEval(JSObject *scope, const char *code)
|
||||
{
|
||||
EXEC("hits = 0;");
|
||||
|
||||
@ -247,12 +232,12 @@ bool testIndirectEval(JSObject *scope, JSObject *g, const char *code, int expect
|
||||
CHECK(codestr);
|
||||
jsval argv[1] = { STRING_TO_JSVAL(codestr) };
|
||||
jsval v;
|
||||
CHECK(JS_CallFunctionName(cx, g, "eval", 1, argv, &v));
|
||||
CHECK(JS_CallFunctionName(cx, scope, "eval", 1, argv, &v));
|
||||
}
|
||||
|
||||
jsval hitsv;
|
||||
EVAL("hits", &hitsv);
|
||||
CHECK_SAME(hitsv, INT_TO_JSVAL(expectedHits));
|
||||
CHECK_SAME(hitsv, INT_TO_JSVAL(1));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testDebugger_newScriptHook)
|
||||
|
@ -354,7 +354,7 @@ class JSAPITest
|
||||
|
||||
virtual JSObject * createGlobal(JSPrincipals *principals = NULL) {
|
||||
/* Create the global object. */
|
||||
JSObject *global = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), principals);
|
||||
JSObject *global = JS_NewGlobalObject(cx, getGlobalClass(), principals);
|
||||
if (!global)
|
||||
return NULL;
|
||||
|
||||
|
@ -751,6 +751,7 @@ JSRuntime::JSRuntime()
|
||||
gcZealFrequency(0),
|
||||
gcNextScheduled(0),
|
||||
gcDeterministicOnly(false),
|
||||
gcIncrementalLimit(0),
|
||||
#endif
|
||||
gcCallback(NULL),
|
||||
gcSliceCallback(NULL),
|
||||
@ -1404,14 +1405,8 @@ JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
GlobalObject *global = target->getGlobalObjectOrNull();
|
||||
if (!global) {
|
||||
SwitchToCompartment sc(cx, target->compartment());
|
||||
global = GlobalObject::create(cx, &dummy_class);
|
||||
if (!global)
|
||||
return NULL;
|
||||
}
|
||||
return JS_EnterCrossCompartmentCall(cx, global);
|
||||
GlobalObject &global = target->compartment()->global();
|
||||
return JS_EnterCrossCompartmentCall(cx, &global);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
@ -3317,16 +3312,6 @@ JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
|
||||
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 {
|
||||
public:
|
||||
explicit AutoHoldCompartment(JSCompartment *compartment JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
@ -3345,10 +3330,12 @@ class AutoHoldCompartment {
|
||||
};
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals)
|
||||
JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
|
||||
JSCompartment *compartment = NewCompartment(cx, principals);
|
||||
if (!compartment)
|
||||
return NULL;
|
||||
@ -3357,10 +3344,10 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *pr
|
||||
|
||||
JSCompartment *saved = cx->compartment;
|
||||
cx->setCompartment(compartment);
|
||||
JSObject *obj = JS_NewGlobalObject(cx, clasp);
|
||||
GlobalObject *global = GlobalObject::create(cx, Valueify(clasp));
|
||||
cx->setCompartment(saved);
|
||||
|
||||
return obj;
|
||||
return global;
|
||||
}
|
||||
|
||||
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"
|
||||
" 5: Verify write barriers between paints\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, ',');
|
||||
zeal = atoi(env);
|
||||
|
@ -3935,10 +3935,7 @@ extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_NewGlobalObject(JSContext *cx, JSClass *clasp);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals);
|
||||
JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
|
||||
|
@ -591,8 +591,9 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
* gcNextScheduled is decremented. When it reaches zero, we do either a
|
||||
* full or a compartmental GC, based on gcDebugCompartmentGC.
|
||||
*
|
||||
* At this point, if gcZeal_ == 2 then gcNextScheduled is reset to the
|
||||
* value of gcZealFrequency. Otherwise, no additional GCs take place.
|
||||
* At this point, if gcZeal_ is one of the types that trigger periodic
|
||||
* collection, then gcNextScheduled is reset to the value of
|
||||
* gcZealFrequency. Otherwise, no additional GCs take place.
|
||||
*
|
||||
* You can control these values in several ways:
|
||||
* - 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
|
||||
* 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
|
||||
int gcZeal_;
|
||||
int gcZealFrequency;
|
||||
int gcNextScheduled;
|
||||
bool gcDeterministicOnly;
|
||||
int gcIncrementalLimit;
|
||||
|
||||
js::Vector<JSObject *, 0, js::SystemAllocPolicy> gcSelectedForMarking;
|
||||
|
||||
@ -617,8 +622,12 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
|
||||
bool needZealousGC() {
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -224,8 +224,13 @@ class CompartmentChecker
|
||||
JSCompartment *compartment;
|
||||
|
||||
public:
|
||||
explicit CompartmentChecker(JSContext *cx) : context(cx), compartment(cx->compartment) {
|
||||
check(cx->hasfp() ? JS_GetGlobalForScopeChain(cx) : cx->globalObject);
|
||||
explicit CompartmentChecker(JSContext *cx)
|
||||
: context(cx), compartment(cx->compartment)
|
||||
{
|
||||
if (cx->compartment) {
|
||||
GlobalObject *global = GetGlobalForScopeChain(cx);
|
||||
JS_ASSERT(cx->compartment->global() == *global);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -42,12 +42,14 @@ using namespace js::gc;
|
||||
JSCompartment::JSCompartment(JSRuntime *rt)
|
||||
: rt(rt),
|
||||
principals(NULL),
|
||||
global_(NULL),
|
||||
needsBarrier_(false),
|
||||
gcState(NoGCScheduled),
|
||||
gcPreserveCode(false),
|
||||
gcBytes(0),
|
||||
gcTriggerBytes(0),
|
||||
hold(false),
|
||||
isSystemCompartment(false),
|
||||
lastCodeRelease(0),
|
||||
typeLifoAlloc(TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
data(NULL),
|
||||
|
@ -122,6 +122,20 @@ struct JSCompartment
|
||||
JSRuntime *rt;
|
||||
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;
|
||||
|
||||
private:
|
||||
|
@ -603,7 +603,15 @@ enum Reason {
|
||||
GCREASONS(MAKE_REASON)
|
||||
#undef MAKE_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 */
|
||||
|
@ -3487,19 +3487,6 @@ SweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool *startBackgroundSweep)
|
||||
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
|
||||
* heap in order to trace through it...
|
||||
@ -3654,12 +3641,23 @@ class AutoCopyFreeListToArenas {
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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) {
|
||||
rt->gcIncrementalState = MARK_ROOTS;
|
||||
rt->gcLastMarkSlice = false;
|
||||
@ -3668,9 +3666,11 @@ IncrementalMarkSlice(JSRuntime *rt, int64_t budget, JSGCInvocationKind gckind, b
|
||||
if (rt->gcIncrementalState == MARK_ROOTS) {
|
||||
BeginMarkPhase(rt);
|
||||
rt->gcIncrementalState = MARK;
|
||||
|
||||
if (zeal == ZealIncrementalRootsThenFinish)
|
||||
return;
|
||||
}
|
||||
|
||||
*shouldSweep = false;
|
||||
if (rt->gcIncrementalState == MARK) {
|
||||
SliceBudget sliceBudget(budget);
|
||||
|
||||
@ -3695,7 +3695,11 @@ IncrementalMarkSlice(JSRuntime *rt, int64_t budget, JSGCInvocationKind gckind, b
|
||||
}
|
||||
if (finished) {
|
||||
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;
|
||||
} else {
|
||||
EndMarkPhase(rt);
|
||||
@ -3796,7 +3800,7 @@ BudgetIncrementalGC(JSRuntime *rt, int64_t *budget)
|
||||
* the marking implementation.
|
||||
*/
|
||||
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
|
||||
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. */
|
||||
ResetIncrementalGC(rt, "requested");
|
||||
rt->gcStats.nonincremental("requested");
|
||||
budget = SliceBudget::Unlimited;
|
||||
} else {
|
||||
BudgetIncrementalGC(rt, &budget);
|
||||
}
|
||||
|
||||
bool shouldSweep;
|
||||
if (budget == SliceBudget::Unlimited && rt->gcIncrementalState == NO_INCREMENTAL) {
|
||||
NonIncrementalMark(rt, gckind);
|
||||
shouldSweep = true;
|
||||
} else {
|
||||
IncrementalMarkSlice(rt, budget, gckind, &shouldSweep);
|
||||
}
|
||||
IncrementalMarkSlice(rt, budget, reason, &shouldSweep);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (rt->gcIncrementalState == NO_INCREMENTAL) {
|
||||
@ -3903,7 +3903,8 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget,
|
||||
#ifdef JS_GC_ZEAL
|
||||
bool restartVerify = rt->gcVerifyData &&
|
||||
rt->gcZeal() == ZealVerifierValue &&
|
||||
reason != gcreason::CC_FORCED;
|
||||
reason != gcreason::CC_FORCED &&
|
||||
rt->hasContexts();
|
||||
|
||||
struct AutoVerifyBarriers {
|
||||
JSRuntime *runtime;
|
||||
@ -3954,7 +3955,7 @@ Collect(JSRuntime *rt, bool incremental, int64_t budget,
|
||||
}
|
||||
|
||||
rt->gcPoke = false;
|
||||
GCCycle(rt, incremental, budget, gckind);
|
||||
GCCycle(rt, incremental, budget, gckind, reason);
|
||||
|
||||
if (rt->gcIncrementalState == NO_INCREMENTAL) {
|
||||
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_GC_END);
|
||||
@ -4186,8 +4187,32 @@ void
|
||||
RunDebugGC(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
JSRuntime *rt = 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
|
||||
}
|
||||
|
||||
|
@ -1081,6 +1081,9 @@ const int ZealVerifierValue = 4;
|
||||
const int ZealFrameVerifierValue = 5;
|
||||
const int ZealStackRootingSafeValue = 6;
|
||||
const int ZealStackRootingValue = 7;
|
||||
const int ZealIncrementalRootsThenFinish = 8;
|
||||
const int ZealIncrementalMarkAllThenFinish = 9;
|
||||
const int ZealIncrementalMultipleSlices = 10;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
||||
|
@ -1434,6 +1434,7 @@ JSScript::ensureHasTypes(JSContext *cx)
|
||||
inline bool
|
||||
JSScript::ensureRanAnalysis(JSContext *cx, JSObject *scope)
|
||||
{
|
||||
js::analyze::AutoEnterAnalysis aea(cx->compartment);
|
||||
JSScript *self = this;
|
||||
JS::SkipRoot root(cx, &self);
|
||||
|
||||
|
@ -1366,8 +1366,8 @@ GeneratorWriteBarrierPre(JSContext *cx, JSGenerator *gen)
|
||||
* stack or closed. Barriers when copying onto the stack or closing preserve
|
||||
* gc invariants.
|
||||
*/
|
||||
static bool
|
||||
GeneratorHasMarkableFrame(JSGenerator *gen)
|
||||
bool
|
||||
js::GeneratorHasMarkableFrame(JSGenerator *gen)
|
||||
{
|
||||
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. */
|
||||
gen->regs.rebaseFromTo(stackRegs, *genfp);
|
||||
genfp->copyFrameAndValues<HeapValue, Value, StackFrame::DoPostBarrier>(
|
||||
cx, genvp, stackfp, stackvp, stackRegs.sp);
|
||||
genfp->copyFrameAndValues<StackFrame::DoPostBarrier>(cx, (Value *)genvp, stackfp,
|
||||
stackvp, stackRegs.sp);
|
||||
|
||||
obj->setPrivate(gen);
|
||||
return obj;
|
||||
|
@ -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:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
@ -316,6 +316,13 @@ struct JSGenerator
|
||||
|
||||
extern JSObject *
|
||||
js_NewGenerator(JSContext *cx);
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
GeneratorHasMarkableFrame(JSGenerator *gen);
|
||||
|
||||
} /* namespace js */
|
||||
#endif
|
||||
|
||||
extern JSObject *
|
||||
|
@ -2802,6 +2802,7 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
|
||||
JS_ASSERT(clasp != &ArrayClass);
|
||||
JS_ASSERT_IF(clasp == &FunctionClass,
|
||||
kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind);
|
||||
JS_ASSERT_IF(parent, parent->global() == cx->compartment->global());
|
||||
|
||||
RootedTypeObject type(cx, type_);
|
||||
|
||||
@ -2815,8 +2816,10 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
|
||||
return NULL;
|
||||
|
||||
JSObject *obj = JSObject::create(cx, kind, shape, type, slots);
|
||||
if (!obj)
|
||||
if (!obj) {
|
||||
cx->free_(slots);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This will cancel an already-running incremental GC from doing any more
|
||||
|
@ -1223,6 +1223,7 @@ JSObject::global() const
|
||||
JSObject *obj = const_cast<JSObject *>(this);
|
||||
while (JSObject *parent = obj->getParent())
|
||||
obj = parent;
|
||||
JS_ASSERT(obj->asGlobal() == compartment()->global());
|
||||
return obj->asGlobal();
|
||||
}
|
||||
|
||||
|
@ -2559,7 +2559,7 @@ static JSClass sandbox_class = {
|
||||
static JSObject *
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
@ -3230,24 +3230,11 @@ Compile(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static JSClass dummy_class = {
|
||||
"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;
|
||||
|
||||
JSObject *global = JS_GetGlobalForScopeChain(cx);
|
||||
JSString *scriptContents = JSVAL_TO_STRING(arg0);
|
||||
|
||||
unsigned oldopts = JS_GetOptions(cx);
|
||||
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_SetOptions(cx, oldopts);
|
||||
|
||||
@ -3425,33 +3412,13 @@ Deserialize(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
enum CompartmentKind { SAME_COMPARTMENT, NEW_COMPARTMENT };
|
||||
|
||||
static JSObject *
|
||||
NewGlobalObject(JSContext *cx, CompartmentKind compartment);
|
||||
NewGlobalObject(JSContext *cx);
|
||||
|
||||
static JSBool
|
||||
NewGlobal(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
if (argc != 1 || !JSVAL_IS_STRING(JS_ARGV(cx, vp)[0])) {
|
||||
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);
|
||||
JSObject *global = NewGlobalObject(cx);
|
||||
if (!global)
|
||||
return false;
|
||||
|
||||
@ -4589,13 +4556,9 @@ DestroyContext(JSContext *cx, bool withGC)
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
NewGlobalObject(JSContext *cx, CompartmentKind compartment)
|
||||
NewGlobalObject(JSContext *cx)
|
||||
{
|
||||
RootedObject glob(cx);
|
||||
|
||||
glob = (compartment == NEW_COMPARTMENT)
|
||||
? JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL)
|
||||
: JS_NewGlobalObject(cx, &global_class);
|
||||
RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, NULL));
|
||||
if (!glob)
|
||||
return NULL;
|
||||
|
||||
@ -4640,7 +4603,7 @@ NewGlobalObject(JSContext *cx, CompartmentKind compartment)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (compartment == NEW_COMPARTMENT && !JS_WrapObject(cx, glob.address()))
|
||||
if (!JS_WrapObject(cx, glob.address()))
|
||||
return NULL;
|
||||
|
||||
return glob;
|
||||
@ -4846,7 +4809,7 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
|
||||
}
|
||||
|
||||
RootedObject glob(cx);
|
||||
glob = NewGlobalObject(cx, NEW_COMPARTMENT);
|
||||
glob = NewGlobalObject(cx);
|
||||
if (!glob)
|
||||
return 1;
|
||||
|
||||
@ -4865,7 +4828,7 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
|
||||
class ShellWorkerHooks : public js::workers::WorkerHooks {
|
||||
public:
|
||||
JSObject *newGlobalObject(JSContext *cx) {
|
||||
return NewGlobalObject(cx, NEW_COMPARTMENT);
|
||||
return NewGlobalObject(cx);
|
||||
}
|
||||
};
|
||||
ShellWorkerHooks hooks;
|
||||
|
@ -242,26 +242,27 @@ GlobalObject::create(JSContext *cx, Class *clasp)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
if (!obj->setDelegate(cx))
|
||||
return NULL;
|
||||
|
||||
/* Construct a regexp statics object for this global object. */
|
||||
JSObject *res = RegExpStatics::create(cx, obj);
|
||||
JSObject *res = RegExpStatics::create(cx, global);
|
||||
if (!res)
|
||||
return NULL;
|
||||
obj->initSlot(REGEXP_STATICS, ObjectValue(*res));
|
||||
obj->initFlags(0);
|
||||
global->initSlot(REGEXP_STATICS, ObjectValue(*res));
|
||||
global->initFlags(0);
|
||||
|
||||
return obj;
|
||||
return global;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
@ -97,30 +97,37 @@ StackFrame::initDummyFrame(JSContext *cx, JSObject &chain)
|
||||
scopeChain_ = &chain;
|
||||
}
|
||||
|
||||
template <class T, class U, StackFrame::TriggerPostBarriers doPostBarrier>
|
||||
template <StackFrame::TriggerPostBarriers doPostBarrier>
|
||||
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((Value *)othervp == otherfp->generatorArgsSnapshotBegin());
|
||||
JS_ASSERT(vp == (Value *)this - ((Value *)otherfp - othervp));
|
||||
JS_ASSERT(othervp == otherfp->generatorArgsSnapshotBegin());
|
||||
JS_ASSERT(othersp >= otherfp->slots());
|
||||
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. */
|
||||
U *srcend = (U *)otherfp->generatorArgsSnapshotEnd();
|
||||
T *dst = vp;
|
||||
for (U *src = othervp; src < srcend; src++, dst++)
|
||||
const Value *srcend = otherfp->generatorArgsSnapshotEnd();
|
||||
Value *dst = vp;
|
||||
for (const Value *src = othervp; src < srcend; src++, dst++) {
|
||||
*dst = *src;
|
||||
if (doPostBarrier)
|
||||
HeapValue::writeBarrierPost(*dst, dst);
|
||||
}
|
||||
|
||||
*this = *otherfp;
|
||||
if (doPostBarrier)
|
||||
writeBarrierPost();
|
||||
|
||||
srcend = (U *)othersp;
|
||||
dst = (T *)slots();
|
||||
for (U *src = (U *)otherfp->slots(); src < srcend; src++, dst++)
|
||||
srcend = othersp;
|
||||
dst = slots();
|
||||
for (const Value *src = otherfp->slots(); src < srcend; src++, dst++) {
|
||||
*dst = *src;
|
||||
if (doPostBarrier)
|
||||
HeapValue::writeBarrierPost(*dst, dst);
|
||||
}
|
||||
|
||||
if (cx->compartment->debugMode())
|
||||
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. */
|
||||
template
|
||||
void StackFrame::copyFrameAndValues<Value, HeapValue, StackFrame::NoPostBarrier>(
|
||||
JSContext *, Value *, StackFrame *, HeapValue *, Value *);
|
||||
void StackFrame::copyFrameAndValues<StackFrame::NoPostBarrier>(
|
||||
JSContext *, Value *, StackFrame *, const Value *, Value *);
|
||||
template
|
||||
void StackFrame::copyFrameAndValues<HeapValue, Value, StackFrame::DoPostBarrier>(
|
||||
JSContext *, HeapValue *, StackFrame *, Value *, Value *);
|
||||
void StackFrame::copyFrameAndValues<StackFrame::DoPostBarrier>(
|
||||
JSContext *, Value *, StackFrame *, const Value *, Value *);
|
||||
|
||||
void
|
||||
StackFrame::writeBarrierPost()
|
||||
@ -1145,8 +1152,8 @@ ContextStack::pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrame
|
||||
JSObject::writeBarrierPre(gen->obj);
|
||||
|
||||
/* Copy from the generator's floating frame to the stack. */
|
||||
stackfp->copyFrameAndValues<Value, HeapValue, StackFrame::NoPostBarrier>(
|
||||
cx, stackvp, gen->fp, genvp, gen->regs.sp);
|
||||
stackfp->copyFrameAndValues<StackFrame::NoPostBarrier>(cx, stackvp, gen->fp,
|
||||
Valueify(genvp), gen->regs.sp);
|
||||
stackfp->resetGeneratorPrev(cx);
|
||||
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. */
|
||||
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->fp->copyFrameAndValues<HeapValue, Value, StackFrame::DoPostBarrier>(
|
||||
cx_, genvp, stackfp, stackvp, stackRegs.sp);
|
||||
gen->fp->copyFrameAndValues<StackFrame::DoPostBarrier>(cx_, (Value *)genvp, stackfp,
|
||||
stackvp, stackRegs.sp);
|
||||
}
|
||||
|
||||
/* ~FrameGuard/popFrame will finish the popping. */
|
||||
|
@ -999,8 +999,9 @@ class StackFrame
|
||||
DoPostBarrier = true,
|
||||
NoPostBarrier = false
|
||||
};
|
||||
template <class T, class U, TriggerPostBarriers doPostBarrier>
|
||||
void copyFrameAndValues(JSContext *cx, T *vp, StackFrame *otherfp, U *othervp, Value *othersp);
|
||||
template <TriggerPostBarriers doPostBarrier>
|
||||
void copyFrameAndValues(JSContext *cx, Value *vp, StackFrame *otherfp,
|
||||
const Value *othervp, Value *othersp);
|
||||
|
||||
JSGenerator *maybeSuspendedGenerator(JSRuntime *rt);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user