import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,27 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PContent;
include protocol PTestShellCommand;
namespace mozilla {
namespace ipc {
async protocol PTestShell
{
manager PContent;
manages PTestShellCommand;
child:
async __delete__();
async ExecuteCommand(nsString aCommand);
async PTestShellCommand(nsString aCommand);
};
} // namespace ipc
} // namespace mozilla

View file

@ -0,0 +1,20 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PTestShell;
namespace mozilla {
namespace ipc {
protocol PTestShellCommand
{
manager PTestShell;
parent:
async __delete__(nsString aResponse);
};
} // namespace ipc
} // namespace mozilla

View file

@ -0,0 +1,56 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TestShellChild.h"
using mozilla::ipc::TestShellChild;
using mozilla::ipc::PTestShellCommandChild;
using mozilla::ipc::XPCShellEnvironment;
TestShellChild::TestShellChild()
: mXPCShell(XPCShellEnvironment::CreateEnvironment())
{
}
bool
TestShellChild::RecvExecuteCommand(const nsString& aCommand)
{
if (mXPCShell->IsQuitting()) {
NS_WARNING("Commands sent after quit command issued!");
return false;
}
return mXPCShell->EvaluateString(aCommand);
}
PTestShellCommandChild*
TestShellChild::AllocPTestShellCommandChild(const nsString& aCommand)
{
return new PTestShellCommandChild();
}
bool
TestShellChild::DeallocPTestShellCommandChild(PTestShellCommandChild* aCommand)
{
delete aCommand;
return true;
}
bool
TestShellChild::RecvPTestShellCommandConstructor(PTestShellCommandChild* aActor,
const nsString& aCommand)
{
if (mXPCShell->IsQuitting()) {
NS_WARNING("Commands sent after quit command issued!");
return false;
}
nsString response;
if (!mXPCShell->EvaluateString(aCommand, &response)) {
return false;
}
return PTestShellCommandChild::Send__delete__(aActor, response);
}

View file

@ -0,0 +1,45 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ipc_testshell_TestShellChild_h
#define ipc_testshell_TestShellChild_h 1
#include "mozilla/ipc/PTestShellChild.h"
#include "mozilla/ipc/PTestShellCommandChild.h"
#include "mozilla/ipc/XPCShellEnvironment.h"
#include "nsAutoPtr.h"
namespace mozilla {
namespace ipc {
class XPCShellEnvironment;
class TestShellChild : public PTestShellChild
{
public:
TestShellChild();
bool
RecvExecuteCommand(const nsString& aCommand);
PTestShellCommandChild*
AllocPTestShellCommandChild(const nsString& aCommand);
bool
RecvPTestShellCommandConstructor(PTestShellCommandChild* aActor,
const nsString& aCommand);
bool
DeallocPTestShellCommandChild(PTestShellCommandChild* aCommand);
private:
nsAutoPtr<XPCShellEnvironment> mXPCShell;
};
} /* namespace ipc */
} /* namespace mozilla */
#endif /* ipc_testshell_TestShellChild_h */

View file

@ -0,0 +1,109 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TestShellParent.h"
/* This must occur *after* TestShellParent.h to avoid typedefs conflicts. */
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "xpcpublic.h"
using namespace mozilla;
using mozilla::ipc::TestShellParent;
using mozilla::ipc::TestShellCommandParent;
using mozilla::ipc::PTestShellCommandParent;
using mozilla::dom::ContentParent;
void
TestShellParent::ActorDestroy(ActorDestroyReason aWhy)
{
// Implement me! Bug 1005177
}
PTestShellCommandParent*
TestShellParent::AllocPTestShellCommandParent(const nsString& aCommand)
{
return new TestShellCommandParent();
}
bool
TestShellParent::DeallocPTestShellCommandParent(PTestShellCommandParent* aActor)
{
delete aActor;
return true;
}
bool
TestShellParent::CommandDone(TestShellCommandParent* command,
const nsString& aResponse)
{
// XXX what should happen if the callback fails?
/*bool ok = */command->RunCallback(aResponse);
command->ReleaseCallback();
return true;
}
bool
TestShellCommandParent::SetCallback(JSContext* aCx,
const JS::Value& aCallback)
{
if (!mCallback.initialized()) {
mCallback.init(aCx, aCallback);
return true;
}
mCallback = aCallback;
return true;
}
bool
TestShellCommandParent::RunCallback(const nsString& aResponse)
{
NS_ENSURE_TRUE(mCallback.isObject(), false);
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. This is just for testing and not in any spec.
dom::AutoEntryScript aes(&mCallback.toObject(), "TestShellCommand");
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
JSString* str = JS_NewUCStringCopyN(cx, aResponse.get(), aResponse.Length());
NS_ENSURE_TRUE(str, false);
JS::Rooted<JS::Value> strVal(cx, JS::StringValue(str));
JS::Rooted<JS::Value> rval(cx);
JS::Rooted<JS::Value> callback(cx, mCallback);
bool ok = JS_CallFunctionValue(cx, global, callback, JS::HandleValueArray(strVal), &rval);
NS_ENSURE_TRUE(ok, false);
return true;
}
void
TestShellCommandParent::ReleaseCallback()
{
mCallback.reset();
}
bool
TestShellCommandParent::ExecuteCallback(const nsString& aResponse)
{
return static_cast<TestShellParent*>(Manager())->CommandDone(
this, aResponse);
}
void
TestShellCommandParent::ActorDestroy(ActorDestroyReason why)
{
if (why == AbnormalShutdown) {
ExecuteCallback(EmptyString());
}
}

View file

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ipc_testshell_TestShellParent_h
#define ipc_testshell_TestShellParent_h 1
#include "mozilla/ipc/PTestShellParent.h"
#include "mozilla/ipc/PTestShellCommandParent.h"
#include "js/TypeDecls.h"
#include "js/RootingAPI.h"
#include "nsString.h"
namespace mozilla {
namespace ipc {
class TestShellCommandParent;
class TestShellParent : public PTestShellParent
{
public:
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
PTestShellCommandParent*
AllocPTestShellCommandParent(const nsString& aCommand) override;
bool
DeallocPTestShellCommandParent(PTestShellCommandParent* aActor) override;
bool
CommandDone(TestShellCommandParent* aActor, const nsString& aResponse);
};
class TestShellCommandParent : public PTestShellCommandParent
{
public:
TestShellCommandParent() {}
bool SetCallback(JSContext* aCx, const JS::Value& aCallback);
bool RunCallback(const nsString& aResponse);
void ReleaseCallback();
protected:
bool ExecuteCallback(const nsString& aResponse);
void ActorDestroy(ActorDestroyReason why);
bool Recv__delete__(const nsString& aResponse) {
return ExecuteCallback(aResponse);
}
private:
JS::PersistentRooted<JS::Value> mCallback;
};
} /* namespace ipc */
} /* namespace mozilla */
#endif /* ipc_testshell_TestShellParent_h */

View file

@ -0,0 +1,541 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_IO_H
#include <io.h> /* for isatty() */
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* for isatty() */
#endif
#include "base/basictypes.h"
#include "jsapi.h"
#include "xpcpublic.h"
#include "XPCShellEnvironment.h"
#include "mozilla/XPCOM.h"
#include "nsIChannel.h"
#include "nsIClassInfo.h"
#include "nsIDirectoryService.h"
#include "nsIPrincipal.h"
#include "nsIScriptSecurityManager.h"
#include "nsIURI.h"
#include "nsIXPConnect.h"
#include "nsIXPCScriptable.h"
#include "nsJSUtils.h"
#include "nsJSPrincipals.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "BackstagePass.h"
#include "TestShellChild.h"
#include "TestShellParent.h"
using mozilla::ipc::XPCShellEnvironment;
using mozilla::ipc::TestShellChild;
using mozilla::ipc::TestShellParent;
using mozilla::AutoSafeJSContext;
using mozilla::dom::AutoJSAPI;
using mozilla::dom::AutoEntryScript;
using namespace JS;
namespace {
static const char kDefaultRuntimeScriptFilename[] = "xpcshell.js";
inline XPCShellEnvironment*
Environment(Handle<JSObject*> global)
{
AutoJSAPI jsapi;
if (!jsapi.Init(global)) {
return nullptr;
}
JSContext* cx = jsapi.cx();
Rooted<Value> v(cx);
if (!JS_GetProperty(cx, global, "__XPCShellEnvironment", &v) ||
!v.get().isDouble())
{
return nullptr;
}
return static_cast<XPCShellEnvironment*>(v.get().toPrivate());
}
static bool
Print(JSContext *cx, unsigned argc, JS::Value *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
for (unsigned i = 0; i < args.length(); i++) {
JSString *str = JS::ToString(cx, args[i]);
if (!str)
return false;
JSAutoByteString bytes(cx, str);
if (!bytes)
return false;
fprintf(stdout, "%s%s", i ? " " : "", bytes.ptr());
fflush(stdout);
}
fputc('\n', stdout);
args.rval().setUndefined();
return true;
}
static bool
GetLine(char *bufp,
FILE *file,
const char *prompt)
{
char line[256];
fputs(prompt, stdout);
fflush(stdout);
if (!fgets(line, sizeof line, file))
return false;
strcpy(bufp, line);
return true;
}
static bool
Dump(JSContext *cx, unsigned argc, JS::Value *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (!args.length())
return true;
JSString *str = JS::ToString(cx, args[0]);
if (!str)
return false;
JSAutoByteString bytes(cx, str);
if (!bytes)
return false;
fputs(bytes.ptr(), stdout);
fflush(stdout);
return true;
}
static bool
Load(JSContext *cx,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
if (!obj)
return false;
if (!JS_IsGlobalObject(obj)) {
JS_ReportErrorASCII(cx, "Trying to load() into a non-global object");
return false;
}
for (unsigned i = 0; i < args.length(); i++) {
JS::Rooted<JSString*> str(cx, JS::ToString(cx, args[i]));
if (!str)
return false;
JSAutoByteString filename(cx, str);
if (!filename)
return false;
FILE *file = fopen(filename.ptr(), "r");
if (!file) {
filename.clear();
if (!filename.encodeUtf8(cx, str))
return false;
JS_ReportErrorUTF8(cx, "cannot open file '%s' for reading", filename.ptr());
return false;
}
JS::CompileOptions options(cx);
options.setUTF8(true)
.setFileAndLine(filename.ptr(), 1);
JS::Rooted<JSScript*> script(cx);
bool ok = JS::Compile(cx, options, file, &script);
fclose(file);
if (!ok)
return false;
if (!JS_ExecuteScript(cx, script)) {
return false;
}
}
args.rval().setUndefined();
return true;
}
static bool
Version(JSContext *cx,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().setInt32(JS_GetVersion(cx));
if (args.get(0).isInt32())
JS_SetVersionForCompartment(js::GetContextCompartment(cx),
JSVersion(args[0].toInt32()));
return true;
}
static bool
Quit(JSContext *cx,
unsigned argc,
JS::Value *vp)
{
Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
XPCShellEnvironment* env = Environment(global);
env->SetIsQuitting();
return false;
}
static bool
DumpXPC(JSContext *cx,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs args = CallArgsFromVp(argc, vp);
uint16_t depth = 2;
if (args.length() > 0) {
if (!JS::ToUint16(cx, args[0], &depth))
return false;
}
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
if (xpc)
xpc->DebugDump(int16_t(depth));
args.rval().setUndefined();
return true;
}
static bool
GC(JSContext *cx,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS_GC(cx);
args.rval().setUndefined();
return true;
}
#ifdef JS_GC_ZEAL
static bool
GCZeal(JSContext *cx, unsigned argc, JS::Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
uint32_t zeal;
if (!ToUint32(cx, args.get(0), &zeal))
return false;
JS_SetGCZeal(cx, uint8_t(zeal), JS_DEFAULT_ZEAL_FREQ);
return true;
}
#endif
const JSFunctionSpec gGlobalFunctions[] =
{
JS_FS("print", Print, 0,0),
JS_FS("load", Load, 1,0),
JS_FS("quit", Quit, 0,0),
JS_FS("version", Version, 1,0),
JS_FS("dumpXPC", DumpXPC, 1,0),
JS_FS("dump", Dump, 1,0),
JS_FS("gc", GC, 0,0),
#ifdef JS_GC_ZEAL
JS_FS("gczeal", GCZeal, 1,0),
#endif
JS_FS_END
};
typedef enum JSShellErrNum
{
#define MSG_DEF(name, number, count, exception, format) \
name = number,
#include "jsshell.msg"
#undef MSG_DEF
JSShellErr_Limit
#undef MSGDEF
} JSShellErrNum;
} /* anonymous namespace */
void
XPCShellEnvironment::ProcessFile(JSContext *cx,
const char *filename,
FILE *file,
bool forceTTY)
{
XPCShellEnvironment* env = this;
JS::Rooted<JS::Value> result(cx);
int lineno, startline;
bool ok, hitEOF;
char *bufp, buffer[4096];
JSString *str;
JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
MOZ_ASSERT(global);
if (forceTTY) {
file = stdin;
}
else if (!isatty(fileno(file)))
{
/*
* It's not interactive - just execute it.
*
* Support the UNIX #! shell hack; gobble the first line if it starts
* with '#'. TODO - this isn't quite compatible with sharp variables,
* as a legal js program (using sharp variables) might start with '#'.
* But that would require multi-character lookahead.
*/
int ch = fgetc(file);
if (ch == '#') {
while((ch = fgetc(file)) != EOF) {
if(ch == '\n' || ch == '\r')
break;
}
}
ungetc(ch, file);
JS::CompileOptions options(cx);
options.setUTF8(true)
.setFileAndLine(filename, 1);
JS::Rooted<JSScript*> script(cx);
if (JS::Compile(cx, options, file, &script))
(void)JS_ExecuteScript(cx, script, &result);
return;
}
/* It's an interactive filehandle; drop into read-eval-print loop. */
lineno = 1;
hitEOF = false;
do {
bufp = buffer;
*bufp = '\0';
/*
* Accumulate lines until we get a 'compilable unit' - one that either
* generates an error (before running out of source) or that compiles
* cleanly. This should be whenever we get a complete statement that
* coincides with the end of a line.
*/
startline = lineno;
do {
if (!GetLine(bufp, file, startline == lineno ? "js> " : "")) {
hitEOF = true;
break;
}
bufp += strlen(bufp);
lineno++;
} while (!JS_BufferIsCompilableUnit(cx, global, buffer, strlen(buffer)));
/* Clear any pending exception from previous failed compiles. */
JS_ClearPendingException(cx);
JS::CompileOptions options(cx);
options.setFileAndLine("typein", startline);
JS::Rooted<JSScript*> script(cx);
if (JS_CompileScript(cx, buffer, strlen(buffer), options, &script)) {
JS::WarningReporter older;
ok = JS_ExecuteScript(cx, script, &result);
if (ok && !result.isUndefined()) {
/* Suppress warnings from JS::ToString(). */
older = JS::SetWarningReporter(cx, nullptr);
str = JS::ToString(cx, result);
JSAutoByteString bytes;
if (str)
bytes.encodeLatin1(cx, str);
JS::SetWarningReporter(cx, older);
if (!!bytes)
fprintf(stdout, "%s\n", bytes.ptr());
else
ok = false;
}
}
} while (!hitEOF && !env->IsQuitting());
fprintf(stdout, "\n");
}
// static
XPCShellEnvironment*
XPCShellEnvironment::CreateEnvironment()
{
XPCShellEnvironment* env = new XPCShellEnvironment();
if (env && !env->Init()) {
delete env;
env = nullptr;
}
return env;
}
XPCShellEnvironment::XPCShellEnvironment()
: mQuitting(false)
{
}
XPCShellEnvironment::~XPCShellEnvironment()
{
if (GetGlobalObject()) {
AutoJSAPI jsapi;
if (!jsapi.Init(GetGlobalObject())) {
return;
}
JSContext* cx = jsapi.cx();
Rooted<JSObject*> global(cx, GetGlobalObject());
{
JSAutoCompartment ac(cx, global);
JS_SetAllNonReservedSlotsToUndefined(cx, global);
}
mGlobalHolder.reset();
JS_GC(cx);
}
}
bool
XPCShellEnvironment::Init()
{
nsresult rv;
// unbuffer stdout so that output is in the correct order; note that stderr
// is unbuffered by default
setbuf(stdout, 0);
AutoSafeJSContext cx;
mGlobalHolder.init(cx);
nsCOMPtr<nsIXPConnect> xpc =
do_GetService(nsIXPConnect::GetCID());
if (!xpc) {
NS_ERROR("failed to get nsXPConnect service!");
return false;
}
nsCOMPtr<nsIPrincipal> principal;
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && securityManager) {
rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
if (NS_FAILED(rv)) {
fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
}
} else {
fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals");
}
RefPtr<BackstagePass> backstagePass;
rv = NS_NewBackstagePass(getter_AddRefs(backstagePass));
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create backstage pass!");
return false;
}
JS::CompartmentOptions options;
options.creationOptions().setZone(JS::SystemZone);
options.behaviors().setVersion(JSVERSION_LATEST);
if (xpc::SharedMemoryEnabled())
options.creationOptions().setSharedMemoryAndAtomicsEnabled(true);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx,
static_cast<nsIGlobalObject *>(backstagePass),
principal, 0,
options,
getter_AddRefs(holder));
if (NS_FAILED(rv)) {
NS_ERROR("InitClassesWithNewWrappedGlobal failed!");
return false;
}
JS::Rooted<JSObject*> globalObj(cx, holder->GetJSObject());
if (!globalObj) {
NS_ERROR("Failed to get global JSObject!");
return false;
}
JSAutoCompartment ac(cx, globalObj);
backstagePass->SetGlobalObject(globalObj);
JS::Rooted<Value> privateVal(cx, PrivateValue(this));
if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment",
privateVal,
JSPROP_READONLY | JSPROP_PERMANENT,
JS_STUBGETTER, JS_STUBSETTER) ||
!JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
!JS_DefineProfilingFunctions(cx, globalObj))
{
NS_ERROR("JS_DefineFunctions failed!");
return false;
}
mGlobalHolder = globalObj;
FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r");
if (runtimeScriptFile) {
fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename);
ProcessFile(cx, kDefaultRuntimeScriptFilename,
runtimeScriptFile, false);
fclose(runtimeScriptFile);
}
return true;
}
bool
XPCShellEnvironment::EvaluateString(const nsString& aString,
nsString* aResult)
{
AutoEntryScript aes(GetGlobalObject(),
"ipc XPCShellEnvironment::EvaluateString");
JSContext* cx = aes.cx();
JS::CompileOptions options(cx);
options.setFileAndLine("typein", 0);
JS::Rooted<JSScript*> script(cx);
if (!JS_CompileUCScript(cx, aString.get(), aString.Length(), options,
&script))
{
return false;
}
if (aResult) {
aResult->Truncate();
}
JS::Rooted<JS::Value> result(cx);
bool ok = JS_ExecuteScript(cx, script, &result);
if (ok && !result.isUndefined()) {
JS::WarningReporter old = JS::SetWarningReporter(cx, nullptr);
JSString* str = JS::ToString(cx, result);
nsAutoJSString autoStr;
if (str)
autoStr.init(cx, str);
JS::SetWarningReporter(cx, old);
if (!autoStr.IsEmpty() && aResult) {
aResult->Assign(autoStr);
}
}
return true;
}

View file

@ -0,0 +1,64 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _IPC_TESTSHELL_XPCSHELLENVIRONMENT_H_
#define _IPC_TESTSHELL_XPCSHELLENVIRONMENT_H_
#include "base/basictypes.h"
#include <string>
#include <stdio.h>
#include "nsCOMPtr.h"
#include "nsDebug.h"
#include "nsString.h"
#include "nsJSPrincipals.h"
#include "nsContentUtils.h"
#include "js/RootingAPI.h"
#include "js/TypeDecls.h"
struct JSPrincipals;
namespace mozilla {
namespace ipc {
class XPCShellEnvironment
{
public:
static XPCShellEnvironment* CreateEnvironment();
~XPCShellEnvironment();
void ProcessFile(JSContext *cx, const char *filename, FILE *file, bool forceTTY);
bool EvaluateString(const nsString& aString,
nsString* aResult = nullptr);
JSPrincipals* GetPrincipal() {
return nsJSPrincipals::get(nsContentUtils::GetSystemPrincipal());
}
JSObject* GetGlobalObject() {
return mGlobalHolder;
}
void SetIsQuitting() {
mQuitting = true;
}
bool IsQuitting() {
return mQuitting;
}
protected:
XPCShellEnvironment();
bool Init();
private:
JS::PersistentRooted<JSObject *> mGlobalHolder;
bool mQuitting;
};
} /* namespace ipc */
} /* namespace mozilla */
#endif /* _IPC_TESTSHELL_XPCSHELLENVIRONMENT_H_ */

37
ipc/testshell/moz.build Normal file
View file

@ -0,0 +1,37 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.ipc += [
'TestShellChild.h',
'TestShellParent.h',
'XPCShellEnvironment.h',
]
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell.ini']
SOURCES += [
'TestShellChild.cpp',
'TestShellParent.cpp',
'XPCShellEnvironment.cpp',
]
IPDL_SOURCES = [
'PTestShell.ipdl',
'PTestShellCommand.ipdl',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
# For xpcshell error messages and nsAutoJSString
LOCAL_INCLUDES += [
'/dom/base',
'/js/xpconnect/src',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']

View file

@ -0,0 +1,28 @@
function callback(result) {
do_check_eq(result, Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT);
do_test_finished();
}
function run_test() {
do_test_pending();
do_check_eq(runtime.processType, Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
sendCommand("load('test_ipcshell_child.js');");
sendCommand("runtime.processType;", callback);
[ [ "C", "D" ], [ "D", "C" ], [ "\u010C", "D" ], [ "D", "\u010C" ] ].forEach(
function (pair) {
do_test_pending();
var cmp = pair[0].localeCompare(pair[1]);
sendCommand(
"'"+ pair[0] +"'.localeCompare('"+ pair[1] +"');",
function (result) {
do_check_eq(cmp, result);
do_test_finished();
});
})
}
load('test_ipcshell_child.js');

View file

@ -0,0 +1,9 @@
var Cc = Components.classes;
var Ci = Components.interfaces;
const runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
if (typeof(run_test) == "undefined") {
run_test = function() {
do_check_eq(runtime.processType, Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
} }

View file

@ -0,0 +1,9 @@
[DEFAULT]
head =
tail =
skip-if = toolkit == 'android'
[test_ipcshell.js]
# Bug 676963: test fails consistently on Android
fail-if = os == "android"
[test_ipcshell_child.js]