Merge from mozilla-central.

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

View File

@ -266,17 +266,14 @@ let MigratorPrototype = {
getService(Ci.nsIObserver);
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();

View File

@ -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 {

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1446,10 +1446,6 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png);
}
.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

View File

@ -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

View File

@ -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++

View File

@ -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" +

View File

@ -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@

View File

@ -736,8 +736,8 @@ OPTIMIZE_JARS_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/optimizeja
CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
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)

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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")

View File

@ -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 + ")" +

View File

@ -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);
}

View File

@ -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);

View File

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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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)

View File

@ -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.
*/

View File

@ -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',

View File

@ -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,

View File

@ -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()

View File

@ -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 = []

View File

@ -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]

View File

@ -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")

View File

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

View File

@ -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])

View File

@ -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'")

View File

@ -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);
};
""")

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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,

View File

@ -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),

View File

@ -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;
}

View File

@ -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))

View File

@ -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,

View File

@ -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.

View File

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

View File

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

View File

@ -251,7 +251,7 @@ static void count_left_right_zeros(const uint8_t* row, int width,
*riteZ = zeros;
}
#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);

View File

@ -273,64 +273,6 @@ bool SkBlitMask::BlitColor(const SkBitmap& device, const SkMask& mask,
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) {
int i, octuple = (count + 7) >> 3;
for (i = 0; i < octuple; ++i) {
int m = *mask++;
if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); }
if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); }
if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); }
if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); }
if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); }
if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); }
if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); }
src += 8;
dst += 8;
}
count &= 7;
if (count > 0) {
int m = *mask;
do {
if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
m <<= 1;
src += 1;
dst += 1;
} while (--count > 0);
}
}
static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
const uint8_t* SK_RESTRICT mask,
const SkPMColor* SK_RESTRICT src, int count) {
int i, octuple = (count + 7) >> 3;
for (i = 0; i < octuple; ++i) {
int m = *mask++;
if (m & 0x80) { dst[0] = src[0]; }
if (m & 0x40) { dst[1] = src[1]; }
if (m & 0x20) { dst[2] = src[2]; }
if (m & 0x10) { dst[3] = src[3]; }
if (m & 0x08) { dst[4] = src[4]; }
if (m & 0x04) { dst[5] = src[5]; }
if (m & 0x02) { dst[6] = src[6]; }
if (m & 0x01) { dst[7] = src[7]; }
src += 8;
dst += 8;
}
count &= 7;
if (count > 0) {
int m = *mask;
do {
if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
m <<= 1;
src += 1;
dst += 1;
} while (--count > 0);
}
}
static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
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,

View File

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

View File

@ -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();

View File

@ -925,10 +925,6 @@ static int operate(const SkRegion::RunType a_runs[],
interval, but we can first trim off the const overhead of the initial TOP
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?

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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++

View File

@ -736,8 +736,8 @@ OPTIMIZE_JARS_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/optimizeja
CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
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)

View File

@ -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

View File

@ -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)

View File

@ -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 {

View File

@ -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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,9 +7,6 @@ load(libdir + "asserts.js");
var dbg = new Debugger;
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');

View File

@ -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')");

View File

@ -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();

View File

@ -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);

View File

@ -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.

View File

@ -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);
/*

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}
/*

View File

@ -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),

View File

@ -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:

View File

@ -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 */

View File

@ -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
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -1,4 +1,4 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=78:
*
* 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 *

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View File

@ -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. */

View File

@ -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