Transplant the initial merge electrolysis to mozilla-central, revision 8ef83d174df3, back onto the Lorentz/1.9.2 branch.
Transplant the initial merge electrolysis to mozilla-central, revision 8ef83d174df3, back onto the Lorentz/1.9.2 branch.
--- a/.hgtags
+++ b/.hgtags
@@ -27,17 +27,27 @@ 0000000000000000000000000000000000000000
0cd41f5990807fb6ab52cb59ba3c8e8247281045 GECKO_1_9_1_BASE
8df5a90281cd4d75835e4b7696da200555eed15f GECKO_1_9_1_BASE
8a601ed6bc4c7b3d1e35aa9e81f257512d984bd5 FENNEC_A2
d7d64f68423b68a671f623f123e90057ebc49dac UPDATE_PACKAGING_R7
fb32f6e1859c07846a01b4478a7b1678019e0b45 UPDATE_PACKAGING_R7
f817a4378f32b1ad0a7c4b5a9949586dba816da5 FENNEC_M11
5c1e7c779b6edc8ff912001990edc579f80597f4 FENNEC_B1
fe9cc55b8db7f56f7e68a246acba363743854979 UPDATE_PACKAGING_R8
+6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-r15462
+6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-latest
376b78fc72230aaf2ca4e279a8f4ef1efd4a1d9f GECKO_1_9_2_BASE
+941ad9d7d079246481f365c3cfbfc75a5bbefc94 last-mozilla-central
+2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
+2bae3bbf866e7de2a4b2377e7c2f52cc9ac14a22 last-mozilla-central
+65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
+65c1582465efe99899189519fccaf7b2826fcb2e last-mozilla-central
+27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
+27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
+a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
f029575f82e4303241c14630c80a8fc05a997ac7 UPDATE_PACKAGING_R9
f029575f82e4303241c14630c80a8fc05a997ac7 UPDATE_PACKAGING_R10
cc96a47d605c79215e25adb7aed5b8010e4ec512 FIREFOX_3_6b1_RELEASE
c60105da01a09ff3b902744879a58247f5717029 FIREFOX_3_6b1_RELEASE
cc96a47d605c79215e25adb7aed5b8010e4ec512 FIREFOX_3_6b1_BUILD1
c60105da01a09ff3b902744879a58247f5717029 FIREFOX_3_6b1_BUILD1
3596945fe21ef9974367519ec72d872e4435041f FENNEC_1_0_BUILD1
3596945fe21ef9974367519ec72d872e4435041f FENNEC_1_0_RELEASE
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -904,15 +904,17 @@ pref("browser.sessionstore.interval", 60
// Whether to use a panel that looks like an OS X sheet for customization
#ifdef XP_MACOSX
pref("toolbar.customization.usesheet", true);
#else
pref("toolbar.customization.usesheet", false);
#endif
+pref("dom.ipc.plugins.enabled", false);
+
#ifdef XP_WIN
#ifndef WINCE
pref("browser.taskbar.previews.enable", false);
pref("browser.taskbar.previews.max", 20);
pref("browser.taskbar.previews.cachetime", 20);
#endif
#endif
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -49,16 +49,19 @@
@BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
#ifdef XP_MACOSX
@BINPATH@/XUL
#else
@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
#endif
+#ifdef MOZ_IPC
+@BINPATH@/mozilla-runtime@BIN_SUFFIX@
+#endif
#ifdef WINCE
@BINPATH@/mozce_shunt.dll
#elifdef XP_WIN32
#ifndef MOZ_MEMORY
@BINPATH@/Microsoft.VC80.CRT.manifest
@BINPATH@/msvcm80.dll
@BINPATH@/msvcp80.dll
@BINPATH@/msvcr80.dll
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -101,16 +101,18 @@ MOZ_DEBUG_ENABLE_DEFS = @MOZ_DEBUG_ENAB
MOZ_DEBUG_DISABLE_DEFS = @MOZ_DEBUG_DISABLE_DEFS@
MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@
MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@
MOZ_DBGRINFO_MODULES = @MOZ_DBGRINFO_MODULES@
MOZ_EXTENSIONS = @MOZ_EXTENSIONS@
MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@
MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@
MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@
+MOZ_IPC = @MOZ_IPC@
+MOZ_IPDL_TESTS = @MOZ_IPDL_TESTS@
MOZ_PERF_METRICS = @MOZ_PERF_METRICS@
MOZ_LEAKY = @MOZ_LEAKY@
MOZ_MEMORY = @MOZ_MEMORY@
MOZ_JPROF = @MOZ_JPROF@
MOZ_SHARK = @MOZ_SHARK@
MOZ_CALLGRIND = @MOZ_CALLGRIND@
MOZ_VTUNE = @MOZ_VTUNE@
MOZ_TRACEVIS = @MOZ_TRACEVIS@
--- a/configure.in
+++ b/configure.in
@@ -456,21 +456,17 @@ fi
dnl Special win32 checks
dnl ========================================================
case "$target" in
*-wince)
WINVER=500
;;
*)
- if test -n "$GNU_CC"; then
- WINVER=501
- else
- WINVER=500
- fi
+ WINVER=502
;;
esac
dnl Target the Windows 7 SDK by default
WINSDK_TARGETVER=601
MOZ_ARG_WITH_STRING(windows-version,
[ --with-windows-version=WINSDK_TARGETVER
@@ -4174,17 +4170,17 @@ dnl are defined in build/autoconf/altopt
dnl ========================================================
dnl =
dnl = Check for external package dependencies
dnl =
dnl ========================================================
MOZ_ARG_HEADER(External Packages)
-MOZ_ENABLE_LIBXUL=
+MOZ_ENABLE_LIBXUL=1
MOZ_ARG_WITH_STRING(libxul-sdk,
[ --with-libxul-sdk=PFX Use the libXUL SDK at <PFX>],
LIBXUL_SDK_DIR=$withval)
if test "$LIBXUL_SDK_DIR" = "yes"; then
AC_MSG_ERROR([--with-libxul-sdk must specify a path])
elif test -n "$LIBXUL_SDK_DIR" -a "$LIBXUL_SDK_DIR" != "no"; then
@@ -5339,16 +5335,61 @@ dnl = JS Debugger XPCOM component (js/js
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(jsd,
[ --disable-jsd Disable JavaScript debug library],
MOZ_JSDEBUGGER=,
MOZ_JSDEBUGGER=1)
dnl ========================================================
+dnl = Disable IPC support for tabs and plugins
+dnl ========================================================
+MOZ_IPC=1
+
+case "${target}" in
+*-apple-darwin*)
+ MOZ_IPC=
+ ;;
+*wince)
+ MOZ_IPC=
+ ;;
+esac
+
+MOZ_ARG_DISABLE_BOOL(ipc,
+[ --disable-ipc Disable IPC supports for tabs and plugins],
+ MOZ_IPC=,
+ MOZ_IPC=1)
+
+if test -n "$MOZ_IPC"; then
+ AC_DEFINE(MOZ_IPC)
+fi
+
+AC_SUBST(MOZ_IPC)
+
+dnl ========================================================
+dnl = Enable IPDL's "expensive" unit tests
+dnl ========================================================
+MOZ_IPDL_TESTS=
+
+MOZ_ARG_ENABLE_BOOL(ipdl-tests,
+[ --enable-ipdl-tests Enable expensive IPDL tests],
+ MOZ_IPDL_TESTS=1,
+ MOZ_IPDL_TESTS=)
+
+if test -z "$MOZ_IPC" -a -n "$MOZ_IPDL_TESTS"; then
+ AC_MSG_ERROR([--enable-ipdl-tests requires --enable-ipc])
+fi
+
+if test -n "$MOZ_IPDL_TESTS"; then
+ AC_DEFINE(MOZ_IPDL_TESTS)
+fi
+
+AC_SUBST(MOZ_IPDL_TESTS)
+
+dnl ========================================================
dnl = Disable plugin support
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(plugins,
[ --disable-plugins Disable plugins support],
MOZ_PLUGINS=,
MOZ_PLUGINS=1)
dnl ========================================================
@@ -7373,16 +7414,17 @@ if test "$ac_nscap_nonconst_opeq_bug" =
AC_DEFINE(NSCAP_DONT_PROVIDE_NONCONST_OPEQ)
fi
fi # SKIP_COMPILER_CHECKS
dnl ========================================================
dnl C++ rtti
dnl Should be smarter and check that the compiler does indeed have rtti
dnl ========================================================
+
MOZ_ARG_ENABLE_BOOL(cpp-rtti,
[ --enable-cpp-rtti Enable C++ RTTI ],
[ _MOZ_USE_RTTI=1 ],
[ _MOZ_USE_RTTI= ])
if test "$_MOZ_USE_RTTI"; then
_MOZ_RTTI_FLAGS=$_MOZ_RTTI_FLAGS_ON
else
@@ -7481,34 +7523,33 @@ dnl =
dnl ========================================================
MOZ_ARG_HEADER(Static build options)
MOZ_ARG_ENABLE_BOOL(static,
[ --enable-static Enable building of internal static libs],
BUILD_STATIC_LIBS=1,
BUILD_STATIC_LIBS=)
-dnl Disable libxul in debug builds, but not for xulrunner.
-if test -n "$MOZ_DEBUG" -a "$MOZ_BUILD_APP" != "xulrunner"; then
- MOZ_ENABLE_LIBXUL=
-fi
-
MOZ_ARG_ENABLE_BOOL(libxul,
[ --enable-libxul Enable building of libxul],
MOZ_ENABLE_LIBXUL=1,
MOZ_ENABLE_LIBXUL=)
if test -n "$MOZ_STATIC_BUILD_UNSUPPORTED" -a -n "$BUILD_STATIC_LIBS"; then
AC_MSG_ERROR([--enable-static is not supported for building $MOZ_APP_NAME. You probably want --enable-libxul.])
fi
if test -n "$MOZ_ENABLE_LIBXUL" -a -n "$BUILD_STATIC_LIBS"; then
AC_MSG_ERROR([--enable-libxul is not compatible with --enable-static])
fi
+if test -n "$MOZ_IPC" -a -z "$MOZ_ENABLE_LIBXUL"; then
+ AC_MSG_ERROR([--enable-ipc requires --enable-libxul])
+fi
+
AC_SUBST(LIBXUL_LIBS)
if test -n "$MOZ_ENABLE_LIBXUL"; then
XPCOM_LIBS="$LIBXUL_LIBS"
AC_DEFINE(MOZ_ENABLE_LIBXUL)
else
if test -n "$BUILD_STATIC_LIBS"; then
AC_DEFINE(MOZ_STATIC_BUILD)
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -74,16 +74,17 @@ ifdef MOZ_SMIL
DIRS += interfaces/smil
endif
DIRS += \
public/coreEvents \
base \
src \
locales \
+ plugins \
$(NULL)
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/rules.mk
--- a/gfx/Makefile.in
+++ b/gfx/Makefile.in
@@ -45,15 +45,19 @@ include $(DEPTH)/config/autoconf.mk
MODULE = gfx
ifdef MOZ_TREE_CAIRO
DIRS = cairo
endif
DIRS += thebes public idl src qcms
+ifdef MOZ_IPC
+DIRS += ipc
+endif
+
ifdef ENABLE_TESTS
ifndef MOZ_ENABLE_LIBXUL
TOOL_DIRS += tests
endif
endif
include $(topsrcdir)/config/rules.mk
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -208,16 +208,19 @@ enum { XKeyPress = KeyPress };
#ifdef MOZ_WIDGET_QT
#include "gfxQtNativeRenderer.h"
#endif
#ifdef XP_WIN
#include <wtypes.h>
#include <winuser.h>
+#ifdef MOZ_IPC
+#define NS_OOPP_DOUBLEPASS_MSGID TEXT("MozDoublePassMsg")
+#endif
#endif
#ifdef CreateEvent // Thank you MS.
#undef CreateEvent
#endif
#ifdef PR_LOGGING
static PRLogModuleInfo *nsObjectFrameLM = PR_NewLogModule("nsObjectFrame");
@@ -672,16 +675,20 @@ NS_IMETHODIMP
nsObjectFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
NS_PRECONDITION(aContent, "How did that happen?");
mPreventInstantiation =
(aContent->GetCurrentDoc()->GetDisplayDocument() != nsnull);
+#ifdef XP_WIN
+ mDoublePassEvent = 0;
+#endif
+
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
("Initializing nsObjectFrame %p for content %p\n", this, aContent));
return nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow);
}
void
nsObjectFrame::Destroy()
@@ -1728,16 +1735,17 @@ nsObjectFrame::PaintPlugin(nsIRenderingC
if (window->type == nsPluginWindowType_Drawable) {
// check if we need to call SetWindow with updated parameters
PRBool doupdatewindow = PR_FALSE;
// the offset of the DC
nsPoint origin;
gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect);
+ PRBool doublePass = PR_FALSE;
do {
HDC hdc = nativeDraw.BeginNativeDrawing();
if (!hdc)
return;
RECT dest;
nativeDraw.TransformToNativeRect(frameGfxRect, dest);
RECT dirty;
@@ -1790,17 +1798,36 @@ nsObjectFrame::PaintPlugin(nsIRenderingC
inst->HandleEvent(&pluginEvent, &eventHandled);
}
inst->SetWindow(window);
}
mInstanceOwner->Paint(dirty, hdc);
nativeDraw.EndNativeDrawing();
- } while (nativeDraw.ShouldRenderAgain());
+ doublePass = nativeDraw.ShouldRenderAgain();
+#ifdef MOZ_IPC
+ if (doublePass) {
+ // OOP plugin specific: let the shim know we are in the middle of a double pass
+ // render. The second pass will reuse the previous rendering without going over
+ // the wire.
+ if (!mDoublePassEvent)
+ mDoublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
+ if (mDoublePassEvent) {
+ NPEvent pluginEvent;
+ pluginEvent.event = mDoublePassEvent;
+ pluginEvent.wParam = 0;
+ pluginEvent.lParam = 0;
+ PRBool eventHandled = PR_FALSE;
+
+ inst->HandleEvent(&pluginEvent, &eventHandled);
+ }
+ }
+#endif
+ } while (doublePass);
nativeDraw.PaintToContext();
} else if (!(ctx->GetFlags() & gfxContext::FLAG_DESTINED_FOR_SCREEN)) {
// Get PrintWindow dynamically since it's not present on Win2K,
// which we still support
typedef BOOL (WINAPI * PrintWindowPtr)
(HWND hwnd, HDC hdcBlt, UINT nFlags);
PrintWindowPtr printProc = nsnull;
--- a/layout/generic/nsObjectFrame.h
+++ b/layout/generic/nsObjectFrame.h
@@ -241,16 +241,19 @@ private:
private:
nsString mEventType;
};
nsRefPtr<nsPluginInstanceOwner> mInstanceOwner;
nsIView* mInnerView;
nsCOMPtr<nsIWidget> mWidget;
nsIntRect mWindowlessRect;
+#ifdef XP_WIN
+ PRUint32 mDoublePassEvent;
+#endif
// For assertions that make it easier to determine if a crash is due
// to the underlying problem described in bug 136927, and to prevent
// reentry into instantiation.
PRBool mPreventInstantiation;
};
class nsDisplayPlugin : public nsDisplayItem {
--- a/modules/plugin/base/src/Makefile.in
+++ b/modules/plugin/base/src/Makefile.in
@@ -141,16 +141,20 @@ EXTRA_DSO_LDOPTS = \
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
EXTRA_DSO_LDOPTS += $(TK_LIBS)
endif
ifndef WINCE
ENABLE_CXX_EXCEPTIONS = 1
endif
+include $(topsrcdir)/config/config.mk
+ifdef MOZ_IPC
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+endif
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH),WINNT)
OS_LIBS += $(call EXPAND_LIBNAME,version)
endif
ifeq ($(OS_ARCH), OpenVMS)
DEFINES += -DGENERIC_MOTIF_REDEFINES
--- a/modules/plugin/base/src/nsJSNPRuntime.cpp
+++ b/modules/plugin/base/src/nsJSNPRuntime.cpp
@@ -48,16 +48,18 @@
#include "nsIXPConnect.h"
#include "nsIDOMElement.h"
#include "prmem.h"
#include "nsIContent.h"
// FIXME(bug 332648): Give me a real API please!
#include "jscntxt.h"
+using namespace mozilla::plugins::parent;
+
// Hash of JSObject wrappers that wraps JSObjects as NPObjects. There
// will be one wrapper per JSObject per plugin instance, i.e. if two
// plugins access the JSObject x, two wrappers for x will be
// created. This is needed to be able to properly drop the wrappers
// when a plugin is torn down in case there's a leak in the plugin (we
// don't want to leak the world just because a plugin leaks an
// NPObject).
static PLDHashTable sJSObjWrappers;
@@ -73,16 +75,17 @@ static PRInt32 sWrapperCount;
// The JSRuntime. Used to unroot JSObjects when no JSContext is
// reachable.
static JSRuntime *sJSRuntime;
// The JS context stack, we use this to push a plugin's JSContext onto
// while executing JS on the context.
static nsIJSContextStack *sContextStack;
+static nsTArray<NPObject*>* sDelayedReleases;
// Helper class that reports any JS exceptions that were thrown while
// the plugin executed JS.
class AutoJSExceptionReporter
{
public:
AutoJSExceptionReporter(JSContext *cx)
@@ -193,27 +196,52 @@ static JSClass sNPObjectMemberClass =
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
JS_ResolveStub, NPObjectMember_Convert,
NPObjectMember_Finalize, nsnull, nsnull, NPObjectMember_Call,
nsnull, nsnull, nsnull, NPObjectMember_Mark, nsnull
};
static void
+OnWrapperDestroyed();
+
+static JSBool
+DelayedReleaseGCCallback(JSContext* cx, JSGCStatus status)
+{
+ if (JSGC_END == status) {
+ if (sDelayedReleases) {
+ for (PRInt32 i = 0; i < sDelayedReleases->Length(); ++i) {
+ NPObject* obj = (*sDelayedReleases)[i];
+ if (obj)
+ _releaseobject(obj);
+ OnWrapperDestroyed();
+ }
+ delete sDelayedReleases;
+ sDelayedReleases = NULL;
+ }
+ }
+ return JS_TRUE;
+}
+
+static void
OnWrapperCreated()
{
if (sWrapperCount++ == 0) {
static const char rtsvc_id[] = "@mozilla.org/js/xpc/RuntimeService;1";
nsCOMPtr<nsIJSRuntimeService> rtsvc(do_GetService(rtsvc_id));
if (!rtsvc)
return;
rtsvc->GetRuntime(&sJSRuntime);
NS_ASSERTION(sJSRuntime != nsnull, "no JSRuntime?!");
+ // Register our GC callback to perform delayed destruction of finalized
+ // NPObjects. Leave this callback around and don't ever unregister it.
+ rtsvc->RegisterGCCallback(DelayedReleaseGCCallback);
+
CallGetService("@mozilla.org/js/xpc/ContextStack;1", &sContextStack);
}
}
static void
OnWrapperDestroyed()
{
NS_ASSERTION(sWrapperCount, "Whaaa, unbalanced created/destroyed calls!");
@@ -483,21 +511,24 @@ ReportExceptionIfPending(JSContext *cx)
return JS_FALSE;
}
nsJSObjWrapper::nsJSObjWrapper(NPP npp)
: nsJSObjWrapperKey(nsnull, npp)
{
+ MOZ_COUNT_CTOR(nsJSObjWrapper);
OnWrapperCreated();
}
nsJSObjWrapper::~nsJSObjWrapper()
{
+ MOZ_COUNT_DTOR(nsJSObjWrapper);
+
// Invalidate first, since it relies on sJSRuntime and sJSObjWrappers.
NP_Invalidate(this);
OnWrapperDestroyed();
}
// static
NPObject *
@@ -1620,27 +1651,25 @@ NPObjWrapper_Convert(JSContext *cx, JSOb
return JS_TRUE;
}
static void
NPObjWrapper_Finalize(JSContext *cx, JSObject *obj)
{
NPObject *npobj = (NPObject *)::JS_GetPrivate(cx, obj);
-
if (npobj) {
if (sNPObjWrappers.ops) {
PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_REMOVE);
}
-
- // Let go of our NPObject
- _releaseobject(npobj);
}
- OnWrapperDestroyed();
+ if (!sDelayedReleases)
+ sDelayedReleases = new nsTArray<NPObject*>;
+ sDelayedReleases->AppendElement(npobj);
}
static JSBool
NPObjWrapper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval,
PR_FALSE);
@@ -1851,16 +1880,26 @@ NPObjWrapperPluginDestroyedCallback(PLDH
table->ops = nsnull;
NPObject *npobj = entry->mNPObj;
if (npobj->_class && npobj->_class->invalidate) {
npobj->_class->invalidate(npobj);
}
+#ifdef NS_BUILD_REFCNT_LOGGING
+ {
+ int32_t refCnt = npobj->referenceCount;
+ while (refCnt) {
+ --refCnt;
+ NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
+ }
+ }
+#endif
+
// Force deallocation of plugin objects since the plugin they came
// from is being torn down.
if (npobj->_class && npobj->_class->deallocate) {
npobj->_class->deallocate(npobj);
} else {
PR_Free(npobj);
}
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -31,18 +31,23 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#endif
+
#include "prtypes.h"
#include "prmem.h"
+#include "prenv.h"
#include "prclist.h"
#include "nsAutoLock.h"
#include "nsNPAPIPlugin.h"
#include "nsNPAPIPluginInstance.h"
#include "nsNPAPIPluginStreamListener.h"
#include "nsIServiceManager.h"
#include "nsThreadUtils.h"
#include "nsIPrivateBrowsingService.h"
@@ -82,98 +87,39 @@
#include <gdk/gdkx.h>
#include "gtk2xtbin.h"
#endif
#include "nsJSNPRuntime.h"
#include "nsIHttpAuthManager.h"
#include "nsICookieService.h"
+#include "mozilla/PluginLibrary.h"
+using mozilla::PluginLibrary;
+
+#include "mozilla/PluginPRLibrary.h"
+using mozilla::PluginPRLibrary;
+
+#ifdef MOZ_IPC
+#include "mozilla/plugins/PluginModuleParent.h"
+using mozilla::plugins::PluginModuleParent;
+#endif
+
static PRLock *sPluginThreadAsyncCallLock = nsnull;
static PRCList sPendingAsyncCalls = PR_INIT_STATIC_CLIST(&sPendingAsyncCalls);
// POST/GET stream type
enum eNPPStreamTypeInternal {
eNPPStreamTypeInternal_Get,
eNPPStreamTypeInternal_Post
};
static NS_DEFINE_IID(kMemoryCID, NS_MEMORY_CID);
-// Static stub functions that are exported to the plugin as entry
-// points via the CALLBACKS variable.
-PR_BEGIN_EXTERN_C
-
- static NPError NP_CALLBACK
- _requestread(NPStream *pstream, NPByteRange *rangeList);
-
- static NPError NP_CALLBACK
- _geturlnotify(NPP npp, const char* relativeURL, const char* target,
- void* notifyData);
-
- static NPError NP_CALLBACK
- _getvalue(NPP npp, NPNVariable variable, void *r_value);
-
- static NPError NP_CALLBACK
- _setvalue(NPP npp, NPPVariable variable, void *r_value);
-
- static NPError NP_CALLBACK
- _geturl(NPP npp, const char* relativeURL, const char* target);
-
- static NPError NP_CALLBACK
- _posturlnotify(NPP npp, const char* relativeURL, const char *target,
- uint32_t len, const char *buf, NPBool file, void* notifyData);
-
- static NPError NP_CALLBACK
- _posturl(NPP npp, const char* relativeURL, const char *target, uint32_t len,
- const char *buf, NPBool file);
-
- static NPError NP_CALLBACK
- _newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream);
-
- static int32_t NP_CALLBACK
- _write(NPP npp, NPStream *pstream, int32_t len, void *buffer);
-
- static NPError NP_CALLBACK
- _destroystream(NPP npp, NPStream *pstream, NPError reason);
-
- static void NP_CALLBACK
- _status(NPP npp, const char *message);
-
- static void NP_CALLBACK
- _memfree (void *ptr);
-
- static uint32_t NP_CALLBACK
- _memflush(uint32_t size);
-
- static void NP_CALLBACK
- _reloadplugins(NPBool reloadPages);
-
- static void NP_CALLBACK
- _invalidaterect(NPP npp, NPRect *invalidRect);
-
- static void NP_CALLBACK
- _invalidateregion(NPP npp, NPRegion invalidRegion);
-
- static void NP_CALLBACK
- _forceredraw(NPP npp);
-
- static const char* NP_CALLBACK
- _useragent(NPP npp);
-
- static void* NP_CALLBACK
- _memalloc (uint32_t size);
-
- // Deprecated entry points for the old Java plugin.
- static void* NP_CALLBACK /* OJI type: JRIEnv* */
- _getJavaEnv(void);
- static void* NP_CALLBACK /* OJI type: jref */
- _getJavaPeer(NPP npp);
-
-PR_END_EXTERN_C
+using namespace mozilla::plugins::parent;
// This function sends a notification using the observer service to any object
// registered to listen to the "experimental-notify-plugin-call" subject.
// Each "experimental-notify-plugin-call" notification carries with it the run
// time value in milliseconds that the call took to execute.
void NS_NotifyPluginCall(PRIntervalTime startTime)
{
PRIntervalTime endTime = PR_IntervalNow() - startTime;
@@ -280,62 +226,58 @@ nsNPAPIPlugin::nsNPAPIPlugin(nsIPluginOl
mShadow = aShadow;
fLibrary = nsnull;
fShutdownEntry = nsnull;
memset((void*) &fCallbacks, 0, sizeof(fCallbacks));
CheckClassInitialized();
}
#endif
-nsNPAPIPlugin::nsNPAPIPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary,
- NP_PLUGINSHUTDOWN aShutdown)
+nsNPAPIPlugin::nsNPAPIPlugin(NPPluginFuncs* callbacks,
+ PluginLibrary* aLibrary)
{
memset((void*) &fCallbacks, 0, sizeof(fCallbacks));
fLibrary = nsnull;
#ifdef OJI
mShadow = nsnull;
#endif
#if defined(XP_WIN) || defined(XP_OS2)
// On Windows (and Mac) we need to keep a direct reference to the
// fCallbacks and NOT just copy the struct. See Bugzilla 85334
- NP_GETENTRYPOINTS pfnGetEntryPoints =
- (NP_GETENTRYPOINTS)PR_FindSymbol(aLibrary, "NP_GetEntryPoints");
-
- if (!pfnGetEntryPoints)
+ NPError gepError;
+ nsresult gepResult = aLibrary->NP_GetEntryPoints(&fCallbacks, &gepError);
+ if (gepResult != NS_OK || gepError != NPERR_NO_ERROR)
return;
fCallbacks.size = sizeof(fCallbacks);
- nsresult result = pfnGetEntryPoints(&fCallbacks);
- NS_ASSERTION(result == NS_OK, "Failed to get callbacks");
-
NS_ASSERTION(HIBYTE(fCallbacks.version) >= NP_VERSION_MAJOR,
"callback version is less than NP version");
- fShutdownEntry = (NP_PLUGINSHUTDOWN)PR_FindSymbol(aLibrary, "NP_Shutdown");
#elif defined(XP_MACOSX)
NPPluginFuncs np_callbacks;
memset((void*) &np_callbacks, 0, sizeof(np_callbacks));
np_callbacks.size = sizeof(np_callbacks);
- fShutdownEntry = (NP_PLUGINSHUTDOWN)PR_FindSymbol(aLibrary, "NP_Shutdown");
- NP_GETENTRYPOINTS pfnGetEntryPoints = (NP_GETENTRYPOINTS)PR_FindSymbol(aLibrary, "NP_GetEntryPoints");
- NP_PLUGININIT pfnInitialize = (NP_PLUGININIT)PR_FindSymbol(aLibrary, "NP_Initialize");
- if (!pfnGetEntryPoints || !pfnInitialize || !fShutdownEntry) {
+ if (!aLibrary->HasRequiredFunctions()) {
NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
return;
}
// we call NP_Initialize before getting function pointers to match
// WebKit's behavior. They implemented this first on Mac OS X.
- if (pfnInitialize(&(nsNPAPIPlugin::CALLBACKS)) != NPERR_NO_ERROR)
+ NPError initError;
+ nsresult initResult = aLibrary->NP_Initialize(&(nsNPAPIPlugin::CALLBACKS), &initError);
+ if (initResult != NS_OK || initError != NPERR_NO_ERROR)
return;
- if (pfnGetEntryPoints(&np_callbacks) != NPERR_NO_ERROR)
+ NPError gepError;
+ nsresult gepResult = aLibrary->NP_GetEntryPoints(&np_callbacks, &gepError);
+ if (gepResult != NS_OK || gepError != NPERR_NO_ERROR)
return;
fCallbacks.size = sizeof(fCallbacks);
fCallbacks.version = np_callbacks.version;
fCallbacks.newp = (NPP_NewProcPtr)np_callbacks.newp;
fCallbacks.destroy = (NPP_DestroyProcPtr)np_callbacks.destroy;
fCallbacks.setwindow = (NPP_SetWindowProcPtr)np_callbacks.setwindow;
fCallbacks.newstream = (NPP_NewStreamProcPtr)np_callbacks.newstream;
@@ -345,115 +287,154 @@ nsNPAPIPlugin::nsNPAPIPlugin(NPPluginFun
fCallbacks.write = (NPP_WriteProcPtr)np_callbacks.write;
fCallbacks.print = (NPP_PrintProcPtr)np_callbacks.print;
fCallbacks.event = (NPP_HandleEventProcPtr)np_callbacks.event;
fCallbacks.urlnotify = (NPP_URLNotifyProcPtr)np_callbacks.urlnotify;
fCallbacks.getvalue = (NPP_GetValueProcPtr)np_callbacks.getvalue;
fCallbacks.setvalue = (NPP_SetValueProcPtr)np_callbacks.setvalue;
#else // for everyone else
memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks));
- fShutdownEntry = aShutdown;
#endif
fLibrary = aLibrary;
}
nsNPAPIPlugin::~nsNPAPIPlugin()
{
// reset the callbacks list
memset((void*) &fCallbacks, 0, sizeof(fCallbacks));
#ifdef OJI
NS_IF_RELEASE(mShadow);
#endif
+
+ delete fLibrary;
+ fLibrary = NULL;
}
#if defined(XP_MACOSX)
void
nsNPAPIPlugin::SetPluginRefNum(short aRefNum)
{
fPluginRefNum = aRefNum;
}
#endif
+namespace {
+
+#ifdef MOZ_IPC
+
+inline PRBool
+OOPPluginsEnabled()
+{
+ if (PR_GetEnv("MOZ_DISABLE_OOP_PLUGINS")) {
+ return PR_FALSE;
+ }
+
+ nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+ if (!prefs) {
+ return PR_FALSE;
+ }
+
+ PRBool oopPluginsEnabled = PR_FALSE;
+ prefs->GetBoolPref("dom.ipc.plugins.enabled", &oopPluginsEnabled);
+
+ if (!oopPluginsEnabled) {
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
+#endif // MOZ_IPC
+
+inline PluginLibrary*
+GetNewPluginLibrary(const char* aFilePath,
+ PRLibrary* aLibrary)
+{
+#ifdef MOZ_IPC
+ if (aFilePath && OOPPluginsEnabled()) {
+ return PluginModuleParent::LoadModule(aFilePath);
+ }
+#endif
+ return new PluginPRLibrary(aFilePath, aLibrary);
+}
+
+} /* anonymous namespace */
+
+
// Creates the nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
nsresult
nsNPAPIPlugin::CreatePlugin(const char* aFilePath, PRLibrary* aLibrary,
nsIPlugin** aResult)
{
CheckClassInitialized();
nsRefPtr<nsNPAPIPlugin> plugin;
#if defined(XP_UNIX) && !defined(XP_MACOSX)
NPPluginFuncs callbacks;
memset((void*) &callbacks, 0, sizeof(callbacks));
callbacks.size = sizeof(callbacks);
- NP_PLUGINSHUTDOWN pfnShutdown =
- (NP_PLUGINSHUTDOWN)PR_FindFunctionSymbol(aLibrary, "NP_Shutdown");
+ PluginLibrary* pluginLib = GetNewPluginLibrary(aFilePath, aLibrary);
// create the new plugin handler
- plugin =
- new nsNPAPIPlugin(&callbacks, aLibrary, pfnShutdown);
+ plugin = new nsNPAPIPlugin(&callbacks, pluginLib);
if (!plugin)
return NS_ERROR_OUT_OF_MEMORY;
// Do not initialize if the file path is NULL.
if (!aFilePath) {
*aResult = plugin.forget().get();
return NS_OK;
}
// we must init here because the plugin may call NPN functions
// when we call into the NP_Initialize entry point - NPN functions
// require that mBrowserManager be set up
plugin->Initialize();
- NP_PLUGINUNIXINIT pfnInitialize =
- (NP_PLUGINUNIXINIT)PR_FindFunctionSymbol(aLibrary, "NP_Initialize");
-
- if (!pfnInitialize)
- return NS_ERROR_UNEXPECTED;
-
- if (pfnInitialize(&(nsNPAPIPlugin::CALLBACKS),&callbacks) != NS_OK)
+ NPError initError;
+ nsresult initResult = pluginLib->NP_Initialize(&(nsNPAPIPlugin::CALLBACKS), &callbacks, &initError);
+ if (initResult != NS_OK || initError != NPERR_NO_ERROR)
return NS_ERROR_UNEXPECTED;
// now copy function table back to nsNPAPIPlugin instance
memcpy((void*) &(plugin->fCallbacks), (void*)&callbacks, sizeof(callbacks));
#endif
#ifdef XP_WIN
+ PluginLibrary* pluginLib = GetNewPluginLibrary(aFilePath, aLibrary);
+
// Note: on Windows, we must use the fCallback because plugins may
// change the function table. The Shockwave installer makes changes
// in the table while running
- plugin = new nsNPAPIPlugin(nsnull, aLibrary, nsnull);
+ plugin = new nsNPAPIPlugin(nsnull, pluginLib);
if (!plugin)
return NS_ERROR_OUT_OF_MEMORY;
// we must init here because the plugin may call NPN functions
// when we call into the NP_Initialize entry point - NPN functions
// require that mBrowserManager be set up
if (NS_FAILED(plugin->Initialize()))
return NS_ERROR_FAILURE;
- NP_PLUGININIT pfnInitialize =
- (NP_PLUGININIT)PR_FindSymbol(aLibrary, "NP_Initialize");
-
- if (!pfnInitialize)
- return NS_ERROR_UNEXPECTED;
-
- if (pfnInitialize(&(nsNPAPIPlugin::CALLBACKS)) != NS_OK)
- return NS_ERROR_UNEXPECTED;
+ NPError initError;
+ nsresult initResult = pluginLib->NP_Initialize(&(nsNPAPIPlugin::CALLBACKS), &initError);
+ if (initResult != NS_OK || initError != NPERR_NO_ERROR)
+ return NS_ERROR_FAILURE;
#endif
#ifdef XP_OS2
+ PluginLibrary* pluginLib = GetNewPluginLibrary(aFilePath, aLibrary);
+
// create the new plugin handler
- plugin = new nsNPAPIPlugin(nsnull, aLibrary, nsnull);
+ plugin = new nsNPAPIPlugin(nsnull, pluginLib);
if (!plugin)
return NS_ERROR_OUT_OF_MEMORY;
// we must init here because the plugin may call NPN functions
// when we call into the NP_Initialize entry point - NPN functions
// require that mBrowserManager be set up
if (NS_FAILED(plugin->Initialize()))
return NS_ERROR_FAILURE;
@@ -532,17 +513,18 @@ nsNPAPIPlugin::CreatePlugin(const char*
NS_NewNativeLocalFile(nsDependentCString(aFilePath), PR_TRUE,
getter_AddRefs(pluginPath));
nsPluginFile pluginFile(pluginPath);
#ifndef __LP64__
pluginRefNum = pluginFile.OpenPluginResource();
#endif
- plugin = new nsNPAPIPlugin(nsnull, aLibrary, nsnull);
+ PluginLibrary* pluginLib = GetNewPluginLibrary(aFilePath, aLibrary);
+ plugin = new nsNPAPIPlugin(nsnull, pluginLib);
#ifndef __LP64__
::UseResFile(appRefNum);
#endif
if (!plugin)
return NS_ERROR_OUT_OF_MEMORY;
if (NS_FAILED(plugin->Initialize()))
return NS_ERROR_FAILURE;
@@ -551,16 +533,18 @@ nsNPAPIPlugin::CreatePlugin(const char*
plugin->SetPluginRefNum(pluginRefNum);
#endif
#endif
#ifdef XP_BEOS
// I just copied UNIX version.
// Makoto Hamanaka <VYA04230@nifty.com>
+ // XXX this code won't compile with the new e10s changes
+
NPPluginFuncs callbacks;
memset((void*) &callbacks, 0, sizeof(callbacks));
callbacks.size = sizeof(callbacks);
NP_PLUGINSHUTDOWN pfnShutdown =
(NP_PLUGINSHUTDOWN)PR_FindSymbol(aLibrary, "NP_Shutdown");
// create the new plugin handler
@@ -815,72 +799,56 @@ nsNPAPIPlugin::Shutdown(void)
#ifdef OJI
if (mShadow)
return mShadow->Shutdown();
#endif
NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC,
("NPP Shutdown to be called: this=%p\n", this));
- if (fShutdownEntry) {
-#if defined(XP_MACOSX)
- (*fShutdownEntry)();
- if (fPluginRefNum > 0)
- ::CloseResFile(fPluginRefNum);
-#else
- NS_TRY_SAFE_CALL_VOID(fShutdownEntry(), fLibrary, nsnull);
+ NPError shutdownError;
+ fLibrary->NP_Shutdown(&shutdownError);
+#ifdef XP_MACOSX
+ if (shutdownError == NS_OK && fPluginRefNum > 0)
+ ::CloseResFile(fPluginRefNum);
#endif
- fShutdownEntry = nsnull;
- }
-
- PLUGIN_LOG(PLUGIN_LOG_NORMAL,
- ("NPAPIPlugin Shutdown done, this=%p", this));
return NS_OK;
}
nsresult
nsNPAPIPlugin::GetMIMEDescription(const char* *resultingDesc)
{
#ifdef OJI
if (mShadow)
return mShadow->GetMIMEDescription(resultingDesc);
#endif
- const char* (*npGetMIMEDescription)() =
- (const char* (*)()) PR_FindFunctionSymbol(fLibrary, "NP_GetMIMEDescription");
-
- *resultingDesc = npGetMIMEDescription ? npGetMIMEDescription() : "";
-
- PLUGIN_LOG(PLUGIN_LOG_NORMAL,
- ("nsNPAPIPlugin::GetMIMEDescription called: this=%p, result=%s\n",
- this, *resultingDesc));
+ nsresult gmdResult = fLibrary->NP_GetMIMEDescription((char**)resultingDesc);
+ if (gmdResult != NS_OK) {
+ return gmdResult;
+ }
return NS_OK;
}
nsresult
nsNPAPIPlugin::GetValue(nsPluginVariable variable, void *value)
{
#ifdef OJI
if (mShadow)
return mShadow->GetValue(variable, value);
#endif
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("nsNPAPIPlugin::GetValue called: this=%p, variable=%d\n", this, variable));
- NPError (*npGetValue)(void*, nsPluginVariable, void*) =
- (NPError (*)(void*, nsPluginVariable, void*)) PR_FindFunctionSymbol(fLibrary,
- "NP_GetValue");
-
- if (npGetValue && NPERR_NO_ERROR == npGetValue(nsnull, variable, value)) {
- return NS_OK;
- }
-
- return NS_ERROR_FAILURE;
+ NPError gvError;
+ fLibrary->NP_GetValue(nsnull, variable, value, &gvError);
+
+ return gvError;
}
// Create a new NPP GET or POST (given in the type argument) url
// stream that may have a notify callback
NPError
MakeNewNPAPIStreamInternal(NPP npp, const char *relativeURL, const char *target,
eNPPStreamTypeInternal type,
PRBool bDoNotify = PR_FALSE,
@@ -922,20 +890,327 @@ MakeNewNPAPIStreamInternal(NPP npp, cons
}
default:
NS_ASSERTION(0, "how'd I get here");
}
return NPERR_NO_ERROR;
}
+#if defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_WINCE)
+extern "C" size_t malloc_usable_size(const void *ptr);
+#endif
+
+namespace {
+
+static char *gNPPException;
+
+// A little helper class used to wrap up plugin manager streams (that is,
+// streams from the plugin to the browser).
+class nsNPAPIStreamWrapper : nsISupports
+{
+public:
+ NS_DECL_ISUPPORTS
+
+protected:
+ nsIOutputStream *fStream;
+ NPStream fNPStream;
+
+public:
+ nsNPAPIStreamWrapper(nsIOutputStream* stream);
+ ~nsNPAPIStreamWrapper();
+
+ void GetStream(nsIOutputStream* &result);
+ NPStream* GetNPStream(void) { return &fNPStream; }
+};
+
+class nsPluginThreadRunnable : public nsRunnable,
+ public PRCList
+{
+public:
+ nsPluginThreadRunnable(NPP instance, PluginThreadCallback func,
+ void *userData);
+ virtual ~nsPluginThreadRunnable();
+
+ NS_IMETHOD Run();
+
+ PRBool IsForInstance(NPP instance)
+ {
+ return (mInstance == instance);
+ }
+
+ void Invalidate()
+ {
+ mFunc = nsnull;
+ }
+
+ PRBool IsValid()
+ {
+ return (mFunc != nsnull);
+ }
+
+private:
+ NPP mInstance;
+ PluginThreadCallback mFunc;
+ void *mUserData;
+};
+
+static nsIDocument *
+GetDocumentFromNPP(NPP npp)
+{
+ NS_ENSURE_TRUE(npp, nsnull);
+
+ nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
+ NS_ENSURE_TRUE(inst, nsnull);
+
+ PluginDestructionGuard guard(inst);
+
+ nsCOMPtr<nsIPluginInstanceOwner> owner;
+ inst->GetOwner(getter_AddRefs(owner));
+ NS_ENSURE_TRUE(owner, nsnull);
+
+ nsCOMPtr<nsIDocument> doc;
+ owner->GetDocument(getter_AddRefs(doc));
+
+ return doc;
+}
+
+static JSContext *
+GetJSContextFromDoc(nsIDocument *doc)
+{
+ nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
+ NS_ENSURE_TRUE(sgo, nsnull);
+
+ nsIScriptContext *scx = sgo->GetContext();
+ NS_ENSURE_TRUE(scx, nsnull);
+
+ return (JSContext *)scx->GetNativeContext();
+}
+
+static JSContext *
+GetJSContextFromNPP(NPP npp)
+{
+ nsIDocument *doc = GetDocumentFromNPP(npp);
+ NS_ENSURE_TRUE(doc, nsnull);
+
+ return GetJSContextFromDoc(doc);
+}
+
+static NPIdentifier
+doGetIdentifier(JSContext *cx, const NPUTF8* name)
+{
+ NS_ConvertUTF8toUTF16 utf16name(name);
+
+ JSString *str = ::JS_InternUCStringN(cx, (jschar *)utf16name.get(),
+ utf16name.Length());
+
+ if (!str)
+ return NULL;
+
+ return (NPIdentifier)STRING_TO_JSVAL(str);
+}
+
+#if defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_WINCE)
+BOOL
+InHeap(HANDLE hHeap, LPVOID lpMem)
+{
+ BOOL success = FALSE;
+ PROCESS_HEAP_ENTRY he;
+ he.lpData = NULL;
+ while (HeapWalk(hHeap, &he) != 0) {
+ if (he.lpData == lpMem) {
+ success = TRUE;
+ break;
+ }
+ }
+ HeapUnlock(hHeap);
+ return success;
+}
+#endif
+
+} /* anonymous namespace */
+
+NS_IMPL_ISUPPORTS1(nsNPAPIStreamWrapper, nsISupports)
+
+nsNPAPIStreamWrapper::nsNPAPIStreamWrapper(nsIOutputStream* stream)
+: fStream(stream)
+{
+ NS_ASSERTION(stream, "bad stream");
+
+ fStream = stream;
+ NS_ADDREF(fStream);
+
+ memset(&fNPStream, 0, sizeof(fNPStream));
+ fNPStream.ndata = (void*) this;
+}
+
+nsNPAPIStreamWrapper::~nsNPAPIStreamWrapper(void)
+{
+ fStream->Close();
+ NS_IF_RELEASE(fStream);
+}
+
+void
+nsNPAPIStreamWrapper::GetStream(nsIOutputStream* &result)
+{
+ result = fStream;
+ NS_IF_ADDREF(fStream);
+}
+
+NPPExceptionAutoHolder::NPPExceptionAutoHolder()
+ : mOldException(gNPPException)
+{
+ gNPPException = nsnull;
+}
+
+NPPExceptionAutoHolder::~NPPExceptionAutoHolder()
+{
+ NS_ASSERTION(!gNPPException, "NPP exception not properly cleared!");
+
+ gNPPException = mOldException;
+}
+
+nsPluginThreadRunnable::nsPluginThreadRunnable(NPP instance,
+ PluginThreadCallback func,
+ void *userData)
+ : mInstance(instance), mFunc(func), mUserData(userData)
+{
+ if (!sPluginThreadAsyncCallLock) {
+ // Failed to create lock, not much we can do here then...
+ mFunc = nsnull;
+
+ return;
+ }
+
+ PR_INIT_CLIST(this);
+
+ {
+ nsAutoLock lock(sPluginThreadAsyncCallLock);
+
+ nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
+ if (!inst || !inst->IsStarted()) {
+ // The plugin was stopped, ignore this async call.
+ mFunc = nsnull;
+
+ return;
+ }
+
+ PR_APPEND_LINK(this, &sPendingAsyncCalls);
+ }
+}
+
+nsPluginThreadRunnable::~nsPluginThreadRunnable()
+{
+ if (!sPluginThreadAsyncCallLock) {
+ return;
+ }
+
+ {
+ nsAutoLock lock(sPluginThreadAsyncCallLock);
+
+ PR_REMOVE_LINK(this);
+ }
+}
+
+NS_IMETHODIMP
+nsPluginThreadRunnable::Run()
+{
+ if (mFunc) {
+ PluginDestructionGuard guard(mInstance);
+
+ NS_TRY_SAFE_CALL_VOID(mFunc(mUserData), nsnull, nsnull);
+ }
+
+ return NS_OK;
+}
+
+void
+OnPluginDestroy(NPP instance)
+{
+ if (!sPluginThreadAsyncCallLock) {
+ return;
+ }
+
+ {
+ nsAutoLock lock(sPluginThreadAsyncCallLock);
+
+ if (PR_CLIST_IS_EMPTY(&sPendingAsyncCalls)) {
+ return;
+ }
+
+ nsPluginThreadRunnable *r =
+ (nsPluginThreadRunnable *)PR_LIST_HEAD(&sPendingAsyncCalls);
+
+ do {
+ if (r->IsForInstance(instance)) {
+ r->Invalidate();
+ }
+
+ r = (nsPluginThreadRunnable *)PR_NEXT_LINK(r);
+ } while (r != &sPendingAsyncCalls);
+ }
+}
+
+void
+OnShutdown()
+{
+ NS_ASSERTION(PR_CLIST_IS_EMPTY(&sPendingAsyncCalls),
+ "Pending async plugin call list not cleaned up!");
+
+ if (sPluginThreadAsyncCallLock) {
+ nsAutoLock::DestroyLock(sPluginThreadAsyncCallLock);
+
+ sPluginThreadAsyncCallLock = nsnull;
+ }
+}
+
+void
+EnterAsyncPluginThreadCallLock()
+{
+ if (sPluginThreadAsyncCallLock) {
+ PR_Lock(sPluginThreadAsyncCallLock);
+ }
+}
+
+void
+ExitAsyncPluginThreadCallLock()
+{
+ if (sPluginThreadAsyncCallLock) {
+ PR_Unlock(sPluginThreadAsyncCallLock);
+ }
+}
+
+NPP NPPStack::sCurrentNPP = nsnull;
+
+const char *
+PeekException()
+{
+ return gNPPException;
+}
+
+void
+PopException()
+{
+ NS_ASSERTION(gNPPException, "Uh, no NPP exception to pop!");
+
+ if (gNPPException) {
+ free(gNPPException);
+
+ gNPPException = nsnull;
+ }
+}
+
//
// Static callbacks that get routed back through the new C++ API
//
+namespace mozilla {
+namespace plugins {
+namespace parent {
+
NPError NP_CALLBACK
_geturl(NPP npp, const char* relativeURL, const char* target)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_geturl called from the wrong thread\n"));
return NPERR_INVALID_PARAM;
}
@@ -987,16 +1262,19 @@ NPError NP_CALLBACK
NPError NP_CALLBACK
_posturlnotify(NPP npp, const char *relativeURL, const char *target,
uint32_t len, const char *buf, NPBool file, void *notifyData)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_posturlnotify called from the wrong thread\n"));
return NPERR_INVALID_PARAM;
}
+ if (!buf)
+ return NPERR_INVALID_PARAM;
+
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_PostURLNotify: npp=%p, target=%s, len=%d, file=%d, "
"notify=%p, url=%s, buf=%s\n",
(void*)npp, target, len, file, notifyData, relativeURL,
buf));
PluginDestructionGuard guard(npp);
@@ -1020,62 +1298,16 @@ NPError NP_CALLBACK
PluginDestructionGuard guard(npp);
return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
eNPPStreamTypeInternal_Post, PR_FALSE, nsnull,
len, buf, file);
}
-// A little helper class used to wrap up plugin manager streams (that is,
-// streams from the plugin to the browser).
-class nsNPAPIStreamWrapper : nsISupports
-{
-public:
- NS_DECL_ISUPPORTS
-
-protected:
- nsIOutputStream *fStream;
- NPStream fNPStream;
-
-public:
- nsNPAPIStreamWrapper(nsIOutputStream* stream);
- ~nsNPAPIStreamWrapper();
-
- void GetStream(nsIOutputStream* &result);
- NPStream* GetNPStream(void) { return &fNPStream; }
-};
-
-NS_IMPL_ISUPPORTS1(nsNPAPIStreamWrapper, nsISupports)
-
-nsNPAPIStreamWrapper::nsNPAPIStreamWrapper(nsIOutputStream* stream)
-: fStream(stream)
-{
- NS_ASSERTION(stream, "bad stream");
-
- fStream = stream;
- NS_ADDREF(fStream);
-
- memset(&fNPStream, 0, sizeof(fNPStream));
- fNPStream.ndata = (void*) this;
-}
-
-nsNPAPIStreamWrapper::~nsNPAPIStreamWrapper(void)
-{
- fStream->Close();
- NS_IF_RELEASE(fStream);
-}
-
-void
-nsNPAPIStreamWrapper::GetStream(nsIOutputStream* &result)
-{
- result = fStream;
- NS_IF_ADDREF(fStream);
-}
-
NPError NP_CALLBACK
_newstream(NPP npp, NPMIMEType type, const char* target, NPStream* *result)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_newstream called from the wrong thread\n"));
return NPERR_INVALID_PARAM;
}
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
@@ -1311,57 +1543,16 @@ void NP_CALLBACK
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
PluginDestructionGuard guard(inst);
inst->ForceRedraw();
}
-static nsIDocument *
-GetDocumentFromNPP(NPP npp)
-{
- NS_ENSURE_TRUE(npp, nsnull);
-
- nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
- NS_ENSURE_TRUE(inst, nsnull);
-
- PluginDestructionGuard guard(inst);
-
- nsCOMPtr<nsIPluginInstanceOwner> owner;
- inst->GetOwner(getter_AddRefs(owner));
- NS_ENSURE_TRUE(owner, nsnull);
-
- nsCOMPtr<nsIDocument> doc;
- owner->GetDocument(getter_AddRefs(doc));
-
- return doc;
-}
-
-static JSContext *
-GetJSContextFromDoc(nsIDocument *doc)
-{
- nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
- NS_ENSURE_TRUE(sgo, nsnull);
-
- nsIScriptContext *scx = sgo->GetContext();
- NS_ENSURE_TRUE(scx, nsnull);
-
- return (JSContext *)scx->GetNativeContext();
-}
-
-static JSContext *
-GetJSContextFromNPP(NPP npp)
-{
- nsIDocument *doc = GetDocumentFromNPP(npp);
- NS_ENSURE_TRUE(doc, nsnull);
-
- return GetJSContextFromDoc(doc);
-}
-
NPObject* NP_CALLBACK
_getwindowobject(NPP npp)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getwindowobject called from the wrong thread\n"));
return nsnull;
}
JSContext *cx = GetJSContextFromNPP(npp);
@@ -1405,30 +1596,16 @@ NPObject* NP_CALLBACK
JSObject* obj = nsnull;
holder->GetJSObject(&obj);
NS_ENSURE_TRUE(obj, nsnull);
return nsJSObjWrapper::GetNewOrUsed(npp, cx, obj);
}
-static NPIdentifier
-doGetIdentifier(JSContext *cx, const NPUTF8* name)
-{
- NS_ConvertUTF8toUTF16 utf16name(name);
-
- JSString *str = ::JS_InternUCStringN(cx, (jschar *)utf16name.get(),
- utf16name.Length());
-
- if (!str)
- return NULL;
-
- return (NPIdentifier)STRING_TO_JSVAL(str);
-}
-
NPIdentifier NP_CALLBACK
_getstringidentifier(const NPUTF8* name)
{
if (!name) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS, ("NPN_getstringidentifier: passed null name"));
return NULL;
}
if (!NS_IsMainThread()) {
@@ -1564,47 +1741,50 @@ NPObject* NP_CALLBACK
npobj = aClass->allocate(npp, aClass);
} else {
npobj = (NPObject *)PR_Malloc(sizeof(NPObject));
}
if (npobj) {
npobj->_class = aClass;
npobj->referenceCount = 1;
+ NS_LOG_ADDREF(npobj, 1, "BrowserNPObject", sizeof(NPObject));
}
NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
("Created NPObject %p, NPClass %p\n", npobj, aClass));
return npobj;
}
NPObject* NP_CALLBACK
_retainobject(NPObject* npobj)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_retainobject called from the wrong thread\n"));
}
if (npobj) {
- PR_AtomicIncrement((PRInt32*)&npobj->referenceCount);
+ int32_t refCnt = PR_AtomicIncrement((PRInt32*)&npobj->referenceCount);
+ NS_LOG_ADDREF(npobj, refCnt, "BrowserNPObject", sizeof(NPObject));
}
return npobj;
}
void NP_CALLBACK
_releaseobject(NPObject* npobj)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releaseobject called from the wrong thread\n"));
}
if (!npobj)
return;
int32_t refCnt = PR_AtomicDecrement((PRInt32*)&npobj->referenceCount);
+ NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
if (refCnt == 0) {
nsNPObjWrapper::OnDestroy(npobj);
NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
("Deleting NPObject %p, refcount hit 0\n", npobj));
if (npobj->_class && npobj->_class->deallocate) {
@@ -1892,36 +2072,16 @@ bool NP_CALLBACK
}
NPPExceptionAutoHolder nppExceptionHolder;
NPPAutoPusher nppPusher(npp);
return npobj->_class->construct(npobj, args, argCount, result);
}
-#if defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_WINCE)
-extern "C" size_t malloc_usable_size(const void *ptr);
-
-BOOL
-InHeap(HANDLE hHeap, LPVOID lpMem)
-{
- BOOL success = FALSE;
- PROCESS_HEAP_ENTRY he;
- he.lpData = NULL;
- while (HeapWalk(hHeap, &he) != 0) {
- if (he.lpData == lpMem) {
- success = TRUE;
- break;
- }
- }
- HeapUnlock(hHeap);
- return success;
-}
-#endif
-
void NP_CALLBACK
_releasevariantvalue(NPVariant* variant)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releasevariantvalue called from the wrong thread\n"));
}
switch (variant->type) {
case NPVariantType_Void :
@@ -1982,18 +2142,16 @@ bool NP_CALLBACK
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_tostring called from the wrong thread\n"));
return false;
}
return false;
}
-static char *gNPPException;
-
void NP_CALLBACK
_setexception(NPObject* npobj, const NPUTF8 *message)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setexception called from the wrong thread\n"));
return;
}
@@ -2001,47 +2159,16 @@ void NP_CALLBACK
// If a plugin throws multiple exceptions, we'll only report the
// last one for now.
free(gNPPException);
}
gNPPException = strdup(message);
}
-const char *
-PeekException()
-{
- return gNPPException;
-}
-
-void
-PopException()
-{
- NS_ASSERTION(gNPPException, "Uh, no NPP exception to pop!");
-
- if (gNPPException) {
- free(gNPPException);
-
- gNPPException = nsnull;
- }
-}
-
-NPPExceptionAutoHolder::NPPExceptionAutoHolder()
- : mOldException(gNPPException)
-{
- gNPPException = nsnull;
-}
-
-NPPExceptionAutoHolder::~NPPExceptionAutoHolder()
-{
- NS_ASSERTION(!gNPPException, "NPP exception not properly cleared!");
-
- gNPPException = mOldException;
-}
-
NPError NP_CALLBACK
_getvalue(NPP npp, NPNVariable variable, void *result)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getvalue called from the wrong thread\n"));
return NPERR_INVALID_PARAM;
}
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetValue: npp=%p, var=%d\n",
@@ -2152,17 +2279,17 @@ NPError NP_CALLBACK
*(NPBool*)result = PR_FALSE;
#endif
return NPERR_NO_ERROR;
}
case NPNVWindowNPObject: {
*(NPObject **)result = _getwindowobject(npp);
- return NPERR_NO_ERROR;
+ return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
}
case NPNVPluginElementNPObject: {
*(NPObject **)result = _getpluginelement(npp);
return NPERR_NO_ERROR;
}
@@ -2474,101 +2601,16 @@ void NP_CALLBACK
}
nsNPAPIPluginInstance *inst = npp ? (nsNPAPIPluginInstance *)npp->ndata : NULL;
if (!inst)
return;
inst->PopPopupsEnabledState();
}
-class nsPluginThreadRunnable : public nsRunnable,
- public PRCList
-{
-public:
- nsPluginThreadRunnable(NPP instance, PluginThreadCallback func,
- void *userData);
- virtual ~nsPluginThreadRunnable();
-
- NS_IMETHOD Run();
-
- PRBool IsForInstance(NPP instance)
- {
- return (mInstance == instance);
- }
-
- void Invalidate()
- {
- mFunc = nsnull;
- }
-
- PRBool IsValid()
- {
- return (mFunc != nsnull);
- }
-
-private:
- NPP mInstance;
- PluginThreadCallback mFunc;
- void *mUserData;
-};
-
-nsPluginThreadRunnable::nsPluginThreadRunnable(NPP instance,
- PluginThreadCallback func,
- void *userData)
- : mInstance(instance), mFunc(func), mUserData(userData)
-{
- if (!sPluginThreadAsyncCallLock) {
- // Failed to create lock, not much we can do here then...
- mFunc = nsnull;
-
- return;
- }
-
- PR_INIT_CLIST(this);
-
- {
- nsAutoLock lock(sPluginThreadAsyncCallLock);
-
- nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
- if (!inst || !inst->IsStarted()) {
- // The plugin was stopped, ignore this async call.
- mFunc = nsnull;
-
- return;
- }
-
- PR_APPEND_LINK(this, &sPendingAsyncCalls);
- }
-}
-
-nsPluginThreadRunnable::~nsPluginThreadRunnable()
-{
- if (!sPluginThreadAsyncCallLock) {
- return;
- }
-
- {
- nsAutoLock lock(sPluginThreadAsyncCallLock);
-
- PR_REMOVE_LINK(this);
- }
-}
-
-NS_IMETHODIMP
-nsPluginThreadRunnable::Run()
-{
- if (mFunc) {
- PluginDestructionGuard guard(mInstance);
-
- NS_TRY_SAFE_CALL_VOID(mFunc(mUserData), nsnull, nsnull);
- }
-
- return NS_OK;
-}
-
void NP_CALLBACK
_pluginthreadasynccall(NPP instance, PluginThreadCallback func, void *userData)
{
if (NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from the main thread\n"));
} else {
NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from a non main thread\n"));
}
@@ -2741,90 +2783,31 @@ NPError NP_CALLBACK
*ulen = *username ? uname8.Length() : 0;
*password = ToNewCString(pwd8);
*plen = *password ? pwd8.Length() : 0;
return NPERR_NO_ERROR;
}
-// We need extern "C" here because it has a function pointer as an argument.
-// See Bug 501889.
-PR_BEGIN_EXTERN_C
uint32_t NP_CALLBACK
-_scheduletimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID))
+_scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc timerFunc)
{
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
if (!inst)
return 0;
return inst->ScheduleTimer(interval, repeat, timerFunc);
}
-PR_END_EXTERN_C
void NP_CALLBACK
_unscheduletimer(NPP instance, uint32_t timerID)
{
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
if (!inst)
return;
inst->UnscheduleTimer(timerID);
}
-void
-OnPluginDestroy(NPP instance)
-{
- if (!sPluginThreadAsyncCallLock) {
- return;
- }
-
- {
- nsAutoLock lock(sPluginThreadAsyncCallLock);
-
- if (PR_CLIST_IS_EMPTY(&sPendingAsyncCalls)) {
- return;
- }
-
- nsPluginThreadRunnable *r =
- (nsPluginThreadRunnable *)PR_LIST_HEAD(&sPendingAsyncCalls);
-
- do {
- if (r->IsForInstance(instance)) {
- r->Invalidate();
- }
-
- r = (nsPluginThreadRunnable *)PR_NEXT_LINK(r);
- } while (r != &sPendingAsyncCalls);
- }
-}
-
-void
-OnShutdown()
-{
- NS_ASSERTION(PR_CLIST_IS_EMPTY(&sPendingAsyncCalls),
- "Pending async plugin call list not cleaned up!");
-
- if (sPluginThreadAsyncCallLock) {
- nsAutoLock::DestroyLock(sPluginThreadAsyncCallLock);
-
- sPluginThreadAsyncCallLock = nsnull;
- }
-}
-
-void
-EnterAsyncPluginThreadCallLock()
-{
- if (sPluginThreadAsyncCallLock) {
- PR_Lock(sPluginThreadAsyncCallLock);
- }
-}
-
-void
-ExitAsyncPluginThreadCallLock()
-{
- if (sPluginThreadAsyncCallLock) {
- PR_Unlock(sPluginThreadAsyncCallLock);
- }
-}
-
-NPP NPPStack::sCurrentNPP = nsnull;
-
+} /* namespace parent */
+} /* namespace plugins */
+} /* namespace mozilla */
--- a/modules/plugin/base/src/nsNPAPIPlugin.h
+++ b/modules/plugin/base/src/nsNPAPIPlugin.h
@@ -43,16 +43,18 @@
#include "nsIPluginOld.h"
#include "nsIJVMPlugin.h"
#include "nsIJVMConsole.h"
#endif
#include "prlink.h"
#include "npfunctions.h"
#include "nsPluginHost.h"
+#include "mozilla/PluginLibrary.h"
+
/*
* Use this macro before each exported function
* (between the return address and the function
* itself), to ensure that the function has the
* right calling conventions on OS/2.
*/
#ifdef XP_OS2
#define NP_CALLBACK _System
@@ -78,22 +80,25 @@ typedef NS_NPAPIPLUGIN_CALLBACK(NPError,
class nsNPAPIPlugin : public nsIPlugin
#ifdef OJI
,public nsIPluginOld,
public nsIJVMPlugin,
public nsIJVMConsole
#endif
{
+private:
+ typedef mozilla::PluginLibrary PluginLibrary;
+
public:
#ifdef OJI
nsNPAPIPlugin(nsIPluginOld *aShadow);
#endif
- nsNPAPIPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary,
- NP_PLUGINSHUTDOWN aShutdown);
+ nsNPAPIPlugin(NPPluginFuncs* callbacks,
+ PluginLibrary* aLibrary /*assume ownership*/);
virtual ~nsNPAPIPlugin();
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGIN
#ifdef OJI
NS_DECL_NSIFACTORY
@@ -135,30 +140,31 @@ protected:
#ifdef XP_MACOSX
short fPluginRefNum;
#endif
// The plugin-side callbacks that the browser calls. One set of
// plugin callbacks for each plugin.
NPPluginFuncs fCallbacks;
- PRLibrary* fLibrary;
-
- NP_PLUGINSHUTDOWN fShutdownEntry;
+ PluginLibrary* fLibrary;
+ PRLibrary* fPRLibrary;
// Browser-side callbacks that the plugin calls.
static NPNetscapeFuncs CALLBACKS;
#ifdef OJI
nsIPluginOld *mShadow; // Strong
#endif
};
+namespace mozilla {
+namespace plugins {
+namespace parent {
-PR_BEGIN_EXTERN_C
NPObject* NP_CALLBACK
_getwindowobject(NPP npp);
NPObject* NP_CALLBACK
_getpluginelement(NPP npp);
NPIdentifier NP_CALLBACK
_getstringidentifier(const NPUTF8* name);
@@ -239,33 +245,105 @@ void NP_CALLBACK
typedef void(*PluginThreadCallback)(void *);
void NP_CALLBACK
_pluginthreadasynccall(NPP instance, PluginThreadCallback func,
void *userData);
NPError NP_CALLBACK
_getvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
char **value, uint32_t *len);
+
NPError NP_CALLBACK
_setvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
const char *value, uint32_t len);
NPError NP_CALLBACK
_getauthenticationinfo(NPP instance, const char *protocol, const char *host,
int32_t port, const char *scheme, const char *realm,
char **username, uint32_t *ulen, char **password,
uint32_t *plen);
+typedef void(*PluginTimerFunc)(NPP npp, uint32_t timerID);
+
uint32_t NP_CALLBACK
-_scheduletimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
+_scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc timerFunc);
void NP_CALLBACK
_unscheduletimer(NPP instance, uint32_t timerID);
-PR_END_EXTERN_C
+NPError NP_CALLBACK
+_requestread(NPStream *pstream, NPByteRange *rangeList);
+
+NPError NP_CALLBACK
+_geturlnotify(NPP npp, const char* relativeURL, const char* target,
+ void* notifyData);
+
+NPError NP_CALLBACK
+_getvalue(NPP npp, NPNVariable variable, void *r_value);
+
+NPError NP_CALLBACK
+_setvalue(NPP npp, NPPVariable variable, void *r_value);
+
+NPError NP_CALLBACK
+_geturl(NPP npp, const char* relativeURL, const char* target);
+
+NPError NP_CALLBACK
+_posturlnotify(NPP npp, const char* relativeURL, const char *target,
+ uint32_t len, const char *buf, NPBool file, void* notifyData);
+
+NPError NP_CALLBACK
+_posturl(NPP npp, const char* relativeURL, const char *target, uint32_t len,
+ const char *buf, NPBool file);
+
+NPError NP_CALLBACK
+_newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream);
+
+int32_t NP_CALLBACK
+_write(NPP npp, NPStream *pstream, int32_t len, void *buffer);
+
+NPError NP_CALLBACK
+_destroystream(NPP npp, NPStream *pstream, NPError reason);
+
+void NP_CALLBACK
+_status(NPP npp, const char *message);
+
+void NP_CALLBACK
+_memfree (void *ptr);
+
+uint32_t NP_CALLBACK
+_memflush(uint32_t size);
+
+void NP_CALLBACK
+_reloadplugins(NPBool reloadPages);
+
+void NP_CALLBACK
+_invalidaterect(NPP npp, NPRect *invalidRect);
+
+void NP_CALLBACK
+_invalidateregion(NPP npp, NPRegion invalidRegion);
+
+void NP_CALLBACK
+_forceredraw(NPP npp);
+
+const char* NP_CALLBACK
+_useragent(NPP npp);
+
+void* NP_CALLBACK
+_memalloc (uint32_t size);
+
+// Deprecated entry points for the old Java plugin.
+void* NP_CALLBACK /* OJI type: JRIEnv* */
+_getJavaEnv(void);
+
+void* NP_CALLBACK /* OJI type: jref */
+_getJavaPeer(NPP npp);
+
+} /* namespace parent */
+} /* namespace plugins */
+} /* namespace mozilla */
const char *
PeekException();
void
PopException();
void
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
+++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
@@ -52,16 +52,18 @@
#include "nsIDocument.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsDirectoryServiceDefs.h"
#include "nsJSNPRuntime.h"
+using namespace mozilla::plugins::parent;
+
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
// nsPluginStreamToFile
// --------------------
// Used to handle NPN_NewStream() - writes the stream as received by the plugin
// to a file and at completion (NPN_DestroyStream), tells the browser to load it into
// a plugin-specified target
@@ -264,17 +266,19 @@ nsresult nsNPAPIPluginStreamListener::Cl
mInst->GetCallbacks(&callbacks);
if (!callbacks)
return rv;
NPP npp;
mInst->GetNPP(&npp);
if (mStreamStarted && callbacks->destroystream) {
- PRLibrary* lib = nsnull;
+ NPPAutoPusher nppPusher(npp);
+
+ PluginLibrary* lib = nsnull;
lib = mInst->mLibrary;
NPError error;
NS_TRY_SAFE_CALL_RETURN(error, (*callbacks->destroystream)(npp, &mNPStream, reason), lib, mInst);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP DestroyStream called: this=%p, npp=%p, reason=%d, return=%d, url=%s\n",
this, npp, reason, error, mNPStream.url));
@@ -353,16 +357,18 @@ nsNPAPIPluginStreamListener::OnStartBind
if (!mResponseHeaders.IsEmpty()) {
mResponseHeaderBuf = PL_strdup(mResponseHeaders.get());
mNPStream.headers = mResponseHeaderBuf;
}
mStreamInfo = pluginInfo;
+ NPPAutoPusher nppPusher(npp);
+
NS_TRY_SAFE_CALL_RETURN(error, (*callbacks->newstream)(npp, (char*)contentType, &mNPStream, seekable, &streamType), mInst->mLibrary, mInst);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP NewStream called: this=%p, npp=%p, mime=%s, seek=%d, type=%d, return=%d, url=%s\n",
this, npp, (char *)contentType, seekable, streamType, error, mNPStream.url));
if (error != NPERR_NO_ERROR)
return NS_ERROR_FAILURE;
@@ -592,16 +598,18 @@ nsNPAPIPluginStreamListener::OnDataAvail
PRInt32 zeroBytesWriteCount = 0;
// mStreamBufferByteCount tells us how many bytes there are in the
// buffer. WriteReady returns to us how many bytes the plugin is
// ready to handle.
while (mStreamBufferByteCount > 0) {
PRInt32 numtowrite;
if (callbacks->writeready) {
+ NPPAutoPusher nppPusher(npp);
+
NS_TRY_SAFE_CALL_RETURN(numtowrite, (*callbacks->writeready)(npp, &mNPStream), mInst->mLibrary, mInst);
NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,
("NPP WriteReady called: this=%p, npp=%p, "
"return(towrite)=%d, url=%s\n",
this, npp, numtowrite, mNPStream.url));
if (!mStreamStarted) {
// The plugin called NPN_DestroyStream() from within
@@ -638,16 +646,18 @@ nsNPAPIPluginStreamListener::OnDataAvail
numtowrite = PR_MIN(numtowrite, mStreamBufferByteCount);
} else {
// if WriteReady is not supported by the plugin, just write
// the whole buffer
numtowrite = mStreamBufferByteCount;
}
+ NPPAutoPusher nppPusher(npp);
+
PRInt32 writeCount = 0; // bytes consumed by plugin instance
NS_TRY_SAFE_CALL_RETURN(writeCount, (*callbacks->write)(npp, &mNPStream, streamPosition, numtowrite, ptrStreamBuffer), mInst->mLibrary, mInst);
NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,
("NPP Write called: this=%p, npp=%p, pos=%d, len=%d, "
"buf=%s, return(written)=%d, url=%s\n",
this, npp, streamPosition, numtowrite,
ptrStreamBuffer, writeCount, mNPStream.url));
@@ -743,17 +753,17 @@ nsNPAPIPluginStreamListener::OnFileAvail
const NPPluginFuncs *callbacks = nsnull;
mInst->GetCallbacks(&callbacks);
if (!callbacks || !callbacks->asfile)
return NS_ERROR_FAILURE;
NPP npp;
mInst->GetNPP(&npp);
- PRLibrary* lib = nsnull;
+ PluginLibrary* lib = nsnull;
lib = mInst->mLibrary;
NS_TRY_SAFE_CALL_VOID((*callbacks->asfile)(npp, &mNPStream, fileName), lib, mInst);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP StreamAsFile called: this=%p, npp=%p, url=%s, file=%s\n",
this, npp, mNPStream.url, fileName));
@@ -897,17 +907,17 @@ nsNPAPIPluginInstance::nsNPAPIPluginInst
mStreams(nsnull),
mMIMEType(nsnull),
mShadow(aShadow)
{
}
#endif
nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
- PRLibrary* aLibrary)
+ PluginLibrary* aLibrary)
: mCallbacks(callbacks),
#ifdef XP_MACOSX
#ifdef NP_NO_QUICKDRAW
mDrawingModel(NPDrawingModelCoreGraphics),
#else
mDrawingModel(NPDrawingModelQuickDraw),
#endif
#endif
@@ -1287,18 +1297,16 @@ nsNPAPIPluginInstance::InitializePlugin(
NS_ASSERTION(!values[count], "attribute/parameter array not setup correctly for NPAPI plugins");
if (pcount)
count += ++pcount; // if it's all setup correctly, then all we need is to
// change the count (attrs + PARAM/blank + params)
}
}
}
- NS_ENSURE_TRUE(mCallbacks->newp, NS_ERROR_FAILURE);
-
// XXX Note that the NPPluginType_* enums were crafted to be
// backward compatible...
nsPluginMode mode;
const char* mimetype;
NPError error;
GetMode(&mode);
@@ -1357,17 +1365,22 @@ nsNPAPIPluginInstance::InitializePlugin(
// Mark this instance as started before calling NPP_New because the plugin may
// call other NPAPI functions, like NPN_GetURLNotify, that assume this is set
// before returning. If the plugin returns failure, we'll clear it out below.
mStarted = PR_TRUE;
PRBool oldVal = mInPluginInitCall;
mInPluginInitCall = PR_TRUE;
- NS_TRY_SAFE_CALL_RETURN(error, (*mCallbacks->newp)((char*)mimetype, &mNPP, (PRUint16)mode, count, (char**)names, (char**)values, NULL), mLibrary,this);
+ // Need this on the stack before calling NPP_New otherwise some callbacks that
+ // the plugin may make could fail (NPN_HasProperty, for example).
+ NPPAutoPusher autopush(&mNPP);
+ nsresult newResult = mLibrary->NPP_New((char*)mimetype, &mNPP, (PRUint16)mode, count, (char**)names, (char**)values, NULL, &error);
+ if (NS_FAILED(newResult))
+ return newResult;
mInPluginInitCall = oldVal;
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP New called: this=%p, npp=%p, mime=%s, mode=%d, argc=%d, return=%d\n",
this, &mNPP, mimetype, mode, count, error));
if (error != NPERR_NO_ERROR) {
@@ -1406,16 +1419,18 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Set
// XXX Turns out that NPPluginWindow and NPWindow are structurally
// identical (on purpose!), so there's no need to make a copy.
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetWindow (about to call it) this=%p\n",this));
PRBool oldVal = mInPluginInitCall;
mInPluginInitCall = PR_TRUE;
+ NPPAutoPusher nppPusher(&mNPP);
+
NS_TRY_SAFE_CALL_RETURN(error, (*mCallbacks->setwindow)(&mNPP, (NPWindow*)window), mLibrary, this);
mInPluginInitCall = oldVal;
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP SetWindow called: this=%p, [x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d], return=%d\n",
this, window->x, window->y, window->width, window->height,
window->clipRect.top, window->clipRect.bottom, window->clipRect.left, window->clipRect.right, error));
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.h
+++ b/modules/plugin/base/src/nsNPAPIPluginInstance.h
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
@@ -53,17 +53,17 @@
#include "nsIPluginInstancePeer2.h"
#include "nsPIPluginInstancePeer.h"
#include "nsIScriptablePlugin.h"
#include "nsIPluginInstanceInternal.h"
#include "nsIJVMPluginInstance.h"
#endif
#include "npfunctions.h"
-#include "prlink.h"
+#include "mozilla/PluginLibrary.h"
class nsNPAPIPluginStreamListener;
class nsPIDOMWindow;
struct nsInstanceStream
{
nsInstanceStream *mNext;
nsNPAPIPluginStreamListener *mPluginStreamListener;
@@ -84,16 +84,19 @@ public:
class nsNPAPIPluginInstance : public nsIPluginInstance
#ifdef OJI
,public nsIPluginInstanceOld,
public nsIScriptablePlugin,
public nsIPluginInstanceInternal,
public nsIJVMPluginInstance
#endif
{
+private:
+ typedef mozilla::PluginLibrary PluginLibrary;
+
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGININSTANCE
#ifdef OJI
NS_DECL_NSISCRIPTABLEPLUGIN
NS_DECL_NSIJVMPLUGININSTANCE
@@ -138,17 +141,17 @@ public:
void* notifyData,
PRBool aCallNotify,
const char * aURL);
#ifdef OJI
nsNPAPIPluginInstance(nsIPluginInstanceOld *aShadow);
#endif
- nsNPAPIPluginInstance(NPPluginFuncs* callbacks, PRLibrary* aLibrary);
+ nsNPAPIPluginInstance(NPPluginFuncs* callbacks, PluginLibrary* aLibrary);
// Use Release() to destroy this
virtual ~nsNPAPIPluginInstance();
// returns the state of mStarted
PRBool IsStarted();
// cache this NPAPI plugin
@@ -196,17 +199,17 @@ protected:
PRPackedBool mTransparent;
PRPackedBool mStarted;
PRPackedBool mCached;
PRPackedBool mWantsAllNetworkStreams;
public:
// True while creating the plugin, or calling NPP_SetWindow() on it.
PRPackedBool mInPluginInitCall;
- PRLibrary* mLibrary;
+ PluginLibrary* mLibrary;
nsInstanceStream *mStreams;
private:
nsTArray<PopupControlState> mPopupStates;
char* mMIMEType;
// Weak pointer to the owner. The owner nulls this out (by calling
--- a/modules/plugin/base/src/nsNPAPIPluginStreamListener.h
+++ b/modules/plugin/base/src/nsNPAPIPluginStreamListener.h
@@ -49,16 +49,19 @@
class nsNPAPIPluginInstance;
class nsINPAPIPluginStreamInfo;
class nsNPAPIPluginStreamListener : public nsIPluginStreamListener,
public nsITimerCallback,
public nsIHTTPHeaderListener
{
+private:
+ typedef mozilla::PluginLibrary PluginLibrary;
+
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGINSTREAMLISTENER
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSIHTTPHEADERLISTENER
// nsNPAPIPluginStreamListener specific methods:
nsNPAPIPluginStreamListener(nsNPAPIPluginInstance* inst, void* notifyData,
--- a/modules/plugin/base/src/nsPluginHost.cpp
+++ b/modules/plugin/base/src/nsPluginHost.cpp
@@ -3613,26 +3613,26 @@ nsPluginHost::TrySetUpPluginInstance(con
GetPlugin(mimetype, getter_AddRefs(plugin));
if (plugin) {
#if defined(XP_WIN) && !defined(WINCE)
static BOOL firstJavaPlugin = FALSE;
BOOL restoreOrigDir = FALSE;
char origDir[_MAX_PATH];
if (pluginTag->mIsJavaPlugin && !firstJavaPlugin) {
- DWORD dw = ::GetCurrentDirectory(_MAX_PATH, origDir);
+ DWORD dw = GetCurrentDirectoryA(_MAX_PATH, origDir);
NS_ASSERTION(dw <= _MAX_PATH, "Falied to obtain the current directory, which may leads to incorrect class laoding");
nsCOMPtr<nsIFile> binDirectory;
result = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
getter_AddRefs(binDirectory));
if (NS_SUCCEEDED(result)) {
nsCAutoString path;
binDirectory->GetNativePath(path);
- restoreOrigDir = ::SetCurrentDirectory(path.get());
+ restoreOrigDir = SetCurrentDirectoryA(path.get());
}
}
#endif
#ifdef OJI
nsNPAPIPlugin *pluginPriv = static_cast<nsNPAPIPlugin*>(plugin.get());
nsIPluginOld *shadowPlugin = pluginPriv->GetShadow();
if (shadowPlugin) {
nsIPluginInstanceOld *shadowInstance = nsnull;
@@ -3650,17 +3650,17 @@ nsPluginHost::TrySetUpPluginInstance(con
result = plugin->CreatePluginInstance(getter_AddRefs(instance));
}
#else
result = plugin->CreatePluginInstance(getter_AddRefs(instance));
#endif
#if defined(XP_WIN) && !defined(WINCE)
if (!firstJavaPlugin && restoreOrigDir) {
- BOOL bCheck = ::SetCurrentDirectory(origDir);
+ BOOL bCheck = SetCurrentDirectoryA(origDir);
NS_ASSERTION(bCheck, " Error restoring driectoy");
firstJavaPlugin = TRUE;
}
#endif
}
if (NS_FAILED(result))
return result;
@@ -4186,16 +4186,17 @@ NS_IMETHODIMP nsPluginHost::GetPlugin(co
}
#else
if (!plugin) {
// Now lets try to get the entry point from an NPAPI plugin
rv = CreateNPAPIPlugin(pluginTag, getter_AddRefs(plugin));
if (NS_FAILED(rv))
return rv;
+ NS_ASSERTION(plugin, "CreateNPAPIPlugin succeeded without setting 'plugin'");
pluginTag->mEntryPoint = plugin;
}
#endif
if (!plugin)
return NS_ERROR_FAILURE;
--- a/modules/plugin/base/src/nsPluginNativeWindowWin.cpp
+++ b/modules/plugin/base/src/nsPluginNativeWindowWin.cpp
@@ -528,16 +528,20 @@ nsresult nsPluginNativeWindowWin::Subcla
if (!hWnd)
return NS_ERROR_FAILURE;
// check if we need to re-subclass
WNDPROC currentWndProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
if (PluginWndProc == currentWndProc)
return NS_OK;
+ LONG style = GetWindowLongPtr(hWnd, GWL_STYLE);
+ style |= WS_CLIPCHILDREN;
+ SetWindowLongPtr(hWnd, GWL_STYLE, style);
+
mPluginWinProc = SubclassWindow(hWnd, (LONG_PTR)PluginWndProc);
if (!mPluginWinProc)
return NS_ERROR_FAILURE;
nsPluginNativeWindowWin * win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
NS_ASSERTION(!win || (win == this), "plugin window already has property and this is not us");
if (!::SetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION, (HANDLE)this))
@@ -557,16 +561,20 @@ nsresult nsPluginNativeWindowWin::UndoSu
::RemoveProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
// restore the original win proc
// but only do this if this were us last time
if (mPluginWinProc) {
WNDPROC currentWndProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
if (currentWndProc == PluginWndProc)
SubclassWindow(hWnd, (LONG_PTR)mPluginWinProc);
+
+ LONG style = GetWindowLongPtr(hWnd, GWL_STYLE);
+ style &= ~WS_CLIPCHILDREN;
+ SetWindowLongPtr(hWnd, GWL_STYLE, style);
}
return NS_OK;
}
#endif // WINCE
nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
{
--- a/modules/plugin/base/src/nsPluginSafety.h
+++ b/modules/plugin/base/src/nsPluginSafety.h
@@ -73,17 +73,17 @@ PR_BEGIN_MACRO
{ \
ret = fun; \
} \
catch(...) \
{ \
nsresult res; \
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID, &res));\
if(NS_SUCCEEDED(res) && (host != nsnull)) \
- host->HandleBadPlugin(library, pluginInst);\
+ host->HandleBadPlugin(nsnull, pluginInst); \
ret = (NPError)NS_ERROR_FAILURE; \
} \
} \
NS_NotifyPluginCall(startTime); \
PR_END_MACRO
#define NS_TRY_SAFE_CALL_VOID(fun, library, pluginInst) \
PR_BEGIN_MACRO \
@@ -96,17 +96,17 @@ PR_BEGIN_MACRO
{ \
fun; \
} \
catch(...) \
{ \
nsresult res; \
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID, &res));\
if(NS_SUCCEEDED(res) && (host != nsnull))\
- host->HandleBadPlugin(library, pluginInst);\
+ host->HandleBadPlugin(nsnull, pluginInst);\
} \
} \
NS_NotifyPluginCall(startTime); \
PR_END_MACRO
#else // vanilla calls
#define NS_TRY_SAFE_CALL_RETURN(ret, fun, library, pluginInst) \
--- a/modules/plugin/base/src/nsPluginsDirWin.cpp
+++ b/modules/plugin/base/src/nsPluginsDirWin.cpp
@@ -234,30 +234,30 @@ nsresult nsPluginFile::LoadPlugin(PRLibr
if (!index) {
PL_strfree(pluginFolderPath);
return NS_ERROR_FILE_INVALID_PATH;
}
*index = 0;
BOOL restoreOrigDir = FALSE;
char aOrigDir[MAX_PATH + 1];
- DWORD dwCheck = ::GetCurrentDirectory(sizeof(aOrigDir), aOrigDir);
+ DWORD dwCheck = GetCurrentDirectoryA(sizeof(aOrigDir), aOrigDir);
NS_ASSERTION(dwCheck <= MAX_PATH + 1, "Error in Loading plugin");
if (dwCheck <= MAX_PATH + 1) {
- restoreOrigDir = ::SetCurrentDirectory(pluginFolderPath);
+ restoreOrigDir = SetCurrentDirectoryA(pluginFolderPath);
NS_ASSERTION(restoreOrigDir, "Error in Loading plugin");
}
#endif
outLibrary = PR_LoadLibrary(temp.get());
#ifndef WINCE
if (restoreOrigDir) {
- BOOL bCheck = ::SetCurrentDirectory(aOrigDir);
+ BOOL bCheck = SetCurrentDirectoryA(aOrigDir);
NS_ASSERTION(bCheck, "Error in Loading plugin");
}
PL_strfree(pluginFolderPath);
#endif
return NS_OK;
}
--- a/modules/plugin/test/mochitest/Makefile.in
+++ b/modules/plugin/test/mochitest/Makefile.in
@@ -54,18 +54,28 @@ include $(topsrcdir)/config/rules.mk
test_pluginstream_src.html \
test_pluginstream_geturl.html \
test_pluginstream_geturlnotify.html \
test_pluginstream_asfile.html \
test_pluginstream_asfileonly.html \
test_pluginstream_post.html \
test_pluginstream_poststream.html \
test_pluginstream_seek.html \
+ test_streamNotify.html \
$(NULL)
+# test_npruntime_npnsetexception.html \ Disabled for e10s
+
+#ifdef MOZ_IPC
+#_MOCHITEST_FILES += \
+# test_crashing.html \
+# crashing_subpage.html \
+# $(NULL)
+#endif
+
_MOCHICHROME_FILES = \
test_bug479979.xul \
test_npruntime.xul \
test_privatemode.xul \
test_wmode.xul \
$(NULL)
libs:: $(_MOCHICHROME_FILES)
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/mochitest/crashing_subpage.html
@@ -0,0 +1,4 @@
+<html>
+<body onload="window.parent.frameLoaded()">
+ <h1>Crashing subpage</h1>
+ <embed id="plugin1" type="application/x-test" width="400" height="400" drawmode="solid" color="FF00FFFF"></embed>
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/mochitest/test_crashing.html
@@ -0,0 +1,59 @@
+<head>
+ <title>Plugin crashing</title>
+ <script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+<body>
+ <iframe id="iframe1" src="crashing_subpage.html" width="600" height="600"></iframe>
+
+ <script class="testbody" type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+
+ var iframe = document.getElementById('iframe1');
+
+ window.frameLoaded = function frameLoaded_toCrash() {
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ var prefs = Components.classes['@mozilla.org/preferences-service;1']
+ .getService(Components.interfaces.nsIPrefBranch);
+ if (!prefs.getBoolPref('dom.ipc.plugins.enabled')) {
+ ok(true, "Skipping this test when IPC plugins are not enabled.");
+ SimpleTest.finish();
+ return;
+ }
+
+ var p = iframe.contentDocument.getElementById('plugin1');
+
+ p.setColor("FFFF00FF");
+
+ try {
+ p.crash();
+ ok(false, "p.crash() should throw an exception");
+ }
+ catch (e) {
+ ok(true, "p.crash() should throw an exception");
+ }
+
+ try {
+ p.setColor("FFFF0000");
+ ok(false, "p.setColor should throw after the plugin crashes");
+ }
+ catch (e) {
+ ok(true, "p.setColor should throw after the plugin crashes");
+ }
+
+ window.frameLoaded = function reloaded() {
+ var p = iframe.contentDocument.getElementById('plugin1');
+ try {
+ p.setColor('FF00FF00');
+ ok(true, "Reloading worked");
+ }
+ catch (e) {
+ ok(false, "Reloading didn't give us a usable plugin");
+ }
+ SimpleTest.finish();
+ }
+
+ iframe.contentWindow.location.reload();
+ }
+
+ </script>
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/mochitest/test_streamNotify.html
@@ -0,0 +1,55 @@
+<head>
+ <title>NPN_Get/PostURLNotify tests</title>
+ <script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+<body onload="runTests()">
+ <embed id="plugin1" type="application/x-test" width="400" height="400"></embed>
+
+ <script class="testbody" type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+
+ var pending = 4;
+ function testDone() {
+ dump("testDone: " + pending + "\n")
+ --pending;
+ if (0 == pending)
+ SimpleTest.finish();
+ }
+
+ function runTests() {
+ var p = document.getElementById('plugin1');
+
+ ok(p.streamTest("loremipsum.txt", false, null,
+ function(r, t) {
+ is(r, 0, "GET loremipsum.txt");
+ is(t.substr(0, 11), "Lorem ipsum",
+ "GET loremipsum.txt correct");
+ testDone();
+ }), "streamTest GET");
+
+ ok(!p.streamTest("post.sjs", true, null,
+ function(r, t) {
+ ok(false, "Shouldn't get callback from null post");
+ }), "streamTest POST null postdata");
+
+ ok(p.streamTest("post.sjs", true, "Something good",
+ function(r, t) {
+ is(r, 0, "POST something good");
+ is(t, "Something good", "POST non-null correct");
+ testDone();
+ }), "streamTest POST valid postdata");
+
+ ok(p.streamTest("http://example.invalid/", false, null,
+ function(r, t) {
+ is(r, 1, "Shouldn't load example.invalid DNS name");
+ testDone();
+ }), "streamTest GET bad DNS");
+
+ ok(p.streamTest("http://localhost:-8/", false, null,
+ function(r, t) {
+ is(r, 1, "Shouldn't load invalid URI");
+ testDone();
+ }), "streamTest GET invalid URL");
+ }
+ </script>
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -42,17 +42,17 @@
ifdef TEST_PATH
TEST_PATH_ARG := --test-path=$(TEST_PATH)
else
TEST_PATH_ARG :=
endif
# Usage: |make [TEST_PATH=...] [EXTRA_TEST_ARGS=...] mochitest*|.
-mochitest:: mochitest-plain mochitest-chrome mochitest-a11y
+mochitest:: mochitest-plain mochitest-chrome mochitest-a11y mochitest-ipcplugins
RUN_MOCHITEST = \
rm -f ./$@.log && \
$(PYTHON) _tests/testing/mochitest/runtests.py --autorun --close-when-done \
--console-level=INFO --log-file=./$@.log --file-level=INFO \
$(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
ifndef NO_FAIL_ON_TEST_ERRORS
@@ -76,16 +76,20 @@ mochitest-chrome:
$(RUN_MOCHITEST) --chrome
$(CHECK_TEST_ERROR)
mochitest-a11y:
$(RUN_MOCHITEST) --a11y
$(CHECK_TEST_ERROR)
+mochitest-ipcplugins:
+ $(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled=true --test-path=modules/plugin/test
+ $(CHECK_TEST_ERROR)
+
# Usage: |make [EXTRA_TEST_ARGS=...] *test|.
RUN_REFTEST = rm -f ./$@.log && $(PYTHON) _tests/reftest/runreftest.py $(EXTRA_TEST_ARGS) $(1) | tee ./$@.log
reftest:
$(call RUN_REFTEST,$(topsrcdir)/layout/reftests/reftest.list)
$(CHECK_TEST_ERROR)
crashtest:
@@ -137,13 +141,13 @@ stage-reftest: make-stage-dir
stage-xpcshell: make-stage-dir
$(MAKE) -C $(DEPTH)/testing/xpcshell stage-package
stage-jstests: make-stage-dir
$(MAKE) -C $(DEPTH)/js/src/tests stage-package
.PHONY: \
- mochitest mochitest-plain mochitest-chrome mochitest-a11y \
+ mochitest mochitest-plain mochitest-chrome mochitest-a11y mochitest-ipcplugins \
reftest crashtest \
xpcshell-tests \
jstestbrowser \
package-tests make-stage-dir stage-mochitest stage-reftest stage-xpcshell stage-jstests
--- a/toolkit/library/dlldeps-xul.cpp
+++ b/toolkit/library/dlldeps-xul.cpp
@@ -44,9 +44,18 @@ void xxxNeverCalledXUL()
XRE_GetStaticComponents(nsnull, nsnull);
XRE_LockProfileDirectory(nsnull, nsnull);
XRE_InitEmbedding(nsnull, nsnull, nsnull, nsnull, 0);
XRE_NotifyProfile();
XRE_TermEmbedding();
XRE_CreateAppData(nsnull, nsnull);
XRE_ParseAppData(nsnull, nsnull);
XRE_FreeAppData(nsnull);
+ XRE_ChildProcessTypeToString(GeckoProcessType_Default);
+ XRE_StringToChildProcessType("");
+ XRE_GetProcessType();
+#ifdef MOZ_IPC
+ XRE_InitChildProcess(0, nsnull, GeckoProcessType_Default);
+ XRE_InitParentProcess(0, nsnull, nsnull, nsnull);
+ XRE_RunAppShell();
+ XRE_ShutdownChildProcess();
+#endif
}
--- a/toolkit/library/libxul-config.mk
+++ b/toolkit/library/libxul-config.mk
@@ -86,16 +86,37 @@ ifdef MOZ_ENABLE_LIBXUL
RESFILE = xulrunos2.res
RCFLAGS += -i $(topsrcdir)/widget/src/os2
endif
LOCAL_INCLUDES += -I$(topsrcdir)/widget/src/os2
endif
# dependent libraries
+ifdef MOZ_IPC
+STATIC_LIBS += \
+ domplugins_s \
+ mozipc_s \
+ mozipdlgen_s \
+ chromium_s \
+ gfxipc_s \
+ $(NULL)
+
+ifdef MOZ_IPDL_TESTS
+STATIC_LIBS += ipdlunittest_s
+endif
+
+ifeq (Linux,$(OS_ARCH))
+OS_LIBS += -lrt
+endif
+ifeq (WINNT,$(OS_ARCH))
+OS_LIBS += psapi.lib dbghelp.lib
+endif
+endif
+
STATIC_LIBS += \
xpcom_core \
ucvutil_s \
gkgfx \
$(NULL)
#ifndef MOZ_EMBEDDING_LEVEL_DEFAULT
ifndef WINCE
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -43,16 +43,21 @@ MAKEFILES_db="
db/mdb/Makefile
db/mdb/public/Makefile
db/mork/Makefile
db/mork/build/Makefile
db/mork/src/Makefile
"
MAKEFILES_dom="
+ ipc/Makefile
+ ipc/chromium/Makefile
+ ipc/glue/Makefile
+ ipc/ipdl/Makefile
+ ipc/testshell/Makefile
dom/Makefile
dom/public/coreEvents/Makefile
dom/interfaces/base/Makefile
dom/interfaces/canvas/Makefile
dom/interfaces/core/Makefile
dom/interfaces/css/Makefile
dom/interfaces/events/Makefile
dom/interfaces/geolocation/Makefile
@@ -75,16 +80,18 @@ MAKEFILES_dom="
dom/src/events/Makefile
dom/src/jsurl/Makefile
dom/src/geolocation/Makefile
dom/src/json/Makefile
dom/src/offline/Makefile
dom/src/storage/Makefile
dom/src/threads/Makefile
dom/locales/Makefile
+ dom/plugins/Makefile
+ dom/ipc/Makefile
"
MAKEFILES_editor="
editor/Makefile
editor/public/Makefile
editor/idl/Makefile
editor/txmgr/Makefile
editor/txmgr/idl/Makefile
--- a/toolkit/toolkit-tiers.mk
+++ b/toolkit/toolkit-tiers.mk
@@ -76,16 +76,20 @@ tier_external_dirs += gfx/qcms
ifeq ($(OS_ARCH),WINCE)
tier_external_dirs += modules/lib7z
endif
#
# tier "gecko" - core components
#
+ifdef MOZ_IPC
+tier_gecko_dirs += ipc
+endif
+
tier_gecko_dirs += \
js/src/xpconnect \
js/ctypes \
intl/chardet \
$(NULL)
ifdef BUILD_CTYPES
ifndef _MSC_VER
--- a/toolkit/xre/Makefile.in
+++ b/toolkit/xre/Makefile.in
@@ -197,18 +197,22 @@ SHARED_LIBRARY_LIBS += \
$(NULL)
endif
endif
ifdef ENABLE_TESTS
DIRS += test
endif
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
+LOCAL_INCLUDES += -I$(topsrcdir)/dom/ipc
+
ifdef BUILD_STATIC_LIBS
export::
@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMP_NAMES) Apprunner
# embedding/browser/gtk/src/Makefile.in sucks! we need to add an empty line to
# FINAL_LINK_COMPS to keep the two lists in sync :-(
@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMPS) ""
endif
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -203,16 +203,20 @@
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#include "nsICrashReporter.h"
#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
#include "nsIPrefService.h"
#endif
+#ifdef MOZ_IPC
+#include "base/command_line.h"
+#endif
+
#ifdef WINCE
class WindowsMutex {
public:
WindowsMutex(const wchar_t *name) {
mHandle = CreateMutexW(0, FALSE, name);
}
~WindowsMutex() {
@@ -3028,16 +3032,19 @@ XRE_main(int argc, char* argv[], const n
}
#ifdef NS_TRACE_MALLOC
gArgc = argc = NS_TraceMallocStartupArgs(gArgc, gArgv);
#endif
MOZ_SPLASHSCREEN_UPDATE(20);
+ rv = XRE_InitCommandLine(gArgc, gArgv);
+ NS_ENSURE_SUCCESS(rv, 1);
+
{
nsXREDirProvider dirProvider;
rv = dirProvider.Initialize(gAppData->directory, gAppData->xreDirectory);
if (NS_FAILED(rv))
return 1;
// Check for -register, which registers chrome and then exits immediately.
ar = CheckArg("register", PR_TRUE);
@@ -3496,23 +3503,24 @@ XRE_main(int argc, char* argv[], const n
PromiseFlatCString(profileName).get());
#endif /* MOZ_ENABLE_XREMOTE */
// enable win32 DDE responses and Mac appleevents responses
nativeApp->Enable();
}
MOZ_SPLASHSCREEN_UPDATE(90);
-
- NS_TIMELINE_ENTER("appStartup->Run");
- rv = appStartup->Run();
- NS_TIMELINE_LEAVE("appStartup->Run");
- if (NS_FAILED(rv)) {
- NS_ERROR("failed to run appstartup");
- gLogConsoleErrors = PR_TRUE;
+ {
+ NS_TIMELINE_ENTER("appStartup->Run");
+ rv = appStartup->Run();
+ NS_TIMELINE_LEAVE("appStartup->Run");
+ if (NS_FAILED(rv)) {
+ NS_ERROR("failed to run appstartup");
+ gLogConsoleErrors = PR_TRUE;
+ }
}
// Check for an application initiated restart. This is one that
// corresponds to nsIAppStartup.quit(eRestart)
if (rv == NS_SUCCESS_RESTART_APP) {
needsRestart = PR_TRUE;
appInitiatedRestart = PR_TRUE;
}
@@ -3621,10 +3629,12 @@ XRE_main(int argc, char* argv[], const n
#endif
}
#ifdef MOZ_CRASHREPORTER
if (appData.flags & NS_XRE_ENABLE_CRASH_REPORTER)
CrashReporter::UnsetExceptionHandler();
#endif
+ XRE_DeinitCommandLine();
+
return NS_FAILED(rv) ? 1 : 0;
}
--- a/toolkit/xre/nsConsoleWriter.cpp
+++ b/toolkit/xre/nsConsoleWriter.cpp
@@ -29,16 +29,20 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef NO_NSPR_10_SUPPORT
+#undef NO_NSPR_10_SUPPORT
+#endif
+
#include "nsAppRunner.h"
#include "prio.h"
#include "prprf.h"
#include "prtime.h"
#include "prenv.h"
#include "nsCRT.h"
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -30,32 +30,81 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#endif
+
#include "nsXULAppAPI.h"
#include <stdlib.h>
+#if defined(MOZ_WIDGET_GTK2)
+#include <glib.h>
+#endif
+#include "prenv.h"
+
+#include "nsIAppShell.h"
#include "nsIAppStartupNotifier.h"
#include "nsIDirectoryService.h"
#include "nsILocalFile.h"
#include "nsIToolkitChromeRegistry.h"
+#include "nsIToolkitProfile.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsAppRunner.h"
+#include "nsAutoRef.h"
#include "nsDirectoryServiceDefs.h"
#include "nsStaticComponents.h"
#include "nsString.h"
+#include "nsThreadUtils.h"
+#include "nsWidgetsCID.h"
+#include "nsXPFEComponentsCID.h"
#include "nsXREDirProvider.h"
-#include "nsIToolkitProfile.h"
+
+#ifdef MOZ_IPC
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/message_loop.h"
+#include "base/process_util.h"
+#include "chrome/common/child_process.h"
+
+#include "mozilla/ipc/GeckoChildProcessHost.h"
+#include "mozilla/ipc/GeckoThread.h"
+#include "ScopedXREEmbed.h"
+
+#include "mozilla/plugins/PluginThreadChild.h"
+
+#include "mozilla/Monitor.h"
+
+#ifdef MOZ_IPDL_TESTS
+#include "mozilla/_ipdltest/IPDLUnitTests.h"
+#include "mozilla/_ipdltest/IPDLUnitTestThreadChild.h"
+
+using mozilla::_ipdltest::IPDLUnitTestThreadChild;
+#endif // ifdef MOZ_IPDL_TESTS
+
+using mozilla::ipc::GeckoChildProcessHost;
+using mozilla::ipc::GeckoThread;
+using mozilla::ipc::BrowserProcessSubThread;
+using mozilla::ipc::ScopedXREEmbed;
+
+using mozilla::plugins::PluginThreadChild;
+
+using mozilla::Monitor;
+using mozilla::MonitorAutoEnter;
+#endif
+
+static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
void
XRE_GetStaticComponents(nsStaticModuleInfo const **aStaticComponents,
PRUint32 *aComponentCount)
{
*aStaticComponents = kPStaticModules;
*aComponentCount = kStaticModuleCount;
}
@@ -156,8 +205,313 @@ XRE_TermEmbedding()
NS_ASSERTION(gDirServiceProvider,
"XRE_TermEmbedding without XRE_InitEmbedding");
gDirServiceProvider->DoShutdown();
NS_ShutdownXPCOM(nsnull);
delete [] sCombined;
delete gDirServiceProvider;
}
+
+const char*
+XRE_ChildProcessTypeToString(GeckoProcessType aProcessType)
+{
+ return (aProcessType < GeckoProcessType_End) ?
+ kGeckoProcessTypeString[aProcessType] : nsnull;
+}
+
+GeckoProcessType
+XRE_StringToChildProcessType(const char* aProcessTypeString)
+{
+ for (int i = 0;
+ i < (int) NS_ARRAY_LENGTH(kGeckoProcessTypeString);
+ ++i) {
+ if (!strcmp(kGeckoProcessTypeString[i], aProcessTypeString)) {
+ return static_cast<GeckoProcessType>(i);
+ }
+ }
+ return GeckoProcessType_Invalid;
+}
+
+#ifdef MOZ_IPC
+static GeckoProcessType sChildProcessType = GeckoProcessType_Default;
+
+static MessageLoop* sIOMessageLoop;
+
+nsresult
+XRE_InitChildProcess(int aArgc,
+ char* aArgv[],
+ GeckoProcessType aProcess)
+{
+ NS_ENSURE_ARG_MIN(aArgc, 2);
+ NS_ENSURE_ARG_POINTER(aArgv);
+ NS_ENSURE_ARG_POINTER(aArgv[0]);
+
+ sChildProcessType = aProcess;
+
+#if defined(MOZ_WIDGET_GTK2)
+ g_thread_init(NULL);
+#endif
+
+ if (PR_GetEnv("MOZ_DEBUG_CHILD_PROCESS")) {
+#ifdef OS_POSIX
+ printf("\n\nCHILDCHILDCHILDCHILD\n debug me @%d\n\n", getpid());
+ sleep(30);
+#elif defined(OS_WIN)
+ Sleep(30000);
+#endif
+ }
+
+ // child processes launched by GeckoChildProcessHost get this magic
+ // argument appended to their command lines
+ const char* const parentPIDString = aArgv[aArgc-1];
+ NS_ABORT_IF_FALSE(parentPIDString, "NULL parent PID");
+ --aArgc;
+
+ char* end = 0;
+ base::ProcessId parentPID = strtol(parentPIDString, &end, 10);
+ NS_ABORT_IF_FALSE(!*end, "invalid parent PID");
+
+ base::ProcessHandle parentHandle;
+ bool ok = base::OpenProcessHandle(parentPID, &parentHandle);
+ NS_ABORT_IF_FALSE(ok, "can't open handle to parent");
+
+ base::AtExitManager exitManager;
+
+ NS_LogInit();
+
+ int rv = XRE_InitCommandLine(aArgc, aArgv);
+ if (NS_FAILED(rv)) {
+ NS_LogTerm();
+ return NS_ERROR_FAILURE;
+ }
+
+ MessageLoopForIO mainMessageLoop;
+
+ {
+ ChildThread* mainThread;
+
+ switch (aProcess) {
+ case GeckoProcessType_Default:
+ mainThread = new GeckoThread(parentHandle);
+ break;
+
+ case GeckoProcessType_Plugin:
+ mainThread = new PluginThreadChild(parentHandle);
+ break;
+
+ case GeckoProcessType_IPDLUnitTest:
+#ifdef MOZ_IPDL_TESTS
+ mainThread = new IPDLUnitTestThreadChild(parentHandle);
+#else
+ NS_RUNTIMEABORT("rebuild with --enable-ipdl-tests");
+#endif
+ break;
+
+ default:
+ NS_RUNTIMEABORT("Unknown main thread class");
+ }
+
+ ChildProcess process(mainThread);
+
+ // Do IPC event loop
+ sIOMessageLoop = MessageLoop::current();
+
+ sIOMessageLoop->Run();
+
+ sIOMessageLoop = nsnull;
+ }
+
+ NS_LogTerm();
+ return XRE_DeinitCommandLine();
+}
+
+MessageLoop*
+XRE_GetIOMessageLoop()
+{
+ if (sChildProcessType == GeckoProcessType_Default) {
+ NS_ASSERTION(!sIOMessageLoop, "Shouldn't be set on parent process!");
+ return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO);
+ }
+ return sIOMessageLoop;
+}
+
+namespace {
+
+class MainFunctionRunnable : public nsRunnable
+{
+public:
+ NS_DECL_NSIRUNNABLE
+
+ MainFunctionRunnable(MainFunction aFunction,
+ void* aData)
+ : mFunction(aFunction),
+ mData(aData)
+ {
+ NS_ASSERTION(aFunction, "Don't give me a null pointer!");
+ }
+
+private:
+ MainFunction mFunction;
+ void* mData;
+};
+
+} /* anonymous namespace */
+
+NS_IMETHODIMP
+MainFunctionRunnable::Run()
+{
+ mFunction(mData);
+ return NS_OK;
+}
+
+nsresult
+XRE_InitParentProcess(int aArgc,
+ char* aArgv[],
+ MainFunction aMainFunction,
+ void* aMainFunctionData)
+{
+ NS_ENSURE_ARG_MIN(aArgc, 1);
+ NS_ENSURE_ARG_POINTER(aArgv);
+ NS_ENSURE_ARG_POINTER(aArgv[0]);
+
+ int rv = XRE_InitCommandLine(aArgc, aArgv);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ ScopedXREEmbed embed;
+
+ {
+ embed.Start();
+
+ nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
+ NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
+
+ if (aMainFunction) {
+ nsCOMPtr<nsIRunnable> runnable =
+ new MainFunctionRunnable(aMainFunction, aMainFunctionData);
+ NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
+
+ nsresult rv = NS_DispatchToCurrentThread(runnable);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // Do event loop
+ if (NS_FAILED(appShell->Run())) {
+ NS_WARNING("Failed to run appshell");
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ return XRE_DeinitCommandLine();
+}
+
+#ifdef MOZ_IPDL_TESTS
+//-----------------------------------------------------------------------------
+// IPDL unit test
+
+int
+XRE_RunIPDLTest(int aArgc, char** aArgv)
+{
+ if (aArgc < 2) {
+ fprintf(stderr, "TEST-UNEXPECTED-FAIL | <---> | insufficient #args, need at least 2\n");
+ return 1;
+ }
+
+ void* data = reinterpret_cast<void*>(aArgv[aArgc-1]);
+
+ nsresult rv =
+ XRE_InitParentProcess(
+ --aArgc, aArgv, mozilla::_ipdltest::IPDLUnitTestMain, data);
+ NS_ENSURE_SUCCESS(rv, 1);
+
+ return 0;
+}
+#endif // ifdef MOZ_IPDL_TESTS
+
+nsresult
+XRE_RunAppShell()
+{
+ nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
+ NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
+
+ return appShell->Run();
+}
+
+void
+XRE_ShutdownChildProcess()
+{
+ NS_ABORT_IF_FALSE(NS_IsMainThread(), "Wrong thread!");
+
+ MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+ NS_ABORT_IF_FALSE(!!ioLoop, "Bad shutdown order");
+
+ ioLoop->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+}
+
+#endif // MOZ_IPC
+
+
+nsresult
+XRE_InitCommandLine(int aArgc, char* aArgv[])
+{
+ nsresult rv = NS_OK;
+
+#if defined(MOZ_IPC)
+
+#if defined(OS_WIN)
+ CommandLine::Init(aArgc, aArgv);
+#else
+ // these leak on error, but that's OK: we'll just exit()
+ char** canonArgs = new char*[aArgc];
+
+ // get the canonical version of the binary's path
+ nsCOMPtr<nsILocalFile> binFile;
+ rv = XRE_GetBinaryPath(aArgv[0], getter_AddRefs(binFile));
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ nsCAutoString canonBinPath;
+ rv = binFile->GetNativePath(canonBinPath);
+ if (NS_FAILED(rv))
+ return NS_ERROR_FAILURE;
+
+ canonArgs[0] = strdup(canonBinPath.get());
+
+ for (int i = 1; i < aArgc; ++i) {
+ if (aArgv[i]) {
+ canonArgs[i] = strdup(aArgv[i]);
+ }
+ }
+
+ NS_ASSERTION(!CommandLine::IsInitialized(), "Bad news!");
+ CommandLine::Init(aArgc, canonArgs);
+
+ for (int i = 0; i < aArgc; ++i)
+ free(canonArgs[i]);
+ delete[] canonArgs;
+#endif
+#endif
+ return rv;
+}
+
+nsresult
+XRE_DeinitCommandLine()
+{
+ nsresult rv = NS_OK;
+
+#if defined(MOZ_IPC)
+ CommandLine::Terminate();
+#endif
+
+ return rv;
+}
+
+GeckoProcessType
+XRE_GetProcessType()
+{
+#ifdef MOZ_IPC
+ return sChildProcessType;
+#else
+ return GeckoProcessType_Default;
+#endif
+}
+
--- a/widget/src/windows/Makefile.in
+++ b/widget/src/windows/Makefile.in
@@ -150,11 +150,16 @@ FORCE_STATIC_LIB = 1
ifdef WINCE
EXTRA_DSO_LDOPTS += ddraw.lib
endif
ifndef WINCE
ENABLE_CXX_EXCEPTIONS = 1
endif
+ifdef MOZ_IPC
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+endif
+
include $(topsrcdir)/config/rules.mk
CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/widget/src/windows/nsAccelerometerWin.cpp
+++ b/widget/src/windows/nsAccelerometerWin.cpp
@@ -405,17 +405,17 @@ ThinkPadSensor::ThinkPadSensor()
ThinkPadSensor::~ThinkPadSensor()
{
}
PRBool
ThinkPadSensor::Startup()
{
- mLibrary = LoadLibrary("sensor.dll");
+ mLibrary = LoadLibraryW(L"sensor.dll");
if (!mLibrary)
return PR_FALSE;
gShockproofGetAccelerometerData = (ShockproofGetAccelerometerData)
GetProcAddress(mLibrary, "ShockproofGetAccelerometerData");
if (!gShockproofGetAccelerometerData) {
FreeLibrary(mLibrary);
mLibrary = nsnull;
--- a/widget/src/windows/nsDeviceContextSpecWin.cpp
+++ b/widget/src/windows/nsDeviceContextSpecWin.cpp
@@ -90,33 +90,33 @@ PRLogModuleInfo * kWidgetPrintingLogMod
class GlobalPrinters {
public:
static GlobalPrinters* GetInstance() { return &mGlobalPrinters; }
~GlobalPrinters() { FreeGlobalPrinters(); }
void FreeGlobalPrinters();
PRBool PrintersAreAllocated() { return mPrinters != nsnull; }
- LPTSTR GetItemFromList(PRInt32 aInx) { return mPrinters?mPrinters->ElementAt(aInx):nsnull; }
+ LPWSTR GetItemFromList(PRInt32 aInx) { return mPrinters?mPrinters->ElementAt(aInx):nsnull; }
nsresult EnumeratePrinterList();
- void GetDefaultPrinterName(LPTSTR& aDefaultPrinterName);
+ void GetDefaultPrinterName(nsString& aDefaultPrinterName);
PRInt32 GetNumPrinters() { return mPrinters?mPrinters->Length():0; }
protected:
GlobalPrinters() {}
nsresult EnumerateNativePrinters();
void ReallocatePrinters();
static GlobalPrinters mGlobalPrinters;
- static nsTArray<LPTSTR>* mPrinters;
+ static nsTArray<LPWSTR>* mPrinters;
};
//---------------
// static members
GlobalPrinters GlobalPrinters::mGlobalPrinters;
-nsTArray<LPTSTR>* GlobalPrinters::mPrinters = nsnull;
+nsTArray<LPWSTR>* GlobalPrinters::mPrinters = nsnull;
//******************************************************
// Define native paper sizes
//******************************************************
typedef struct {
short mPaperSize; // native enum
double mWidth;
@@ -203,63 +203,59 @@ nsDeviceContextSpecWin::~nsDeviceContext
GlobalPrinters::GetInstance()->FreeGlobalPrinters();
}
//------------------------------------------------------------------
// helper
static PRUnichar * GetDefaultPrinterNameFromGlobalPrinters()
{
- PRUnichar * printerName;
- LPTSTR lpPrtName;
- GlobalPrinters::GetInstance()->GetDefaultPrinterName(lpPrtName);
- nsAutoString str;
- NS_CopyNativeToUnicode(nsDependentCString((char *)lpPrtName), str);
- printerName = ToNewUnicode(str);
- free(lpPrtName);
- return printerName;
+ nsAutoString printerName;
+ GlobalPrinters::GetInstance()->GetDefaultPrinterName(printerName);
+ return ToNewUnicode(printerName);
}
//----------------------------------------------------------------
static nsresult
EnumerateNativePrinters(DWORD aWhichPrinters, LPWSTR aPrinterName, PRBool& aIsFound, PRBool& aIsFile)
{
#ifdef WINCE
aIsFound = PR_FALSE;
#else
DWORD dwSizeNeeded = 0;
DWORD dwNumItems = 0;
LPPRINTER_INFO_2W lpInfo = NULL;
// Get buffer size
- if (::EnumPrinters ( aWhichPrinters, NULL, 2, NULL, 0, &dwSizeNeeded, &dwNumItems )) {
+ if (::EnumPrintersW(aWhichPrinters, NULL, 2, NULL, 0, &dwSizeNeeded,
+ &dwNumItems)) {
return NS_ERROR_FAILURE;
}
// allocate memory
- lpInfo = (LPPRINTER_INFO_2W)HeapAlloc ( GetProcessHeap (), HEAP_ZERO_MEMORY, dwSizeNeeded );
- if ( lpInfo == NULL ) {
+ lpInfo = (LPPRINTER_INFO_2W) malloc(dwSizeNeeded);
+ if (!lpInfo) {
return NS_ERROR_OUT_OF_MEMORY;
}
- if (::EnumPrinters ( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)lpInfo, dwSizeNeeded, &dwSizeNeeded, &dwNumItems) == 0 ) {
- ::HeapFree(GetProcessHeap (), 0, lpInfo);
+ if (::EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)lpInfo,
+ dwSizeNeeded, &dwSizeNeeded, &dwNumItems) == 0) {
+ free(lpInfo);
return NS_OK;
}
-
for (DWORD i = 0; i < dwNumItems; i++ ) {
if (wcscmp(lpInfo[i].pPrinterName, aPrinterName) == 0) {
aIsFound = PR_TRUE;
aIsFile = wcscmp(lpInfo[i].pPortName, L"FILE:") == 0;
break;
}
}
- ::HeapFree(GetProcessHeap (), 0, lpInfo);
+ free(lpInfo);
#endif
return NS_OK;
}
//----------------------------------------------------------------
static void
CheckForPrintToFileWithName(LPWSTR aPrinterName, PRBool& aIsFile)
{
@@ -670,39 +666,17 @@ SetupDevModeFromSettings(LPDEVMODEW aDev
PRInt32 copies;
aPrintSettings->GetNumCopies(&copies);
aDevMode->dmCopies = copies;
aDevMode->dmFields |= DM_COPIES;
}
}
-#if defined(DEBUG_rods) || defined(DEBUG_dcone)
-static void DisplayLastError()
-{
- LPVOID lpMsgBuf;
- DWORD errCode = GetLastError();
-
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
-
- // Display the string.
- MessageBox( NULL, (const char *)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
-}
-#define DISPLAY_LAST_ERROR DisplayLastError();
-#else
#define DISPLAY_LAST_ERROR
-#endif
//----------------------------------------------------------------------------------
// Setup the object's data member with the selected printer's data
nsresult
nsDeviceContextSpecWin::GetDataFromPrinter(const PRUnichar * aName, nsIPrintSettings* aPS)
{
#ifdef WINCE
return NS_ERROR_NOT_IMPLEMENTED;
@@ -940,17 +914,17 @@ nsPrinterEnumeratorWin::GetPrinterNameLi
PRInt32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
nsTArray<nsString> *printers = new nsTArray<nsString>(numPrinters);
if (!printers)
return NS_ERROR_OUT_OF_MEMORY;
PRInt32 printerInx = 0;
while( printerInx < numPrinters ) {
- LPTSTR name = GlobalPrinters::GetInstance()->GetItemFromList(printerInx++);
+ LPWSTR name = GlobalPrinters::GetInstance()->GetItemFromList(printerInx++);
#ifdef UNICODE
nsDependentString newName(name);
#else
nsAutoString newName;
NS_CopyNativeToUnicode(nsDependentCString(name), newName);
#endif
printers->AppendElement(newName);
}
@@ -973,17 +947,17 @@ NS_IMETHODIMP nsPrinterEnumeratorWin::Di
//----------------------------------------------------------------------------------
// THe array hold the name and port for each printer
void
GlobalPrinters::ReallocatePrinters()
{
if (PrintersAreAllocated()) {
FreeGlobalPrinters();
}
- mPrinters = new nsTArray<LPTSTR>();
+ mPrinters = new nsTArray<LPWSTR>();
NS_ASSERTION(mPrinters, "Printers Array is NULL!");
}
//----------------------------------------------------------------------------------
void
GlobalPrinters::FreeGlobalPrinters()
{
if (mPrinters != nsnull) {
@@ -999,26 +973,28 @@ GlobalPrinters::FreeGlobalPrinters()
nsresult
GlobalPrinters::EnumerateNativePrinters()
{
nsresult rv = NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
#ifndef WINCE
PR_PL(("-----------------------\n"));
PR_PL(("EnumerateNativePrinters\n"));
- TCHAR szDefaultPrinterName[1024];
- DWORD status = GetProfileString("devices", 0, ",", szDefaultPrinterName, sizeof(szDefaultPrinterName)/sizeof(TCHAR));
+ WCHAR szDefaultPrinterName[1024];
+ DWORD status = GetProfileStringW(L"devices", 0, L",",
+ szDefaultPrinterName,
+ NS_ARRAY_LENGTH(szDefaultPrinterName));
if (status > 0) {
DWORD count = 0;
- LPTSTR sPtr = (LPTSTR)szDefaultPrinterName;
- LPTSTR ePtr = (LPTSTR)(szDefaultPrinterName+(status*sizeof(TCHAR)));
- LPTSTR prvPtr = sPtr;
+ LPWSTR sPtr = szDefaultPrinterName;
+ LPWSTR ePtr = szDefaultPrinterName + status;
+ LPWSTR prvPtr = sPtr;
while (sPtr < ePtr) {
if (*sPtr == NULL) {
- LPTSTR name = _tcsdup(prvPtr);
+ LPWSTR name = wcsdup(prvPtr);
mPrinters->AppendElement(name);
PR_PL(("Printer Name: %s\n", prvPtr));
prvPtr = sPtr+1;
count++;
}
sPtr++;
}
rv = NS_OK;
@@ -1026,38 +1002,40 @@ GlobalPrinters::EnumerateNativePrinters(
PR_PL(("-----------------------\n"));
#endif
return rv;
}
//------------------------------------------------------------------
// Uses the GetProfileString to get the default printer from the registry
void
-GlobalPrinters::GetDefaultPrinterName(LPTSTR& aDefaultPrinterName)
+GlobalPrinters::GetDefaultPrinterName(nsString& aDefaultPrinterName)
{
#ifndef WINCE
- aDefaultPrinterName = nsnull;
- TCHAR szDefaultPrinterName[1024];
- DWORD status = GetProfileString("windows", "device", 0, szDefaultPrinterName, sizeof(szDefaultPrinterName)/sizeof(TCHAR));
+ aDefaultPrinterName.Truncate();
+ WCHAR szDefaultPrinterName[1024];
+ DWORD status = GetProfileStringW(L"windows", L"device", 0,
+ szDefaultPrinterName,
+ NS_ARRAY_LENGTH(szDefaultPrinterName));
if (status > 0) {
- TCHAR comma = (TCHAR)',';
- LPTSTR sPtr = (LPTSTR)szDefaultPrinterName;
+ WCHAR comma = ',';
+ LPWSTR sPtr = szDefaultPrinterName;
while (*sPtr != comma && *sPtr != NULL)
sPtr++;
if (*sPtr == comma) {
*sPtr = NULL;
}
- aDefaultPrinterName = _tcsdup(szDefaultPrinterName);
+ aDefaultPrinterName = szDefaultPrinterName;
} else {
- aDefaultPrinterName = _tcsdup("");
+ aDefaultPrinterName = NS_LITERAL_STRING("");
}
PR_PL(("DEFAULT PRINTER [%s]\n", aDefaultPrinterName));
#else
- aDefaultPrinterName = TEXT("UNKNOWN");
+ aDefaultPrinterName = NS_LITERAL_STRING("UNKNOWN");
#endif
}
//----------------------------------------------------------------------------------
// This goes and gets the list of available printers and puts
// the default printer at the beginning of the list
nsresult
GlobalPrinters::EnumeratePrinterList()
@@ -1067,33 +1045,32 @@ GlobalPrinters::EnumeratePrinterList()
ReallocatePrinters();
// any of these could only fail with an OUT_MEMORY_ERROR
// PRINTER_ENUM_LOCAL should get the network printers on Win95
nsresult rv = EnumerateNativePrinters();
if (NS_FAILED(rv)) return rv;
// get the name of the default printer
- LPTSTR defPrinterName;
+ nsAutoString defPrinterName;
GetDefaultPrinterName(defPrinterName);
// put the default printer at the beginning of list
- if (defPrinterName != nsnull) {
+ if (!defPrinterName.IsEmpty()) {
for (PRInt32 i=0;i<mPrinters->Length();i++) {
- LPTSTR name = mPrinters->ElementAt(i);
- if (!_tcscmp(name, defPrinterName)) {
+ LPWSTR name = mPrinters->ElementAt(i);
+ if (defPrinterName.Equals(name)) {
if (i > 0) {
- LPTSTR ptr = mPrinters->ElementAt(0);
+ LPWSTR ptr = mPrinters->ElementAt(0);
mPrinters->ElementAt(0) = name;
mPrinters->ElementAt(i) = ptr;
}
break;
}
}
- free(defPrinterName);
}
// make sure we at least tried to get the printers
if (!PrintersAreAllocated()) {
PR_PL(("***** nsDeviceContextSpecWin::EnumeratePrinterList - Printers aren`t allocated\n"));
return NS_ERROR_FAILURE;
}
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -99,16 +99,20 @@
**
** BLOCK: Includes
**
** Include headers.
**
**************************************************************
**************************************************************/
+#ifdef MOZ_IPC
+#include "mozilla/ipc/SyncChannel.h"
+#endif
+
#include "nsWindow.h"
#include <windows.h>
#include <process.h>
#include <commctrl.h>
#include <unknwn.h>
#include "prlog.h"
@@ -3563,16 +3567,21 @@ PRBool nsWindow::ConvertStatus(nsEventSt
* The main Windows event procedures and associated
* message processing methods.
*
**************************************************************/
// The WndProc procedure for all nsWindows in this toolkit
LRESULT CALLBACK nsWindow::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
+#ifdef MOZ_IPC
+ NS_ASSERTION(!mozilla::ipc::SyncChannel::IsPumpingMessages(),
+ "Failed to prevent a nonqueued message from running!");
+#endif
+
// create this here so that we store the last rolled up popup until after
// the event has been processed.
nsAutoRollup autoRollup;
LRESULT popupHandlingResult;
if ( DealWithPopups(hWnd, msg, wParam, lParam, &popupHandlingResult) )
return popupHandlingResult;
--- a/widget/src/xpwidgets/Makefile.in
+++ b/widget/src/xpwidgets/Makefile.in
@@ -60,17 +60,21 @@ REQUIRES = xpcom \
uconv \
unicharutil \
view \
windowwatcher \
qcms \
thebes \
$(NULL)
-DEFINES += -D_IMPL_NS_WIDGET -DUSE_TLS_FOR_TOOLKIT
+DEFINES += \
+ -D_IMPL_NS_WIDGET \
+ -DUSE_TLS_FOR_TOOLKIT \
+ -DNO_NSPR_10_SUPPORT=1 \
+ $(NULL)
CPPSRCS = \
nsBaseAppShell.cpp \
nsBaseWidget.cpp \
nsTransferable.cpp \
nsHTMLFormatConverter.cpp \
nsBaseDragService.cpp \
nsPrimitiveHelpers.cpp \
@@ -93,20 +97,21 @@ ifneq (,$(filter beos qt gtk2 os2 cocoa
CPPSRCS += nsBaseFilePicker.cpp
REQUIRES += docshell view intl
endif
ifneq (,$(filter qt gtk2 windows cocoa,$(MOZ_WIDGET_TOOLKIT)))
CPPSRCS += nsNativeTheme.cpp
endif
-LOCAL_INCLUDES = \
+LOCAL_INCLUDES += \
-I$(srcdir)/../$(MOZ_WIDGET_TOOLKIT) \
-I$(srcdir) \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
CXXFLAGS += $(TK_CFLAGS)
-
--- a/widget/src/xpwidgets/nsBaseAppShell.cpp
+++ b/widget/src/xpwidgets/nsBaseAppShell.cpp
@@ -36,16 +36,20 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsBaseAppShell.h"
#include "nsThreadUtils.h"
#include "nsIObserverService.h"
#include "nsServiceManagerUtils.h"
+#ifdef MOZ_IPC
+#include "base/message_loop.h"
+#endif
+
// When processing the next thread event, the appshell may process native
// events (if not in performance mode), which can result in suppressing the
// next thread event for at most this many ticks:
#define THREAD_EVENT_STARVATION_LIMIT PR_MillisecondsToInterval(20)
NS_IMPL_THREADSAFE_ISUPPORTS3(nsBaseAppShell, nsIAppShell, nsIThreadObserver,
nsIObserver)
@@ -54,17 +58,17 @@ nsBaseAppShell::nsBaseAppShell()
, mBlockedWait(nsnull)
, mFavorPerf(0)
, mNativeEventPending(0)
, mEventloopNestingLevel(0)
, mStarvationDelay(0)
, mSwitchTime(0)
, mLastNativeEventTime(0)
, mEventloopNestingState(eEventloopNone)
- , mRunWasCalled(PR_FALSE)
+ , mRunning(PR_FALSE)
, mExiting(PR_FALSE)
, mBlockNativeEvent(PR_FALSE)
{
}
nsresult
nsBaseAppShell::Init()
{
@@ -156,31 +160,42 @@ nsBaseAppShell::DoProcessNextNativeEvent
}
//-------------------------------------------------------------------------
// nsIAppShell methods:
NS_IMETHODIMP
nsBaseAppShell::Run(void)
{
+ NS_ENSURE_STATE(!mRunning); // should not call Run twice
+ mRunning = PR_TRUE;
+
nsIThread *thread = NS_GetCurrentThread();
- NS_ENSURE_STATE(!mRunWasCalled); // should not call Run twice
- mRunWasCalled = PR_TRUE;
-
+#ifdef MOZ_IPC
+ MessageLoop::current()->Run();
+#else
while (!mExiting)
NS_ProcessNextEvent(thread);
+#endif
NS_ProcessPendingEvents(thread);
+
+ mRunning = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsBaseAppShell::Exit(void)
{
+#ifdef MOZ_IPC
+ if (mRunning && !mExiting) {
+ MessageLoop::current()->Quit();
+ }
+#endif
mExiting = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsBaseAppShell::FavorPerformanceHint(PRBool favorPerfOverStarvation,
PRUint32 starvationDelay)
{
--- a/widget/src/xpwidgets/nsBaseAppShell.h
+++ b/widget/src/xpwidgets/nsBaseAppShell.h
@@ -114,17 +114,17 @@ private:
PRIntervalTime mSwitchTime;
PRIntervalTime mLastNativeEventTime;
enum EventloopNestingState {
eEventloopNone, // top level thread execution
eEventloopXPCOM, // innermost native event loop is ProcessNextNativeEvent
eEventloopOther // innermost native event loop is a native library/plugin etc
};
EventloopNestingState mEventloopNestingState;
- PRPackedBool mRunWasCalled;
+ PRPackedBool mRunning;
PRPackedBool mExiting;
/**
* mBlockNativeEvent blocks the appshell from processing native events.
* It is set to PR_TRUE while a nested native event loop (eEventloopOther)
* is processing gecko events in NativeEventCallback(), thus queuing up
* native events until we return to that loop (bug 420148).
* We force mBlockNativeEvent to PR_FALSE in case handling one of the gecko
* events spins up a nested XPCOM event loop (eg. modal window) which would
--- a/xpcom/base/Makefile.in
+++ b/xpcom/base/Makefile.in
@@ -42,16 +42,17 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = xpcom
XPIDL_MODULE = xpcom_base
LIBRARY_NAME = xpcombase_s
GRE_MODULE = 1
MOZILLA_INTERNAL_API =1
+LIBXUL_LIBRARY = 1
REQUIRES = string \
$(NULL)
CPPSRCS = \
nsAllocator.cpp \
nsVersionComparatorImpl.cpp \
nsConsoleMessage.cpp \
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -71,16 +71,19 @@
#include <tchar.h>
#include "nsString.h"
#endif
static void
Abort(const char *aMsg);
static void
+RealBreak();
+
+static void
Break(const char *aMsg);
#if defined(XP_OS2)
# define INCL_WINDIALOGS // need for WinMessageBox
# include <os2.h>
# include <string.h>
#endif /* XP_OS2 */
@@ -312,16 +315,19 @@ NS_DebugBreak(PRUint32 aSeverity, const
case NS_DEBUG_WARNING:
return;
case NS_DEBUG_BREAK:
Break(buf.buffer);
return;
case NS_DEBUG_ABORT:
+#ifdef DEBUG
+ RealBreak();
+#endif
nsTraceRefcntImpl::WalkTheStack(stderr);
Abort(buf.buffer);
return;
}
// Now we deal with assertions
PR_AtomicIncrement(&gAssertionCount);
@@ -383,16 +389,35 @@ Abort(const char *aMsg)
// (Written this way to lessen the likelihood of it being optimized away.)
gAssertionCount += *((PRInt32 *) 0); // TODO annotation saying we know
// this is crazy
// Still haven't aborted? Try _exit().
PR_ProcessExit(127);
}
+static void
+RealBreak()
+{
+#if defined(_WIN32)
+#ifndef WINCE
+ ::DebugBreak();
+#endif
+#elif defined(XP_OS2)
+ asm("int $3");
+#elif defined(XP_BEOS)
+#elif defined(XP_MACOSX)
+ raise(SIGTRAP);
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__))
+ asm("int $3");
+#else
+ // don't know how to break on this platform
+#endif
+}
+
// Abort() calls this function, don't call it!
static void
Break(const char *aMsg)
{
#if defined(_WIN32)
#ifndef WINCE // we really just want to crash for now
static int ignoreDebugger;
if (!ignoreDebugger) {
@@ -443,18 +468,17 @@ Break(const char *aMsg)
//If we are ignored exit this way..
_exit(3);
case IDIGNORE:
return;
}
}
- ::DebugBreak();
-
+ RealBreak();
#endif // WINCE
#elif defined(XP_OS2)
char msg[1200];
PR_snprintf(msg, sizeof(msg),
"%s\n\nClick Cancel to Debug Application.\n"
"Click Enter to continue running the Application.", aMsg);
ULONG code = MBID_ERROR;
code = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg,
@@ -467,27 +491,28 @@ Break(const char *aMsg)
* Break()
* Actually, that's a really bad idea since this happens a lot with threadsafe
* assertions and since it means that you can't actually run the debug build
* outside a debugger without it crashing constantly.
*/
if (( code == MBID_ENTER ) || (code == MBID_ERROR))
return;
- asm("int $3");
+ RealBreak();
#elif defined(XP_BEOS)
DEBUGGER(aMsg);
+ RealBreak();
#elif defined(XP_MACOSX)
/* Note that we put this Mac OS X test above the GNUC/x86 test because the
* GNUC/x86 test is also true on Intel Mac OS X and we want the PPC/x86
* impls to be the same.
*/
- raise(SIGTRAP);
+ RealBreak();
#elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__))
- asm("int $3");
+ RealBreak();
#else
// don't know how to break on this platform
#endif
}
static const nsDebugImpl kImpl;
NS_METHOD
--- a/xpcom/base/nsTraceRefcntImpl.cpp
+++ b/xpcom/base/nsTraceRefcntImpl.cpp
@@ -44,16 +44,27 @@
#include "prlog.h"
#include "plstr.h"
#include "prlink.h"
#include <stdlib.h>
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include <math.h>
#include "nsStackWalk.h"
+#include "nsString.h"
+
+#ifdef MOZ_IPC
+#include "nsXULAppAPI.h"
+#ifdef XP_WIN
+#include <process.h>
+#define getpid _getpid
+#else
+#include <unistd.h>
+#endif
+#endif
#ifdef HAVE_LIBDL
#include <dlfcn.h>
#endif
////////////////////////////////////////////////////////////////////////////////
NS_COM void
@@ -313,18 +324,22 @@ public:
}
static PRBool HaveLeaks(nsTraceRefcntStats* stats) {
return ((stats->mAddRefs != stats->mReleases) ||
(stats->mCreates != stats->mDestroys));
}
PRBool PrintDumpHeader(FILE* out, const char* msg, nsTraceRefcntImpl::StatisticsType type) {
+#ifdef MOZ_IPC
+ fprintf(out, "\n== BloatView: %s, %s process %d\n", msg,
+ XRE_ChildProcessTypeToString(XRE_GetProcessType()), getpid());
+#else
fprintf(out, "\n== BloatView: %s\n", msg);
-
+#endif
nsTraceRefcntStats& stats =
(type == nsTraceRefcntImpl::NEW_STATS) ? mNewStats : mAllStats;
if (gLogLeaksOnly && !HaveLeaks(&stats))
return PR_FALSE;
fprintf(out,
"\n" \
" |<----------------Class--------------->|<-----Bytes------>|<----------------Objects---------------->|<--------------References-------------->|\n" \
@@ -629,28 +644,43 @@ static PRBool InitLog(const char* envVar
}
else if (nsCRT::strcmp(value, "2") == 0) {
*result = stderr;
fprintf(stdout, "### %s defined -- logging %s to stderr\n",
envVar, msg);
return PR_TRUE;
}
else {
- FILE *stream = ::fopen(value, "w");
+ FILE *stream;
+ nsCAutoString fname(value);
+#ifdef MOZ_IPC
+ if (XRE_GetProcessType() != GeckoProcessType_Default) {
+ bool hasLogExtension =
+ fname.RFind(".log", PR_TRUE, -1, 4) == kNotFound ? false : true;
+ if (hasLogExtension)
+ fname.Cut(fname.Length() - 4, 4);
+ fname.AppendLiteral("_");
+ fname.Append((char*)XRE_ChildProcessTypeToString(XRE_GetProcessType()));
+ fname.AppendLiteral("_pid");
+ fname.AppendInt(getpid());
+ if (hasLogExtension)
+ fname.AppendLiteral(".log");
+ }
+#endif
+ stream = ::fopen(fname.get(), "w");
if (stream != NULL) {
*result = stream;
fprintf(stdout, "### %s defined -- logging %s to %s\n",
- envVar, msg, value);
- return PR_TRUE;
+ envVar, msg, fname.get());
}
else {
fprintf(stdout, "### %s defined -- unable to log %s to %s\n",
- envVar, msg, value);
- return PR_FALSE;
+ envVar, msg, fname.get());
}
+ return stream != NULL;
}
}
return PR_FALSE;
}
static PLHashNumber HashNumber(const void* aKey)
{
--- a/xpcom/build.mk
+++ b/xpcom/build.mk
@@ -37,8 +37,12 @@
TIERS += xpcom
ifdef NS_TRACE_MALLOC
tier_xpcom_dirs = tools/trace-malloc/lib
endif
tier_xpcom_dirs += xpcom
+
+ifdef MOZ_IPC
+tier_xpcom_dirs += ipc/chromium ipc/glue
+endif
--- a/xpcom/build/Makefile.in
+++ b/xpcom/build/Makefile.in
@@ -155,16 +155,18 @@ ifndef MOZ_ENABLE_LIBXUL
FORCE_SHARED_LIB = 1
endif
# UNIX98 iconv support
OS_LIBS += $(LIBICONV)
GARBAGE += $(XPCOM_GLUE_SRC_LCSRCS) $(XPCOM_GLUE_SRC_LCPPSRCS) $(XPCOM_GLUENS_SRC_LCPPSRCS) $(wildcard *.$(OBJ_SUFFIX))
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
DEFINES += \
-D_IMPL_NS_COM \
-D_IMPL_NS_STRINGAPI \
-DEXPORT_XPT_API \
-DEXPORT_XPTC_API
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -32,17 +32,22 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "base/basictypes.h"
+#endif
+
#include "mozilla/XPCOM.h"
+#include "nsXULAppAPI.h"
#include "nsXPCOMPrivate.h"
#include "nsXPCOMCIDInternal.h"
#include "nsStaticComponents.h"
#include "prlink.h"
#include "nsObserverList.h"
@@ -140,16 +145,36 @@ NS_DECL_CLASSINFO(nsStringInputStream)
#include "nsMacUtilsImpl.h"
#endif
#include "nsSystemInfo.h"
#include "nsMemoryReporterManager.h"
#include <locale.h>
+#ifdef MOZ_IPC
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/message_loop.h"
+
+#include "mozilla/ipc/GeckoThread.h"
+
+using base::AtExitManager;
+using mozilla::ipc::BrowserProcessSubThread;
+
+namespace {
+
+static AtExitManager* sExitManager;
+static MessageLoop* sMessageLoop;
+static bool sCommandLineWasInitialized;
+static BrowserProcessSubThread* sIOThread;
+
+} /* anonymous namespace */
+#endif
+
using mozilla::TimeStamp;
// Registry Factory creation function defined in nsRegistry.cpp
// We hook into this function locally to create and register the registry
// Since noone outside xpcom needs to know about this and nsRegistry.cpp
// does not have a local include file, we are putting this definition
// here rather than in nsIRegistry.h
extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
@@ -544,16 +569,44 @@ NS_InitXPCOM3(nsIServiceManager* *result
staticComponents = kPStaticModules;
componentCount = kStaticModuleCount;
}
#endif
// We are not shutting down
gXPCOMShuttingDown = PR_FALSE;
+#ifdef MOZ_IPC
+ // Set up chromium libs
+ NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
+
+ if (!AtExitManager::AlreadyRegistered()) {
+ sExitManager = new AtExitManager();
+ NS_ENSURE_STATE(sExitManager);
+ }
+
+ if (!MessageLoop::current()) {
+ sMessageLoop = new MessageLoopForUI();
+ NS_ENSURE_STATE(sMessageLoop);
+ }
+
+ if (XRE_GetProcessType() == GeckoProcessType_Default &&
+ !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
+ scoped_ptr<BrowserProcessSubThread> ioThread(
+ new BrowserProcessSubThread(BrowserProcessSubThread::IO));
+ NS_ENSURE_TRUE(ioThread.get(), NS_ERROR_OUT_OF_MEMORY);
+
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_IO;
+ NS_ENSURE_TRUE(ioThread->StartWithOptions(options), NS_ERROR_FAILURE);
+
+ sIOThread = ioThread.release();
+ }
+#endif
+
NS_LogInit();
// Set up TimeStamp
rv = TimeStamp::Startup();
NS_ENSURE_SUCCESS(rv, rv);
// Establish the main thread here.
rv = nsThreadManager::get()->Init();
@@ -604,16 +657,40 @@ NS_InitXPCOM3(nsIServiceManager* *result
nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
}
if (appFileLocationProvider) {
rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
if (NS_FAILED(rv)) return rv;
}
+#ifdef MOZ_IPC
+ if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
+#ifdef OS_WIN
+ CommandLine::Init(0, nsnull);
+#else
+ nsCOMPtr<nsIFile> binaryFile;
+ nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
+ NS_GET_IID(nsIFile),
+ getter_AddRefs(binaryFile));
+ NS_ENSURE_STATE(binaryFile);
+
+ rv = binaryFile->AppendNative(NS_LITERAL_CSTRING("nonexistent-executable"));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString binaryPath;
+ rv = binaryFile->GetNativePath(binaryPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ static char const *const argv = { strdup(binaryPath.get()) };
+ CommandLine::Init(1, &argv);
+#endif
+ }
+#endif
+
NS_ASSERTION(nsComponentManagerImpl::gComponentManager == NULL, "CompMgr not null at init");
// Create the Component/Service Manager
nsComponentManagerImpl *compMgr = new nsComponentManagerImpl();
if (compMgr == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(compMgr);
@@ -912,16 +989,35 @@ ShutdownXPCOM(nsIServiceManager* servMgr
* BlockingResourceBase::Shutdown() runs after all other shutdown
* functions.
*/
BlockingResourceBase::Shutdown();
#endif
NS_LogTerm();
+#ifdef MOZ_IPC
+ if (sIOThread) {
+ delete sIOThread;
+ sIOThread = nsnull;
+ }
+ if (sMessageLoop) {
+ delete sMessageLoop;
+ sMessageLoop = nsnull;
+ }
+ if (sCommandLineWasInitialized) {
+ CommandLine::Terminate();
+ sCommandLineWasInitialized = false;
+ }
+ if (sExitManager) {
+ delete sExitManager;
+ sExitManager = nsnull;
+ }
+#endif
+
#ifdef GC_LEAK_DETECTOR
// Shutdown the Leak detector.
NS_ShutdownLeakDetector();
#endif
return NS_OK;
}
--- a/xpcom/build/nsXULAppAPI.h
+++ b/xpcom/build/nsXULAppAPI.h
@@ -40,16 +40,17 @@
#ifndef _nsXULAppAPI_h__
#define _nsXULAppAPI_h__
#include "prtypes.h"
#include "nsID.h"
#include "xrecore.h"
#include "nsXPCOM.h"
#include "nsISupports.h"
+#include "prlog.h"
/**
* Application-specific data needed to start the apprunner.
*
* @status FROZEN - This API is stable. Additional fields may be added to the
* end of the structure in the future. Runtime detection
* of the version of nsXREAppData can be determined by
* examining the "size" field.
@@ -413,9 +414,86 @@ XRE_API(nsresult,
nsXREAppData *aAppData))
/**
* Free a nsXREAppData structure that was allocated with XRE_CreateAppData.
*/
XRE_API(void,
XRE_FreeAppData, (nsXREAppData *aAppData))
+enum GeckoProcessType {
+ GeckoProcessType_Default = 0,
+
+ GeckoProcessType_Plugin,
+ GeckoProcessType_Content,
+
+ GeckoProcessType_IPDLUnitTest,
+
+ GeckoProcessType_End,
+ GeckoProcessType_Invalid = GeckoProcessType_End
+};
+
+static const char* const kGeckoProcessTypeString[] = {
+ "default",
+ "plugin",
+ "tab",
+ "ipdlunittest"
+};
+
+PR_STATIC_ASSERT(sizeof(kGeckoProcessTypeString) /
+ sizeof(kGeckoProcessTypeString[0]) ==
+ GeckoProcessType_End);
+
+
+XRE_API(const char*,
+ XRE_ChildProcessTypeToString, (GeckoProcessType aProcessType))
+
+XRE_API(GeckoProcessType,
+ XRE_StringToChildProcessType, (const char* aProcessTypeString))
+
+XRE_API(nsresult,
+ XRE_InitChildProcess, (int aArgc,
+ char* aArgv[],
+ GeckoProcessType aProcess))
+
+XRE_API(GeckoProcessType,
+ XRE_GetProcessType, ())
+
+typedef void (*MainFunction)(void* aData);
+
+XRE_API(nsresult,
+ XRE_InitParentProcess, (int aArgc,
+ char* aArgv[],
+ MainFunction aMainFunction,
+ void* aMainFunctionExtraData))
+
+XRE_API(int,
+ XRE_RunIPDLTest, (int aArgc,
+ char* aArgv[]))
+
+XRE_API(nsresult,
+ XRE_RunAppShell, ())
+
+XRE_API(nsresult,
+ XRE_InitCommandLine, (int aArgc, char* aArgv[]))
+
+XRE_API(nsresult,
+ XRE_DeinitCommandLine, ())
+
+class MessageLoop;
+
+XRE_API(void,
+ XRE_ShutdownChildProcess, ())
+
+XRE_API(MessageLoop*,
+ XRE_GetIOMessageLoop, ())
+
+struct JSContext;
+struct JSString;
+
+XRE_API(bool,
+ XRE_SendTestShellCommand, (JSContext* aCx,
+ JSString* aCommand,
+ void* aCallback))
+XRE_API(bool,
+ XRE_ShutdownTestShell, ())
+
#endif // _nsXULAppAPI_h__