2013-06-12 11:00:09 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
2012-05-21 15:12:37 +04:00
|
|
|
* 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/. */
|
1999-09-07 10:18:08 +04:00
|
|
|
|
2011-12-16 23:42:07 +04:00
|
|
|
#include "mozilla/Attributes.h"
|
|
|
|
|
2013-01-15 16:22:03 +04:00
|
|
|
#include <cstdarg>
|
2007-05-16 03:27:40 +04:00
|
|
|
|
2015-05-19 21:15:34 +03:00
|
|
|
#include "mozilla/Logging.h"
|
2014-02-12 01:01:29 +04:00
|
|
|
#ifdef ANDROID
|
|
|
|
#include <android/log.h>
|
|
|
|
#endif
|
|
|
|
#ifdef XP_WIN
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
2000-05-26 08:56:23 +04:00
|
|
|
|
2013-03-17 07:36:37 +04:00
|
|
|
#include "jsapi.h"
|
2000-05-26 08:56:23 +04:00
|
|
|
#include "nsCOMPtr.h"
|
2005-12-13 20:55:43 +03:00
|
|
|
#include "nsAutoPtr.h"
|
1999-09-07 10:18:08 +04:00
|
|
|
#include "nsIComponentManager.h"
|
2010-06-10 22:11:11 +04:00
|
|
|
#include "mozilla/Module.h"
|
2012-06-06 06:08:30 +04:00
|
|
|
#include "nsIFile.h"
|
1999-09-07 10:18:08 +04:00
|
|
|
#include "mozJSComponentLoader.h"
|
2011-07-10 07:21:16 +04:00
|
|
|
#include "mozJSLoaderUtils.h"
|
1999-09-07 10:18:08 +04:00
|
|
|
#include "nsIXPConnect.h"
|
2000-05-16 09:09:31 +04:00
|
|
|
#include "nsIObserverService.h"
|
2000-05-26 08:56:23 +04:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2007-06-11 01:13:18 +04:00
|
|
|
#include "nsIFileURL.h"
|
2010-06-15 23:38:46 +04:00
|
|
|
#include "nsIJARURI.h"
|
2002-01-08 04:31:25 +03:00
|
|
|
#include "nsNetUtil.h"
|
2007-05-16 03:27:40 +04:00
|
|
|
#include "jsprf.h"
|
2012-03-09 13:48:50 +04:00
|
|
|
#include "nsJSPrincipals.h"
|
2014-07-10 19:36:33 +04:00
|
|
|
#include "nsJSUtils.h"
|
2010-11-16 04:39:28 +03:00
|
|
|
#include "xpcprivate.h"
|
2011-12-28 12:13:38 +04:00
|
|
|
#include "xpcpublic.h"
|
2012-07-23 18:47:18 +04:00
|
|
|
#include "nsContentUtils.h"
|
2015-03-06 19:34:08 +03:00
|
|
|
#include "nsXULAppAPI.h"
|
2017-06-20 23:11:06 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2012-07-23 18:47:18 +04:00
|
|
|
#include "WrapperFactory.h"
|
2000-03-31 15:19:51 +04:00
|
|
|
|
2017-05-20 22:20:35 +03:00
|
|
|
#include "AutoMemMap.h"
|
|
|
|
#include "ScriptPreloader-inl.h"
|
|
|
|
|
2014-06-21 22:55:15 +04:00
|
|
|
#include "mozilla/AddonPathService.h"
|
2010-08-12 23:37:52 +04:00
|
|
|
#include "mozilla/scache/StartupCache.h"
|
|
|
|
#include "mozilla/scache/StartupCacheUtils.h"
|
2014-05-13 01:37:46 +04:00
|
|
|
#include "mozilla/MacroForEach.h"
|
2012-06-07 06:52:14 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2017-05-04 08:06:33 +03:00
|
|
|
#include "mozilla/ScriptPreloader.h"
|
2014-08-08 16:30:54 +04:00
|
|
|
#include "mozilla/dom/ScriptSettings.h"
|
2015-12-06 17:20:16 +03:00
|
|
|
#include "mozilla/UniquePtrExtensions.h"
|
2016-08-23 07:09:32 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2010-08-12 23:37:52 +04:00
|
|
|
|
2011-11-08 21:10:51 +04:00
|
|
|
using namespace mozilla;
|
2011-07-20 11:39:09 +04:00
|
|
|
using namespace mozilla::scache;
|
2017-05-20 22:20:35 +03:00
|
|
|
using namespace mozilla::loader;
|
2012-07-23 18:47:18 +04:00
|
|
|
using namespace xpc;
|
2013-04-23 19:48:05 +04:00
|
|
|
using namespace JS;
|
2011-07-20 11:39:09 +04:00
|
|
|
|
2005-10-20 20:39:24 +04:00
|
|
|
static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1";
|
2017-09-10 00:59:00 +03:00
|
|
|
|
|
|
|
#define JS_CACHE_PREFIX(aType) "jsloader/" aType
|
1999-11-10 03:34:26 +03:00
|
|
|
|
2005-10-20 20:39:24 +04:00
|
|
|
/**
|
|
|
|
* Buffer sizes for serialization and deserialization of scripts.
|
2008-04-02 10:41:23 +04:00
|
|
|
* FIXME: bug #411579 (tune this macro!) Last updated: Jan 2008
|
2005-10-20 20:39:24 +04:00
|
|
|
*/
|
|
|
|
#define XPC_SERIALIZATION_BUFFER_SIZE (64 * 1024)
|
2008-04-02 10:41:23 +04:00
|
|
|
#define XPC_DESERIALIZATION_BUFFER_SIZE (12 * 8192)
|
2005-10-20 20:39:24 +04:00
|
|
|
|
2016-05-26 02:31:13 +03:00
|
|
|
// MOZ_LOG=JSComponentLoader:5
|
2016-01-28 21:35:00 +03:00
|
|
|
static LazyLogModule gJSCLLog("JSComponentLoader");
|
2005-10-20 20:39:24 +04:00
|
|
|
|
2015-06-04 01:25:57 +03:00
|
|
|
#define LOG(args) MOZ_LOG(gJSCLLog, mozilla::LogLevel::Debug, args)
|
2005-10-20 20:39:24 +04:00
|
|
|
|
2007-05-16 03:27:40 +04:00
|
|
|
// Components.utils.import error messages
|
|
|
|
#define ERROR_SCOPE_OBJ "%s - Second argument must be an object."
|
|
|
|
#define ERROR_NOT_PRESENT "%s - EXPORTED_SYMBOLS is not present."
|
|
|
|
#define ERROR_NOT_AN_ARRAY "%s - EXPORTED_SYMBOLS is not an array."
|
|
|
|
#define ERROR_GETTING_ARRAY_LENGTH "%s - Error getting array length of EXPORTED_SYMBOLS."
|
|
|
|
#define ERROR_ARRAY_ELEMENT "%s - EXPORTED_SYMBOLS[%d] is not a string."
|
|
|
|
#define ERROR_GETTING_SYMBOL "%s - Could not get symbol '%s'."
|
|
|
|
#define ERROR_SETTING_SYMBOL "%s - Could not set symbol '%s' on target object."
|
|
|
|
|
2013-08-02 11:41:57 +04:00
|
|
|
static bool
|
2015-03-29 01:22:11 +03:00
|
|
|
Dump(JSContext* cx, unsigned argc, Value* vp)
|
1999-09-07 10:18:08 +04:00
|
|
|
{
|
2017-08-02 21:56:33 +03:00
|
|
|
if (!nsContentUtils::DOMWindowDumpEnabled()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-11-16 16:31:36 +04:00
|
|
|
CallArgs args = CallArgsFromVp(argc, vp);
|
|
|
|
|
|
|
|
if (args.length() == 0)
|
2011-11-26 14:05:59 +04:00
|
|
|
return true;
|
2010-03-24 00:08:18 +03:00
|
|
|
|
2014-07-10 19:36:33 +04:00
|
|
|
RootedString str(cx, JS::ToString(cx, args[0]));
|
1999-09-07 10:18:08 +04:00
|
|
|
if (!str)
|
2011-11-26 14:05:59 +04:00
|
|
|
return false;
|
1999-09-07 10:18:08 +04:00
|
|
|
|
2014-07-10 19:36:33 +04:00
|
|
|
JSAutoByteString utf8str;
|
|
|
|
if (!utf8str.encodeUtf8(cx, str))
|
2011-11-26 14:05:59 +04:00
|
|
|
return false;
|
2010-12-03 11:24:17 +03:00
|
|
|
|
2014-02-12 01:01:29 +04:00
|
|
|
#ifdef ANDROID
|
2014-07-10 19:36:33 +04:00
|
|
|
__android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", utf8str.ptr());
|
2014-02-12 01:01:29 +04:00
|
|
|
#endif
|
|
|
|
#ifdef XP_WIN
|
|
|
|
if (IsDebuggerPresent()) {
|
2014-07-10 19:36:33 +04:00
|
|
|
nsAutoJSString wstr;
|
|
|
|
if (!wstr.init(cx, str))
|
|
|
|
return false;
|
|
|
|
OutputDebugStringW(wstr.get());
|
2014-02-12 01:01:29 +04:00
|
|
|
}
|
|
|
|
#endif
|
2014-07-10 19:36:33 +04:00
|
|
|
fputs(utf8str.ptr(), stdout);
|
2014-02-12 01:01:29 +04:00
|
|
|
fflush(stdout);
|
2011-11-26 14:05:59 +04:00
|
|
|
return true;
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2013-08-02 11:41:57 +04:00
|
|
|
static bool
|
2015-07-18 22:45:35 +03:00
|
|
|
Debug(JSContext* cx, unsigned argc, Value* vp)
|
2000-05-26 08:56:23 +04:00
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
2010-08-16 23:35:04 +04:00
|
|
|
return Dump(cx, argc, vp);
|
2000-05-26 08:56:23 +04:00
|
|
|
#else
|
2011-11-26 14:05:59 +04:00
|
|
|
return true;
|
2000-05-26 08:56:23 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-04-23 01:15:49 +04:00
|
|
|
static const JSFunctionSpec gGlobalFun[] = {
|
2017-08-25 18:04:12 +03:00
|
|
|
JS_FN("dump", Dump, 1,0),
|
|
|
|
JS_FN("debug", Debug, 1,0),
|
|
|
|
JS_FN("atob", Atob, 1,0),
|
|
|
|
JS_FN("btoa", Btoa, 1,0),
|
2012-08-08 09:26:19 +04:00
|
|
|
JS_FS_END
|
1999-09-07 10:18:08 +04:00
|
|
|
};
|
|
|
|
|
2013-04-29 22:16:19 +04:00
|
|
|
class MOZ_STACK_CLASS JSCLContextHelper
|
2005-10-20 20:39:24 +04:00
|
|
|
{
|
|
|
|
public:
|
2014-09-01 05:06:35 +04:00
|
|
|
explicit JSCLContextHelper(JSContext* aCx);
|
2011-05-13 19:56:26 +04:00
|
|
|
~JSCLContextHelper();
|
2009-02-18 07:11:09 +03:00
|
|
|
|
2017-03-04 01:10:11 +03:00
|
|
|
void reportErrorAfterPop(UniqueChars&& buf);
|
2005-10-20 20:39:24 +04:00
|
|
|
|
|
|
|
private:
|
|
|
|
JSContext* mContext;
|
2017-03-04 01:10:11 +03:00
|
|
|
UniqueChars mBuf;
|
2010-03-12 09:50:10 +03:00
|
|
|
|
|
|
|
// prevent copying and assignment
|
2015-03-29 01:22:11 +03:00
|
|
|
JSCLContextHelper(const JSCLContextHelper&) = delete;
|
|
|
|
const JSCLContextHelper& operator=(const JSCLContextHelper&) = delete;
|
2005-10-20 20:39:24 +04:00
|
|
|
};
|
|
|
|
|
2009-02-18 07:11:09 +03:00
|
|
|
static nsresult
|
2016-10-11 21:44:40 +03:00
|
|
|
MOZ_FORMAT_PRINTF(2, 3)
|
2016-09-30 06:34:44 +03:00
|
|
|
ReportOnCallerUTF8(JSContext* callerContext,
|
|
|
|
const char* format, ...) {
|
2011-12-18 14:09:16 +04:00
|
|
|
if (!callerContext) {
|
2009-02-18 07:11:09 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2011-10-14 21:52:47 +04:00
|
|
|
|
2009-02-18 07:11:09 +03:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
|
|
|
|
2017-03-04 01:10:11 +03:00
|
|
|
UniqueChars buf = JS_vsmprintf(format, ap);
|
2011-05-13 19:56:26 +04:00
|
|
|
if (!buf) {
|
2016-10-10 14:31:16 +03:00
|
|
|
va_end(ap);
|
2011-05-13 19:56:26 +04:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
2017-03-04 01:10:11 +03:00
|
|
|
JS_ReportErrorUTF8(callerContext, "%s", buf.get());
|
2011-05-13 19:56:26 +04:00
|
|
|
|
2016-10-10 14:31:16 +03:00
|
|
|
va_end(ap);
|
2011-05-13 19:56:26 +04:00
|
|
|
return NS_OK;
|
2009-02-18 07:11:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2016-10-11 21:44:40 +03:00
|
|
|
MOZ_FORMAT_PRINTF(2, 3)
|
2016-09-30 06:34:44 +03:00
|
|
|
ReportOnCallerUTF8(JSCLContextHelper& helper,
|
|
|
|
const char* format, ...)
|
2009-02-18 07:11:09 +03:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
|
|
|
|
2017-03-04 01:10:11 +03:00
|
|
|
UniqueChars buf = JS_vsmprintf(format, ap);
|
2011-05-13 19:56:26 +04:00
|
|
|
if (!buf) {
|
2016-10-10 14:31:16 +03:00
|
|
|
va_end(ap);
|
2011-05-13 19:56:26 +04:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2009-02-18 07:11:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-04 01:10:11 +03:00
|
|
|
helper.reportErrorAfterPop(Move(buf));
|
2016-10-10 14:31:16 +03:00
|
|
|
va_end(ap);
|
2011-05-13 19:56:26 +04:00
|
|
|
return NS_OK;
|
2009-02-18 07:11:09 +03:00
|
|
|
}
|
|
|
|
|
1999-09-26 00:07:20 +04:00
|
|
|
mozJSComponentLoader::mozJSComponentLoader()
|
2014-08-07 22:36:31 +04:00
|
|
|
: mModules(16),
|
2014-08-06 17:31:21 +04:00
|
|
|
mImports(16),
|
|
|
|
mInProgressImports(16),
|
2017-07-25 06:32:42 +03:00
|
|
|
mLocations(16),
|
2017-07-19 00:47:27 +03:00
|
|
|
mInitialized(false),
|
|
|
|
mShareLoaderGlobal(false),
|
|
|
|
mLoaderGlobal(dom::RootingCx())
|
1999-09-07 10:18:08 +04:00
|
|
|
{
|
2013-08-14 11:00:34 +04:00
|
|
|
MOZ_ASSERT(!sSelf, "mozJSComponentLoader should be a singleton");
|
2005-12-13 20:55:43 +03:00
|
|
|
|
|
|
|
sSelf = this;
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2014-05-13 01:37:46 +04:00
|
|
|
#define ENSURE_DEP(name) { nsresult rv = Ensure##name(); NS_ENSURE_SUCCESS(rv, rv); }
|
|
|
|
#define ENSURE_DEPS(...) MOZ_FOR_EACH(ENSURE_DEP, (), (__VA_ARGS__));
|
|
|
|
#define BEGIN_ENSURE(self, ...) { \
|
|
|
|
if (m##self) \
|
|
|
|
return NS_OK; \
|
|
|
|
ENSURE_DEPS(__VA_ARGS__); \
|
|
|
|
}
|
|
|
|
|
|
|
|
class MOZ_STACK_CLASS ComponentLoaderInfo {
|
|
|
|
public:
|
2014-09-01 05:06:35 +04:00
|
|
|
explicit ComponentLoaderInfo(const nsACString& aLocation) : mLocation(aLocation) {}
|
2014-05-13 01:37:46 +04:00
|
|
|
|
|
|
|
nsIIOService* IOService() { MOZ_ASSERT(mIOService); return mIOService; }
|
|
|
|
nsresult EnsureIOService() {
|
|
|
|
if (mIOService)
|
|
|
|
return NS_OK;
|
|
|
|
nsresult rv;
|
|
|
|
mIOService = do_GetIOService(&rv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIURI* URI() { MOZ_ASSERT(mURI); return mURI; }
|
|
|
|
nsresult EnsureURI() {
|
|
|
|
BEGIN_ENSURE(URI, IOService);
|
|
|
|
return mIOService->NewURI(mLocation, nullptr, nullptr, getter_AddRefs(mURI));
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIChannel* ScriptChannel() { MOZ_ASSERT(mScriptChannel); return mScriptChannel; }
|
|
|
|
nsresult EnsureScriptChannel() {
|
|
|
|
BEGIN_ENSURE(ScriptChannel, IOService, URI);
|
2015-02-17 21:09:23 +03:00
|
|
|
return NS_NewChannel(getter_AddRefs(mScriptChannel),
|
|
|
|
mURI,
|
|
|
|
nsContentUtils::GetSystemPrincipal(),
|
2016-03-08 01:19:50 +03:00
|
|
|
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
2015-02-17 21:09:23 +03:00
|
|
|
nsIContentPolicy::TYPE_SCRIPT,
|
|
|
|
nullptr, // aLoadGroup
|
|
|
|
nullptr, // aCallbacks
|
|
|
|
nsIRequest::LOAD_NORMAL,
|
|
|
|
mIOService);
|
2014-05-13 01:37:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsIURI* ResolvedURI() { MOZ_ASSERT(mResolvedURI); return mResolvedURI; }
|
|
|
|
nsresult EnsureResolvedURI() {
|
2017-07-22 01:42:38 +03:00
|
|
|
BEGIN_ENSURE(ResolvedURI, URI);
|
|
|
|
return ResolveURI(mURI, getter_AddRefs(mResolvedURI));
|
2014-05-13 01:37:46 +04:00
|
|
|
}
|
|
|
|
|
2017-07-25 06:32:42 +03:00
|
|
|
const nsACString& Key() { return mLocation; }
|
2014-05-13 01:37:46 +04:00
|
|
|
nsresult EnsureKey() {
|
2017-07-25 06:32:42 +03:00
|
|
|
return NS_OK;
|
2014-05-13 01:37:46 +04:00
|
|
|
}
|
|
|
|
|
2016-09-30 06:34:44 +03:00
|
|
|
MOZ_MUST_USE nsresult GetLocation(nsCString& aLocation) {
|
|
|
|
nsresult rv = EnsureURI();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return mURI->GetSpec(aLocation);
|
|
|
|
}
|
|
|
|
|
2014-05-13 01:37:46 +04:00
|
|
|
private:
|
|
|
|
const nsACString& mLocation;
|
|
|
|
nsCOMPtr<nsIIOService> mIOService;
|
|
|
|
nsCOMPtr<nsIURI> mURI;
|
|
|
|
nsCOMPtr<nsIChannel> mScriptChannel;
|
|
|
|
nsCOMPtr<nsIURI> mResolvedURI;
|
|
|
|
};
|
|
|
|
|
|
|
|
#undef BEGIN_ENSURE
|
|
|
|
#undef ENSURE_DEPS
|
|
|
|
#undef ENSURE_DEP
|
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
mozJSComponentLoader::~mozJSComponentLoader()
|
1999-09-07 10:18:08 +04:00
|
|
|
{
|
2005-12-13 20:55:43 +03:00
|
|
|
if (mInitialized) {
|
|
|
|
NS_ERROR("'xpcom-shutdown-loaders' was not fired before cleaning up mozJSComponentLoader");
|
|
|
|
UnloadModules();
|
1999-11-10 03:34:26 +03:00
|
|
|
}
|
1999-09-07 10:18:08 +04:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
sSelf = nullptr;
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
mozJSComponentLoader*
|
|
|
|
mozJSComponentLoader::sSelf;
|
1999-09-08 00:30:25 +04:00
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(mozJSComponentLoader,
|
|
|
|
mozilla::ModuleLoader,
|
|
|
|
xpcIJSModuleLoader,
|
|
|
|
nsIObserver)
|
2011-10-14 21:52:47 +04:00
|
|
|
|
1999-09-24 06:52:46 +04:00
|
|
|
nsresult
|
1999-09-24 05:37:44 +04:00
|
|
|
mozJSComponentLoader::ReallyInit()
|
|
|
|
{
|
2017-08-26 05:36:44 +03:00
|
|
|
MOZ_ASSERT(!mInitialized);
|
|
|
|
|
2017-09-10 00:59:45 +03:00
|
|
|
const char* shareGlobal = PR_GetEnv("MOZ_LOADER_SHARE_GLOBAL");
|
|
|
|
if (shareGlobal && *shareGlobal) {
|
|
|
|
nsDependentCString val(shareGlobal);
|
|
|
|
mShareLoaderGlobal = !(val.EqualsLiteral("0") ||
|
|
|
|
val.LowerCaseEqualsLiteral("no") ||
|
|
|
|
val.LowerCaseEqualsLiteral("false") ||
|
|
|
|
val.LowerCaseEqualsLiteral("off"));
|
|
|
|
} else {
|
|
|
|
mShareLoaderGlobal = Preferences::GetBool("jsloader.shareGlobal");
|
|
|
|
}
|
2017-07-19 00:47:27 +03:00
|
|
|
|
1999-09-24 05:37:44 +04:00
|
|
|
nsresult rv;
|
2005-10-20 20:39:24 +04:00
|
|
|
nsCOMPtr<nsIObserverService> obsSvc =
|
|
|
|
do_GetService(kObserverServiceContractID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
rv = obsSvc->AddObserver(this, "xpcom-shutdown-loaders", false);
|
2005-12-13 20:55:43 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mInitialized = true;
|
1999-11-10 03:34:26 +03:00
|
|
|
|
1999-09-07 10:18:08 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-10-07 00:00:29 +03:00
|
|
|
// For terrible compatibility reasons, we need to consider both the global
|
2016-08-25 11:28:47 +03:00
|
|
|
// lexical environment and the global of modules when searching for exported
|
2015-10-07 00:00:29 +03:00
|
|
|
// symbols.
|
|
|
|
static JSObject*
|
|
|
|
ResolveModuleObjectProperty(JSContext* aCx, HandleObject aModObj, const char* name)
|
|
|
|
{
|
2016-08-25 11:28:47 +03:00
|
|
|
if (JS_HasExtensibleLexicalEnvironment(aModObj)) {
|
|
|
|
RootedObject lexical(aCx, JS_ExtensibleLexicalEnvironment(aModObj));
|
2015-10-07 00:00:29 +03:00
|
|
|
bool found;
|
|
|
|
if (!JS_HasOwnProperty(aCx, lexical, name, &found)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
if (found) {
|
|
|
|
return lexical;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return aModObj;
|
|
|
|
}
|
|
|
|
|
2010-06-10 22:11:11 +04:00
|
|
|
const mozilla::Module*
|
2015-03-29 01:22:11 +03:00
|
|
|
mozJSComponentLoader::LoadModule(FileLocation& aFile)
|
2010-06-15 23:38:46 +04:00
|
|
|
{
|
2016-07-08 03:08:25 +03:00
|
|
|
if (!NS_IsMainThread()) {
|
|
|
|
MOZ_ASSERT(false, "Don't use JS components off the main thread");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2012-06-06 06:08:30 +04:00
|
|
|
nsCOMPtr<nsIFile> file = aFile.GetBaseFile();
|
2010-06-15 23:38:46 +04:00
|
|
|
|
2011-11-08 21:10:51 +04:00
|
|
|
nsCString spec;
|
|
|
|
aFile.GetURIString(spec);
|
2014-05-13 01:37:46 +04:00
|
|
|
ComponentLoaderInfo info(spec);
|
|
|
|
nsresult rv = info.EnsureURI();
|
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
2010-06-15 23:38:46 +04:00
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
if (!mInitialized) {
|
|
|
|
rv = ReallyInit();
|
2005-12-03 18:27:17 +03:00
|
|
|
if (NS_FAILED(rv))
|
2013-10-11 00:35:53 +04:00
|
|
|
return nullptr;
|
2005-10-20 20:39:24 +04:00
|
|
|
}
|
1999-09-27 06:22:25 +04:00
|
|
|
|
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
This patch makes the following changes to the macros.
- Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside
classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was
mostly misused.
- Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is
universally available now anyway.
- Combines the first two string literal arguments of PROFILER_LABEL and
PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for
them to be separate, and it forced a '::' in the label, which isn't always
appropriate. Also, the meaning of the "name_space" argument was interpreted
in an interesting variety of ways.
- Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make
it clearer they construct RAII objects rather than just being function calls.
(I myself have screwed up the scoping because of this in the past.)
- Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so
the caller doesn't need to. This makes a *lot* more of the uses fit onto a
single line.
The patch also makes the following changes to the macro uses (beyond those
required by the changes described above).
- Fixes a bunch of labels that had gotten out of sync with the name of the
class and/or function that encloses them.
- Removes a useless PROFILER_LABEL use within a trivial scope in
EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving
any useful purpose. It also serves as extra evidence that the AUTO_ prefix is
a good idea.
- Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is
done within them, instead of at their callsites, because that's a more
standard way of doing things.
--HG--
extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
|
|
|
AUTO_PROFILER_LABEL_DYNAMIC("mozJSComponentLoader::LoadModule", OTHER,
|
|
|
|
spec.get());
|
2017-06-20 23:11:06 +03:00
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
ModuleEntry* mod;
|
2011-11-08 21:10:51 +04:00
|
|
|
if (mModules.Get(spec, &mod))
|
2017-02-19 16:27:57 +03:00
|
|
|
return mod;
|
2005-12-03 18:27:17 +03:00
|
|
|
|
2014-08-07 22:28:16 +04:00
|
|
|
dom::AutoJSAPI jsapi;
|
|
|
|
jsapi.Init();
|
|
|
|
JSContext* cx = jsapi.cx();
|
2005-12-03 18:27:17 +03:00
|
|
|
|
2016-08-11 15:39:22 +03:00
|
|
|
nsAutoPtr<ModuleEntry> entry(new ModuleEntry(RootingContext::get(cx)));
|
2014-08-07 22:28:16 +04:00
|
|
|
RootedValue dummy(cx);
|
2014-05-13 01:37:46 +04:00
|
|
|
rv = ObjectForLocation(info, file, &entry->obj, &entry->thisObjectKey,
|
2013-04-23 19:48:05 +04:00
|
|
|
&entry->location, false, &dummy);
|
2005-10-20 20:39:24 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
2013-10-11 00:35:53 +04:00
|
|
|
return nullptr;
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
nsCOMPtr<nsIComponentManager> cm;
|
|
|
|
rv = NS_GetComponentManager(getter_AddRefs(cm));
|
|
|
|
if (NS_FAILED(rv))
|
2013-10-11 00:35:53 +04:00
|
|
|
return nullptr;
|
2000-08-24 11:50:27 +04:00
|
|
|
|
2012-10-31 20:13:28 +04:00
|
|
|
JSAutoCompartment ac(cx, entry->obj);
|
2014-01-31 13:55:20 +04:00
|
|
|
RootedObject entryObj(cx, entry->obj);
|
2000-10-05 08:15:43 +04:00
|
|
|
|
2015-10-07 00:00:29 +03:00
|
|
|
RootedObject NSGetFactoryHolder(cx, ResolveModuleObjectProperty(cx, entryObj, "NSGetFactory"));
|
2013-04-23 19:48:05 +04:00
|
|
|
RootedValue NSGetFactory_val(cx);
|
2015-10-07 00:00:29 +03:00
|
|
|
if (!NSGetFactoryHolder ||
|
|
|
|
!JS_GetProperty(cx, NSGetFactoryHolder, "NSGetFactory", &NSGetFactory_val) ||
|
|
|
|
NSGetFactory_val.isUndefined())
|
|
|
|
{
|
2013-10-11 00:35:53 +04:00
|
|
|
return nullptr;
|
2004-10-12 07:37:20 +04:00
|
|
|
}
|
|
|
|
|
2010-06-10 22:11:11 +04:00
|
|
|
if (JS_TypeOfValue(cx, NSGetFactory_val) != JSTYPE_FUNCTION) {
|
2016-09-30 06:34:43 +03:00
|
|
|
/*
|
|
|
|
* spec's encoding is ASCII unless it's zip file, otherwise it's
|
|
|
|
* random encoding. Latin1 variant is safe for random encoding.
|
|
|
|
*/
|
|
|
|
JS_ReportErrorLatin1(cx, "%s has NSGetFactory property that is not a function",
|
|
|
|
spec.get());
|
2013-10-11 00:35:53 +04:00
|
|
|
return nullptr;
|
2004-10-12 07:37:20 +04:00
|
|
|
}
|
2011-10-14 21:52:47 +04:00
|
|
|
|
2013-04-23 19:48:05 +04:00
|
|
|
RootedObject jsGetFactoryObj(cx);
|
2013-09-20 13:22:59 +04:00
|
|
|
if (!JS_ValueToObject(cx, NSGetFactory_val, &jsGetFactoryObj) ||
|
2010-06-10 22:11:11 +04:00
|
|
|
!jsGetFactoryObj) {
|
1999-09-08 00:30:25 +04:00
|
|
|
/* XXX report error properly */
|
2013-10-11 00:35:53 +04:00
|
|
|
return nullptr;
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2017-05-10 00:08:15 +03:00
|
|
|
rv = nsXPConnect::XPConnect()->WrapJS(cx, jsGetFactoryObj,
|
|
|
|
NS_GET_IID(xpcIJSGetFactory),
|
|
|
|
getter_AddRefs(entry->getfactoryobj));
|
2005-10-20 20:39:24 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
1999-09-08 00:30:25 +04:00
|
|
|
/* XXX report error properly */
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
|
|
|
#ifdef DEBUG
|
1999-09-07 10:18:08 +04:00
|
|
|
fprintf(stderr, "mJCL: couldn't get nsIModule from jsval\n");
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 21:42:36 +04:00
|
|
|
#endif
|
2013-10-11 00:35:53 +04:00
|
|
|
return nullptr;
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2017-09-13 22:19:53 +03:00
|
|
|
#if defined(NIGHTLY_BUILD) || defined(DEBUG)
|
|
|
|
if (Preferences::GetBool("browser.startup.record", false)) {
|
|
|
|
entry->importStack = xpc_PrintJSStack(cx, false, false, false).get();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
// Cache this module for later
|
2012-05-18 21:30:49 +04:00
|
|
|
mModules.Put(spec, entry);
|
2000-09-21 08:30:32 +04:00
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
// The hash owns the ModuleEntry now, forget about it
|
2010-06-12 00:13:26 +04:00
|
|
|
return entry.forget();
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2017-05-17 00:27:50 +03:00
|
|
|
void
|
2012-11-13 23:13:27 +04:00
|
|
|
mozJSComponentLoader::FindTargetObject(JSContext* aCx,
|
2013-10-14 15:42:16 +04:00
|
|
|
MutableHandleObject aTargetObject)
|
2012-11-13 23:13:27 +04:00
|
|
|
{
|
2017-07-19 00:47:27 +03:00
|
|
|
aTargetObject.set(js::GetJSMEnvironmentOfScriptedCaller(aCx));
|
|
|
|
|
2017-09-10 21:23:32 +03:00
|
|
|
// The above could fail if the scripted caller is not a component/JSM (it
|
|
|
|
// could be a DOM scope, for instance).
|
|
|
|
//
|
|
|
|
// If the target object was not in the JSM shared global, return the global
|
|
|
|
// instead. This is needed when calling the subscript loader within a frame
|
|
|
|
// script, since it the FrameScript NSVO will have been found.
|
|
|
|
if (!aTargetObject ||
|
|
|
|
!IsLoaderGlobal(js::GetGlobalForObjectCrossCompartment(aTargetObject))) {
|
2017-07-19 00:47:27 +03:00
|
|
|
aTargetObject.set(CurrentGlobalOrNull(aCx));
|
|
|
|
}
|
2012-11-13 23:13:27 +04:00
|
|
|
}
|
|
|
|
|
2015-07-31 07:19:57 +03:00
|
|
|
// This requires that the keys be strings and the values be pointers.
|
|
|
|
template <class Key, class Data, class UserData>
|
|
|
|
static size_t
|
|
|
|
SizeOfTableExcludingThis(const nsBaseHashtable<Key, Data, UserData>& aTable,
|
|
|
|
MallocSizeOf aMallocSizeOf)
|
2013-12-06 01:54:30 +04:00
|
|
|
{
|
2015-07-31 07:19:57 +03:00
|
|
|
size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
|
|
|
for (auto iter = aTable.ConstIter(); !iter.Done(); iter.Next()) {
|
|
|
|
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
|
|
|
n += iter.Data()->SizeOfIncludingThis(aMallocSizeOf);
|
|
|
|
}
|
|
|
|
return n;
|
2013-12-06 01:54:30 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
mozJSComponentLoader::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
|
|
|
|
{
|
2015-07-31 07:19:57 +03:00
|
|
|
size_t n = aMallocSizeOf(this);
|
|
|
|
n += SizeOfTableExcludingThis(mModules, aMallocSizeOf);
|
|
|
|
n += SizeOfTableExcludingThis(mImports, aMallocSizeOf);
|
2017-07-25 06:32:42 +03:00
|
|
|
n += mLocations.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
2015-07-31 07:19:57 +03:00
|
|
|
n += SizeOfTableExcludingThis(mInProgressImports, aMallocSizeOf);
|
|
|
|
return n;
|
2013-12-06 01:54:30 +04:00
|
|
|
}
|
|
|
|
|
2017-05-16 01:46:13 +03:00
|
|
|
void
|
|
|
|
mozJSComponentLoader::CreateLoaderGlobal(JSContext* aCx,
|
2017-08-26 05:36:44 +03:00
|
|
|
const nsACString& aLocation,
|
2017-05-16 01:46:13 +03:00
|
|
|
JSAddonId* aAddonID,
|
|
|
|
MutableHandleObject aGlobal)
|
|
|
|
{
|
|
|
|
RefPtr<BackstagePass> backstagePass;
|
|
|
|
nsresult rv = NS_NewBackstagePass(getter_AddRefs(backstagePass));
|
|
|
|
NS_ENSURE_SUCCESS_VOID(rv);
|
|
|
|
|
|
|
|
CompartmentOptions options;
|
|
|
|
|
|
|
|
options.creationOptions()
|
|
|
|
.setSystemZone()
|
|
|
|
.setAddonId(aAddonID);
|
|
|
|
|
2017-08-14 14:45:14 +03:00
|
|
|
options.behaviors().setVersion(JSVERSION_DEFAULT);
|
2017-05-16 01:46:13 +03:00
|
|
|
|
|
|
|
if (xpc::SharedMemoryEnabled())
|
|
|
|
options.creationOptions().setSharedMemoryAndAtomicsEnabled(true);
|
|
|
|
|
|
|
|
// Defer firing OnNewGlobalObject until after the __URI__ property has
|
|
|
|
// been defined so the JS debugger can tell what module the global is
|
|
|
|
// for
|
2017-09-19 02:35:39 +03:00
|
|
|
RootedObject global(aCx);
|
|
|
|
rv = xpc::InitClassesWithNewWrappedGlobal(aCx,
|
|
|
|
static_cast<nsIGlobalObject*>(backstagePass),
|
|
|
|
nsContentUtils::GetSystemPrincipal(),
|
2017-09-19 23:12:50 +03:00
|
|
|
xpc::DONT_FIRE_ONNEWGLOBALHOOK,
|
2017-09-19 02:35:39 +03:00
|
|
|
options,
|
|
|
|
&global);
|
2017-05-16 01:46:13 +03:00
|
|
|
NS_ENSURE_SUCCESS_VOID(rv);
|
|
|
|
|
|
|
|
NS_ENSURE_TRUE_VOID(global);
|
|
|
|
|
|
|
|
backstagePass->SetGlobalObject(global);
|
|
|
|
|
|
|
|
JSAutoCompartment ac(aCx, global);
|
|
|
|
if (!JS_DefineFunctions(aCx, global, gGlobalFun) ||
|
|
|
|
!JS_DefineProfilingFunctions(aCx, global)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-12 20:45:52 +03:00
|
|
|
// Set the location information for the new global, so that tools like
|
|
|
|
// about:memory may use that information
|
|
|
|
xpc::SetLocationForGlobal(global, aLocation);
|
|
|
|
|
2017-05-16 01:46:13 +03:00
|
|
|
aGlobal.set(global);
|
|
|
|
}
|
|
|
|
|
2017-07-19 00:47:27 +03:00
|
|
|
bool
|
|
|
|
mozJSComponentLoader::ReuseGlobal(bool aIsAddon, nsIURI* aURI)
|
|
|
|
{
|
|
|
|
if (aIsAddon || !mShareLoaderGlobal)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
nsCString spec;
|
|
|
|
NS_ENSURE_SUCCESS(aURI->GetSpec(spec), false);
|
|
|
|
|
|
|
|
// The loader calls Object.freeze on global properties, which
|
|
|
|
// causes problems if the global is shared with other code.
|
|
|
|
if (spec.EqualsASCII("resource://gre/modules/commonjs/toolkit/loader.js")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Various tests call addDebuggerToGlobal on the result of
|
|
|
|
// importing this JSM, which would be annoying to fix.
|
|
|
|
if (spec.EqualsASCII("resource://gre/modules/jsdebugger.jsm")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Some SpecialPowers jsms call Cu.forcePermissiveCOWs(),
|
|
|
|
// which sets a per-compartment flag that disables certain
|
|
|
|
// security wrappers, so don't use the shared global for them
|
|
|
|
// to avoid breaking tests.
|
|
|
|
if (FindInReadable(NS_LITERAL_CSTRING("chrome://specialpowers/"), spec)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-26 05:36:44 +03:00
|
|
|
JSObject*
|
|
|
|
mozJSComponentLoader::GetSharedGlobal(JSContext* aCx)
|
|
|
|
{
|
|
|
|
if (!mLoaderGlobal) {
|
|
|
|
JS::RootedObject globalObj(aCx);
|
|
|
|
CreateLoaderGlobal(aCx, NS_LITERAL_CSTRING("shared JSM global"),
|
|
|
|
nullptr, &globalObj);
|
|
|
|
|
|
|
|
// If we fail to create a module global this early, we're not going to
|
|
|
|
// get very far, so just bail out now.
|
|
|
|
MOZ_RELEASE_ASSERT(globalObj);
|
|
|
|
mLoaderGlobal = globalObj;
|
|
|
|
|
|
|
|
// AutoEntryScript required to invoke debugger hook, which is a
|
|
|
|
// Gecko-specific concept at present.
|
|
|
|
dom::AutoEntryScript aes(globalObj,
|
|
|
|
"component loader report global");
|
|
|
|
JS_FireOnNewGlobalObject(aes.cx(), globalObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mLoaderGlobal;
|
|
|
|
}
|
|
|
|
|
2012-10-31 20:13:28 +04:00
|
|
|
JSObject*
|
2014-08-07 22:16:47 +04:00
|
|
|
mozJSComponentLoader::PrepareObjectForLocation(JSContext* aCx,
|
2015-03-29 01:22:11 +03:00
|
|
|
nsIFile* aComponentFile,
|
|
|
|
nsIURI* aURI,
|
2017-07-19 00:47:27 +03:00
|
|
|
bool* aReuseGlobal,
|
2015-03-29 01:22:11 +03:00
|
|
|
bool* aRealFile)
|
1999-09-07 10:18:08 +04:00
|
|
|
{
|
2017-06-12 20:45:52 +03:00
|
|
|
nsAutoCString nativePath;
|
|
|
|
NS_ENSURE_SUCCESS(aURI->GetSpec(nativePath), nullptr);
|
|
|
|
|
2017-07-19 00:47:27 +03:00
|
|
|
JSAddonId* addonId = MapURIToAddonID(aURI);
|
|
|
|
bool reuseGlobal = ReuseGlobal(!!addonId, aURI);
|
|
|
|
|
|
|
|
*aReuseGlobal = reuseGlobal;
|
|
|
|
|
|
|
|
bool createdNewGlobal = false;
|
2017-05-16 01:46:13 +03:00
|
|
|
RootedObject globalObj(aCx);
|
2017-08-26 05:36:44 +03:00
|
|
|
if (reuseGlobal) {
|
|
|
|
globalObj = GetSharedGlobal(aCx);
|
|
|
|
} else if (!globalObj) {
|
|
|
|
CreateLoaderGlobal(aCx, nativePath, addonId, &globalObj);
|
2017-07-19 00:47:27 +03:00
|
|
|
createdNewGlobal = true;
|
|
|
|
}
|
2012-10-30 23:28:11 +04:00
|
|
|
|
2017-05-18 23:18:53 +03:00
|
|
|
// |thisObj| is the object we set properties on for a particular .jsm.
|
2017-05-16 01:46:13 +03:00
|
|
|
RootedObject thisObj(aCx, globalObj);
|
2017-05-18 23:18:53 +03:00
|
|
|
NS_ENSURE_TRUE(thisObj, nullptr);
|
2012-10-30 23:28:11 +04:00
|
|
|
|
2017-05-18 23:18:53 +03:00
|
|
|
JSAutoCompartment ac(aCx, thisObj);
|
2012-10-31 20:13:28 +04:00
|
|
|
|
2017-07-19 00:47:27 +03:00
|
|
|
if (reuseGlobal) {
|
|
|
|
thisObj = js::NewJSMEnvironment(aCx);
|
|
|
|
NS_ENSURE_TRUE(thisObj, nullptr);
|
|
|
|
}
|
|
|
|
|
2012-10-31 20:13:28 +04:00
|
|
|
*aRealFile = false;
|
|
|
|
|
2010-06-15 23:38:46 +04:00
|
|
|
// need to be extra careful checking for URIs pointing to files
|
|
|
|
// EnsureFile may not always get called, especially on resource URIs
|
|
|
|
// so we need to call GetFile to make sure this is a valid file
|
2017-05-16 01:46:13 +03:00
|
|
|
nsresult rv = NS_OK;
|
2010-06-15 23:38:46 +04:00
|
|
|
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
|
|
|
|
nsCOMPtr<nsIFile> testFile;
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
fileURL->GetFile(getter_AddRefs(testFile));
|
|
|
|
}
|
2011-10-14 21:52:47 +04:00
|
|
|
|
2010-06-15 23:38:46 +04:00
|
|
|
if (testFile) {
|
2012-10-31 20:13:28 +04:00
|
|
|
*aRealFile = true;
|
2005-10-20 20:39:24 +04:00
|
|
|
|
2015-07-04 04:29:00 +03:00
|
|
|
if (XRE_IsParentProcess()) {
|
2015-07-01 21:17:17 +03:00
|
|
|
RootedObject locationObj(aCx);
|
2015-07-04 04:29:00 +03:00
|
|
|
|
2017-05-18 23:18:53 +03:00
|
|
|
rv = nsXPConnect::XPConnect()->WrapNative(aCx, thisObj, aComponentFile,
|
2017-05-10 00:08:15 +03:00
|
|
|
NS_GET_IID(nsIFile),
|
|
|
|
locationObj.address());
|
2015-03-06 19:34:08 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
NS_ENSURE_TRUE(locationObj, nullptr);
|
2010-06-15 23:38:46 +04:00
|
|
|
|
2017-05-18 23:18:53 +03:00
|
|
|
if (!JS_DefineProperty(aCx, thisObj, "__LOCATION__", locationObj, 0))
|
2015-03-06 19:34:08 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
2005-10-20 20:39:24 +04:00
|
|
|
}
|
|
|
|
|
2011-04-14 02:10:13 +04:00
|
|
|
// Expose the URI from which the script was imported through a special
|
|
|
|
// variable that we insert into the JSM.
|
2014-01-22 06:11:17 +04:00
|
|
|
RootedString exposedUri(aCx, JS_NewStringCopyN(aCx, nativePath.get(), nativePath.Length()));
|
|
|
|
NS_ENSURE_TRUE(exposedUri, nullptr);
|
|
|
|
|
2017-05-18 23:18:53 +03:00
|
|
|
if (!JS_DefineProperty(aCx, thisObj, "__URI__", exposedUri, 0))
|
2012-10-31 20:13:28 +04:00
|
|
|
return nullptr;
|
2012-10-30 23:28:11 +04:00
|
|
|
|
2017-07-19 00:47:27 +03:00
|
|
|
if (createdNewGlobal) {
|
2014-08-08 16:30:54 +04:00
|
|
|
// AutoEntryScript required to invoke debugger hook, which is a
|
|
|
|
// Gecko-specific concept at present.
|
2017-05-16 01:46:13 +03:00
|
|
|
dom::AutoEntryScript aes(globalObj,
|
2015-04-09 04:23:48 +03:00
|
|
|
"component loader report global");
|
2017-05-16 01:46:13 +03:00
|
|
|
JS_FireOnNewGlobalObject(aes.cx(), globalObj);
|
2014-03-26 03:33:06 +04:00
|
|
|
}
|
|
|
|
|
2017-05-18 23:18:53 +03:00
|
|
|
return thisObj;
|
2012-10-31 20:13:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2015-03-29 01:22:11 +03:00
|
|
|
mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo& aInfo,
|
|
|
|
nsIFile* aComponentFile,
|
2014-04-16 12:47:53 +04:00
|
|
|
MutableHandleObject aObject,
|
|
|
|
MutableHandleScript aTableScript,
|
2015-03-29 01:22:11 +03:00
|
|
|
char** aLocation,
|
2013-04-23 19:48:05 +04:00
|
|
|
bool aPropagateExceptions,
|
2013-10-14 15:42:16 +04:00
|
|
|
MutableHandleValue aException)
|
2012-10-31 20:13:28 +04:00
|
|
|
{
|
2014-08-08 16:30:54 +04:00
|
|
|
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
|
2012-10-31 20:13:28 +04:00
|
|
|
|
2014-08-08 16:30:54 +04:00
|
|
|
dom::AutoJSAPI jsapi;
|
|
|
|
jsapi.Init();
|
|
|
|
JSContext* cx = jsapi.cx();
|
2012-10-31 20:13:28 +04:00
|
|
|
|
|
|
|
bool realFile = false;
|
2014-05-13 01:37:46 +04:00
|
|
|
nsresult rv = aInfo.EnsureURI();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2017-07-19 00:47:27 +03:00
|
|
|
bool reuseGlobal = false;
|
2014-05-13 01:37:46 +04:00
|
|
|
RootedObject obj(cx, PrepareObjectForLocation(cx, aComponentFile, aInfo.URI(),
|
2017-07-19 00:47:27 +03:00
|
|
|
&reuseGlobal, &realFile));
|
2012-10-31 20:13:28 +04:00
|
|
|
NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
|
2017-07-19 00:47:27 +03:00
|
|
|
MOZ_ASSERT(JS_IsGlobalObject(obj) == !reuseGlobal);
|
2012-10-31 20:13:28 +04:00
|
|
|
|
|
|
|
JSAutoCompartment ac(cx, obj);
|
2000-01-25 00:28:28 +03:00
|
|
|
|
2013-04-26 21:50:18 +04:00
|
|
|
RootedScript script(cx);
|
2012-10-31 20:13:28 +04:00
|
|
|
|
|
|
|
nsAutoCString nativePath;
|
2014-05-13 01:37:46 +04:00
|
|
|
rv = aInfo.URI()->GetSpec(nativePath);
|
2012-10-31 20:13:28 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2010-08-12 23:37:52 +04:00
|
|
|
|
2005-10-20 20:39:24 +04:00
|
|
|
// Before compiling the script, first check to see if we have it in
|
2010-08-12 23:37:52 +04:00
|
|
|
// the startupcache. Note: as a rule, startupcache errors are not fatal
|
2005-10-20 20:39:24 +04:00
|
|
|
// to loading the script, since we can always slow-load.
|
2011-10-14 21:52:47 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool writeToCache = false;
|
2010-08-12 23:37:52 +04:00
|
|
|
StartupCache* cache = StartupCache::GetSingleton();
|
2005-10-20 20:39:24 +04:00
|
|
|
|
2017-07-22 01:42:38 +03:00
|
|
|
aInfo.EnsureResolvedURI();
|
|
|
|
|
2017-09-10 00:59:00 +03:00
|
|
|
nsAutoCString cachePath(reuseGlobal ? JS_CACHE_PREFIX("non-syntactic")
|
|
|
|
: JS_CACHE_PREFIX("global"));
|
2017-07-22 01:42:38 +03:00
|
|
|
rv = PathifyURI(aInfo.ResolvedURI(), cachePath);
|
2011-07-10 07:21:16 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2017-05-16 00:33:21 +03:00
|
|
|
script = ScriptPreloader::GetSingleton().GetCachedScript(cx, cachePath);
|
|
|
|
if (!script && cache) {
|
2017-07-07 21:14:04 +03:00
|
|
|
ReadCachedScript(cache, cachePath, cx, &script);
|
2017-05-01 07:53:49 +03:00
|
|
|
}
|
2012-10-31 20:13:28 +04:00
|
|
|
|
2017-05-16 01:00:46 +03:00
|
|
|
if (script) {
|
2017-05-01 07:53:49 +03:00
|
|
|
LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
|
|
|
|
} else if (cache) {
|
|
|
|
// This is ok, it just means the script is not yet in the
|
|
|
|
// cache. Could mean that the cache was corrupted and got removed,
|
|
|
|
// but either way we're going to write this out.
|
|
|
|
writeToCache = true;
|
2017-05-16 00:33:21 +03:00
|
|
|
// ReadCachedScript may have set a pending exception.
|
2017-05-01 07:53:49 +03:00
|
|
|
JS_ClearPendingException(cx);
|
2005-10-20 20:39:24 +04:00
|
|
|
}
|
2005-03-24 21:24:09 +03:00
|
|
|
|
2017-05-16 01:00:46 +03:00
|
|
|
if (!script) {
|
2010-08-12 23:37:52 +04:00
|
|
|
// The script wasn't in the cache , so compile it now.
|
2005-10-20 20:39:24 +04:00
|
|
|
LOG(("Slow loading %s\n", nativePath.get()));
|
2005-10-04 03:34:58 +04:00
|
|
|
|
2017-05-16 00:33:21 +03:00
|
|
|
// Use lazy source if we're using the startup cache. Non-lazy source +
|
|
|
|
// startup cache regresses installer size (due to source code stored in
|
|
|
|
// XDR encoded modules in omni.ja). Also, XDR decoding is relatively
|
|
|
|
// fast. When we're not using the startup cache, we want to use non-lazy
|
|
|
|
// source code so that we can use lazy parsing.
|
|
|
|
// See bug 1303754.
|
2013-10-14 15:42:16 +04:00
|
|
|
CompileOptions options(cx);
|
2017-05-16 00:33:21 +03:00
|
|
|
options.setNoScriptRval(true)
|
2017-08-14 14:45:14 +03:00
|
|
|
.setVersion(JSVERSION_DEFAULT)
|
2017-08-28 21:39:06 +03:00
|
|
|
.maybeMakeStrictMode(true)
|
2016-09-23 10:50:47 +03:00
|
|
|
.setFileAndLine(nativePath.get(), 1)
|
2017-07-19 21:57:18 +03:00
|
|
|
.setSourceIsLazy(cache || ScriptPreloader::GetSingleton().Active());
|
2008-08-04 21:03:34 +04:00
|
|
|
|
2010-06-15 23:38:46 +04:00
|
|
|
if (realFile) {
|
2017-05-20 22:20:35 +03:00
|
|
|
AutoMemMap map;
|
|
|
|
MOZ_TRY(map.init(aComponentFile));
|
2005-10-04 03:34:58 +04:00
|
|
|
|
2017-05-16 00:33:21 +03:00
|
|
|
// Note: exceptions will get handled further down;
|
|
|
|
// don't early return for them here.
|
2017-05-20 22:20:35 +03:00
|
|
|
auto buf = map.get<char>();
|
2017-07-19 00:47:27 +03:00
|
|
|
if (reuseGlobal)
|
|
|
|
CompileForNonSyntacticScope(cx, options, buf.get(), map.size(), &script);
|
|
|
|
else
|
|
|
|
Compile(cx, options, buf.get(), map.size(), &script);
|
2010-06-15 23:38:46 +04:00
|
|
|
} else {
|
2014-05-13 01:37:46 +04:00
|
|
|
rv = aInfo.EnsureScriptChannel();
|
2010-06-15 23:38:46 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsCOMPtr<nsIInputStream> scriptStream;
|
2016-06-10 15:32:09 +03:00
|
|
|
rv = NS_MaybeOpenChannelUsingOpen2(aInfo.ScriptChannel(),
|
|
|
|
getter_AddRefs(scriptStream));
|
2010-06-15 23:38:46 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2008-08-04 21:03:34 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t len64;
|
|
|
|
uint32_t bytesRead;
|
2010-06-15 23:38:46 +04:00
|
|
|
|
2012-08-11 06:44:11 +04:00
|
|
|
rv = scriptStream->Available(&len64);
|
2010-06-15 23:38:46 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2012-09-28 10:57:33 +04:00
|
|
|
NS_ENSURE_TRUE(len64 < UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
|
2012-08-11 06:44:11 +04:00
|
|
|
if (!len64)
|
2010-06-15 23:38:46 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t len = (uint32_t)len64;
|
2010-06-15 23:38:46 +04:00
|
|
|
|
|
|
|
/* malloc an internal buf the size of the file */
|
2015-12-06 17:20:16 +03:00
|
|
|
auto buf = MakeUniqueFallible<char[]>(len + 1);
|
2010-06-15 23:38:46 +04:00
|
|
|
if (!buf)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
/* read the file in one swoop */
|
2015-12-06 17:20:16 +03:00
|
|
|
rv = scriptStream->Read(buf.get(), len, &bytesRead);
|
2010-06-15 23:38:46 +04:00
|
|
|
if (bytesRead != len)
|
|
|
|
return NS_BASE_STREAM_OSERROR;
|
|
|
|
|
|
|
|
buf[len] = '\0';
|
|
|
|
|
2017-07-19 00:47:27 +03:00
|
|
|
if (reuseGlobal)
|
|
|
|
CompileForNonSyntacticScope(cx, options, buf.get(), bytesRead, &script);
|
|
|
|
else
|
|
|
|
Compile(cx, options, buf.get(), bytesRead, &script);
|
2010-06-15 23:38:46 +04:00
|
|
|
}
|
2008-08-04 21:03:34 +04:00
|
|
|
// Propagate the exception, if one exists. Also, don't leave the stale
|
|
|
|
// exception on this context.
|
2017-05-16 01:00:46 +03:00
|
|
|
if (!script && aPropagateExceptions && jsapi.HasException()) {
|
2016-07-14 06:18:11 +03:00
|
|
|
if (!jsapi.StealException(aException))
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2008-08-04 21:03:34 +04:00
|
|
|
}
|
2005-10-20 20:39:24 +04:00
|
|
|
}
|
2000-01-25 00:28:28 +03:00
|
|
|
|
2017-05-16 01:00:46 +03:00
|
|
|
if (!script) {
|
2005-10-20 20:39:24 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
1999-09-08 00:30:25 +04:00
|
|
|
|
2017-05-16 01:00:46 +03:00
|
|
|
ScriptPreloader::GetSingleton().NoteScript(nativePath, cachePath, script);
|
2017-05-04 08:06:33 +03:00
|
|
|
|
2010-08-12 23:37:52 +04:00
|
|
|
if (writeToCache) {
|
2011-10-14 21:52:47 +04:00
|
|
|
// We successfully compiled the script, so cache it.
|
2017-07-07 21:27:53 +03:00
|
|
|
rv = WriteCachedScript(cache, cachePath, cx, script);
|
2005-10-20 20:39:24 +04:00
|
|
|
|
|
|
|
// Don't treat failure to write as fatal, since we might be working
|
2010-08-12 23:37:52 +04:00
|
|
|
// with a read-only cache.
|
2005-10-20 20:39:24 +04:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2010-08-12 23:37:52 +04:00
|
|
|
LOG(("Successfully wrote to cache\n"));
|
2005-10-20 20:39:24 +04:00
|
|
|
} else {
|
2010-08-12 23:37:52 +04:00
|
|
|
LOG(("Failed to write to cache\n"));
|
2003-03-23 10:22:18 +03:00
|
|
|
}
|
1999-09-08 00:30:25 +04:00
|
|
|
}
|
2005-10-20 20:39:24 +04:00
|
|
|
|
2012-10-31 20:13:28 +04:00
|
|
|
// Assign aObject here so that it's available to recursive imports.
|
2007-06-20 10:29:49 +04:00
|
|
|
// See bug 384168.
|
2014-04-16 12:47:53 +04:00
|
|
|
aObject.set(obj);
|
2007-06-20 10:29:49 +04:00
|
|
|
|
2017-05-16 01:00:46 +03:00
|
|
|
aTableScript.set(script);
|
2013-12-20 00:49:52 +04:00
|
|
|
|
2013-10-14 15:42:16 +04:00
|
|
|
|
2016-03-09 23:28:33 +03:00
|
|
|
{ // Scope for AutoEntryScript
|
|
|
|
|
2017-05-16 01:00:46 +03:00
|
|
|
// We're going to run script via JS_ExecuteScript, so we need an
|
|
|
|
// AutoEntryScript. This is Gecko-specific and not in any spec.
|
2016-03-09 23:28:33 +03:00
|
|
|
dom::AutoEntryScript aes(CurrentGlobalOrNull(cx),
|
2015-04-09 04:23:48 +03:00
|
|
|
"component loader load module");
|
2016-03-09 23:28:33 +03:00
|
|
|
JSContext* aescx = aes.cx();
|
2017-07-19 00:47:27 +03:00
|
|
|
|
|
|
|
bool executeOk = false;
|
|
|
|
if (JS_IsGlobalObject(obj)) {
|
|
|
|
JS::RootedValue rval(cx);
|
|
|
|
executeOk = JS::CloneAndExecuteScript(aescx, script, &rval);
|
|
|
|
} else {
|
|
|
|
executeOk = js::ExecuteInJSMEnvironment(aescx, script, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!executeOk) {
|
2016-03-09 23:28:33 +03:00
|
|
|
if (aPropagateExceptions && aes.HasException()) {
|
2016-07-14 06:18:11 +03:00
|
|
|
// Ignore return value because we're returning an error code
|
|
|
|
// anyway.
|
|
|
|
Unused << aes.StealException(aException);
|
2016-03-09 23:28:33 +03:00
|
|
|
}
|
|
|
|
aObject.set(nullptr);
|
|
|
|
aTableScript.set(nullptr);
|
|
|
|
return NS_ERROR_FAILURE;
|
2011-12-28 20:55:11 +04:00
|
|
|
}
|
2003-03-23 10:22:18 +03:00
|
|
|
}
|
1999-09-08 00:30:25 +04:00
|
|
|
|
2005-10-20 20:39:24 +04:00
|
|
|
/* Freed when we remove from the table. */
|
2010-06-15 23:38:46 +04:00
|
|
|
*aLocation = ToNewCString(nativePath);
|
2007-06-20 10:29:49 +04:00
|
|
|
if (!*aLocation) {
|
2014-04-16 12:47:53 +04:00
|
|
|
aObject.set(nullptr);
|
|
|
|
aTableScript.set(nullptr);
|
2005-12-13 20:55:43 +03:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2007-06-20 10:29:49 +04:00
|
|
|
}
|
2000-09-21 08:30:32 +04:00
|
|
|
|
2005-10-20 20:39:24 +04:00
|
|
|
return NS_OK;
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2005-12-13 20:55:43 +03:00
|
|
|
void
|
|
|
|
mozJSComponentLoader::UnloadModules()
|
2005-12-03 18:27:17 +03:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
mInitialized = false;
|
2005-12-03 18:27:17 +03:00
|
|
|
|
2017-07-19 00:47:27 +03:00
|
|
|
if (mLoaderGlobal) {
|
|
|
|
dom::AutoJSAPI jsapi;
|
|
|
|
jsapi.Init();
|
|
|
|
JSContext* cx = jsapi.cx();
|
|
|
|
RootedObject global(cx, mLoaderGlobal);
|
|
|
|
JSAutoCompartment ac(cx, global);
|
|
|
|
MOZ_ASSERT(JS_HasExtensibleLexicalEnvironment(global));
|
|
|
|
JS_SetAllNonReservedSlotsToUndefined(cx, JS_ExtensibleLexicalEnvironment(global));
|
|
|
|
JS_SetAllNonReservedSlotsToUndefined(cx, global);
|
|
|
|
mLoaderGlobal = nullptr;
|
|
|
|
}
|
|
|
|
|
2007-06-20 10:29:49 +04:00
|
|
|
mInProgressImports.Clear();
|
2007-05-16 03:27:40 +04:00
|
|
|
mImports.Clear();
|
2017-07-25 06:32:42 +03:00
|
|
|
mLocations.Clear();
|
2010-06-12 00:13:26 +04:00
|
|
|
|
2015-11-23 05:52:40 +03:00
|
|
|
for (auto iter = mModules.Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
iter.Data()->Clear();
|
|
|
|
iter.Remove();
|
|
|
|
}
|
1999-09-07 10:18:08 +04:00
|
|
|
}
|
|
|
|
|
2017-07-18 03:11:06 +03:00
|
|
|
nsresult
|
2011-12-18 14:09:16 +04:00
|
|
|
mozJSComponentLoader::Import(const nsACString& registryLocation,
|
2014-01-09 21:39:36 +04:00
|
|
|
HandleValue targetValArg,
|
2015-03-29 01:22:11 +03:00
|
|
|
JSContext* cx,
|
2012-08-22 19:56:38 +04:00
|
|
|
uint8_t optionalArgc,
|
2014-01-09 21:39:36 +04:00
|
|
|
MutableHandleValue retval)
|
2007-05-16 03:27:40 +04:00
|
|
|
{
|
2012-10-26 03:10:53 +04:00
|
|
|
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
2013-04-23 19:48:05 +04:00
|
|
|
|
|
|
|
RootedValue targetVal(cx, targetValArg);
|
|
|
|
RootedObject targetObject(cx, nullptr);
|
2011-12-18 14:09:16 +04:00
|
|
|
if (optionalArgc) {
|
2007-05-16 03:27:40 +04:00
|
|
|
// The caller passed in the optional second argument. Get it.
|
2012-07-23 18:47:18 +04:00
|
|
|
if (targetVal.isObject()) {
|
|
|
|
// If we're passing in something like a content DOM window, chances
|
|
|
|
// are the caller expects the properties to end up on the object
|
|
|
|
// proper and not on the Xray holder. This is dubious, but can be used
|
|
|
|
// during testing. Given that dumb callers can already leak JSMs into
|
|
|
|
// content by passing a raw content JS object (where Xrays aren't
|
|
|
|
// possible), we aim for consistency here. Waive xray.
|
|
|
|
if (WrapperFactory::IsXrayWrapper(&targetVal.toObject()) &&
|
2013-10-26 20:19:05 +04:00
|
|
|
!WrapperFactory::WaiveXrayAndWrap(cx, &targetVal))
|
2012-07-23 18:47:18 +04:00
|
|
|
{
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
targetObject = &targetVal.toObject();
|
|
|
|
} else if (!targetVal.isNull()) {
|
|
|
|
// If targetVal isNull(), we actually want to leave targetObject null.
|
|
|
|
// Not doing so breaks |make package|.
|
2016-09-30 06:34:44 +03:00
|
|
|
return ReportOnCallerUTF8(cx, ERROR_SCOPE_OBJ,
|
|
|
|
PromiseFlatCString(registryLocation).get());
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
|
|
|
} else {
|
2017-05-17 00:27:50 +03:00
|
|
|
FindTargetObject(cx, &targetObject);
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
2011-10-14 21:52:47 +04:00
|
|
|
|
2012-08-22 05:42:53 +04:00
|
|
|
Maybe<JSAutoCompartment> ac;
|
|
|
|
if (targetObject) {
|
2014-08-14 02:42:00 +04:00
|
|
|
ac.emplace(cx, targetObject);
|
2010-10-11 02:42:04 +04:00
|
|
|
}
|
|
|
|
|
2013-04-23 19:48:05 +04:00
|
|
|
RootedObject global(cx);
|
|
|
|
nsresult rv = ImportInto(registryLocation, targetObject, cx, &global);
|
2010-10-11 02:42:04 +04:00
|
|
|
|
2013-04-23 19:48:05 +04:00
|
|
|
if (global) {
|
2013-10-16 04:02:23 +04:00
|
|
|
if (!JS_WrapObject(cx, &global)) {
|
2013-04-23 19:48:05 +04:00
|
|
|
NS_ERROR("can't wrap return value");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2007-05-16 03:27:40 +04:00
|
|
|
|
2014-01-09 21:39:36 +04:00
|
|
|
retval.setObject(*global);
|
2013-04-23 19:48:05 +04:00
|
|
|
}
|
2007-05-16 03:27:40 +04:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2017-07-18 03:11:06 +03:00
|
|
|
nsresult
|
2014-05-15 22:22:45 +04:00
|
|
|
mozJSComponentLoader::IsModuleLoaded(const nsACString& aLocation,
|
2015-03-29 01:22:11 +03:00
|
|
|
bool* retval)
|
2014-05-15 22:22:45 +04:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (!mInitialized) {
|
|
|
|
rv = ReallyInit();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
ComponentLoaderInfo info(aLocation);
|
|
|
|
rv = info.EnsureKey();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
*retval = !!mImports.Get(info.Key());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-06-01 00:00:43 +03:00
|
|
|
NS_IMETHODIMP mozJSComponentLoader::LoadedModules(uint32_t* length,
|
|
|
|
char*** aModules)
|
|
|
|
{
|
|
|
|
char** modules = new char*[mImports.Count()];
|
|
|
|
*length = mImports.Count();
|
|
|
|
*aModules = modules;
|
|
|
|
|
|
|
|
for (auto iter = mImports.Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
*modules = NS_strdup(iter.Data()->location);
|
|
|
|
modules++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP mozJSComponentLoader::LoadedComponents(uint32_t* length,
|
|
|
|
char*** aComponents)
|
|
|
|
{
|
|
|
|
char** comp = new char*[mModules.Count()];
|
|
|
|
*length = mModules.Count();
|
|
|
|
*aComponents = comp;
|
|
|
|
|
|
|
|
for (auto iter = mModules.Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
*comp = NS_strdup(iter.Data()->location);
|
|
|
|
comp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-09-13 22:19:53 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
mozJSComponentLoader::GetModuleImportStack(const nsACString& aLocation,
|
|
|
|
nsACString& retval)
|
|
|
|
{
|
|
|
|
#if defined(NIGHTLY_BUILD) || defined(DEBUG)
|
|
|
|
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
|
|
|
MOZ_ASSERT(mInitialized);
|
|
|
|
|
|
|
|
ComponentLoaderInfo info(aLocation);
|
|
|
|
nsresult rv = info.EnsureKey();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
ModuleEntry* mod;
|
|
|
|
if (!mImports.Get(info.Key(), &mod))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
retval = mod->importStack;
|
|
|
|
return NS_OK;
|
|
|
|
#else
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
mozJSComponentLoader::GetComponentLoadStack(const nsACString& aLocation,
|
|
|
|
nsACString& retval)
|
|
|
|
{
|
|
|
|
#if defined(NIGHTLY_BUILD) || defined(DEBUG)
|
|
|
|
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
|
|
|
MOZ_ASSERT(mInitialized);
|
|
|
|
|
|
|
|
ComponentLoaderInfo info(aLocation);
|
|
|
|
nsresult rv = info.EnsureURI();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
ModuleEntry* mod;
|
|
|
|
if (!mModules.Get(info.Key(), &mod))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
retval = mod->importStack;
|
|
|
|
return NS_OK;
|
|
|
|
#else
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-10-07 00:00:29 +03:00
|
|
|
static JSObject*
|
|
|
|
ResolveModuleObjectPropertyById(JSContext* aCx, HandleObject aModObj, HandleId id)
|
|
|
|
{
|
2016-08-25 11:28:47 +03:00
|
|
|
if (JS_HasExtensibleLexicalEnvironment(aModObj)) {
|
|
|
|
RootedObject lexical(aCx, JS_ExtensibleLexicalEnvironment(aModObj));
|
2015-10-07 00:00:29 +03:00
|
|
|
bool found;
|
|
|
|
if (!JS_HasOwnPropertyById(aCx, lexical, id, &found)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
if (found) {
|
|
|
|
return lexical;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return aModObj;
|
|
|
|
}
|
|
|
|
|
2011-12-18 14:09:16 +04:00
|
|
|
nsresult
|
2015-03-29 01:22:11 +03:00
|
|
|
mozJSComponentLoader::ImportInto(const nsACString& aLocation,
|
2013-10-14 15:42:16 +04:00
|
|
|
HandleObject targetObj,
|
2015-03-29 01:22:11 +03:00
|
|
|
JSContext* callercx,
|
2013-10-14 15:42:16 +04:00
|
|
|
MutableHandleObject vp)
|
2007-05-16 03:27:40 +04:00
|
|
|
{
|
2013-04-23 19:48:05 +04:00
|
|
|
vp.set(nullptr);
|
2007-05-16 03:27:40 +04:00
|
|
|
|
2013-04-23 19:48:05 +04:00
|
|
|
nsresult rv;
|
2007-05-16 03:27:40 +04:00
|
|
|
if (!mInitialized) {
|
|
|
|
rv = ReallyInit();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2011-10-14 21:52:47 +04:00
|
|
|
|
2014-05-13 01:37:46 +04:00
|
|
|
ComponentLoaderInfo info(aLocation);
|
2007-05-16 03:27:40 +04:00
|
|
|
|
2014-05-13 01:37:46 +04:00
|
|
|
rv = info.EnsureKey();
|
2010-06-15 23:38:46 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-05-16 03:27:40 +04:00
|
|
|
|
|
|
|
ModuleEntry* mod;
|
|
|
|
nsAutoPtr<ModuleEntry> newEntry;
|
2014-05-13 01:37:46 +04:00
|
|
|
if (!mImports.Get(info.Key(), &mod) && !mInProgressImports.Get(info.Key(), &mod)) {
|
2016-08-11 15:39:22 +03:00
|
|
|
newEntry = new ModuleEntry(RootingContext::get(callercx));
|
2012-05-18 21:30:49 +04:00
|
|
|
if (!newEntry)
|
2007-05-16 03:27:40 +04:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2017-07-22 01:11:02 +03:00
|
|
|
|
|
|
|
rv = info.EnsureResolvedURI();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// get the JAR if there is one
|
|
|
|
nsCOMPtr<nsIJARURI> jarURI;
|
|
|
|
jarURI = do_QueryInterface(info.ResolvedURI(), &rv);
|
|
|
|
nsCOMPtr<nsIFileURL> baseFileURL;
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
nsCOMPtr<nsIURI> baseURI;
|
|
|
|
while (jarURI) {
|
|
|
|
jarURI->GetJARFile(getter_AddRefs(baseURI));
|
|
|
|
jarURI = do_QueryInterface(baseURI, &rv);
|
|
|
|
}
|
|
|
|
baseFileURL = do_QueryInterface(baseURI, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else {
|
|
|
|
baseFileURL = do_QueryInterface(info.ResolvedURI(), &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFile> sourceFile;
|
|
|
|
rv = baseFileURL->GetFile(getter_AddRefs(sourceFile));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2017-07-25 06:32:42 +03:00
|
|
|
rv = info.ResolvedURI()->GetSpec(newEntry->resolvedURL);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCString* existingPath;
|
|
|
|
if (mLocations.Get(newEntry->resolvedURL, &existingPath) && *existingPath != info.Key()) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
mLocations.Put(newEntry->resolvedURL, new nsCString(info.Key()));
|
2014-05-13 01:37:46 +04:00
|
|
|
mInProgressImports.Put(info.Key(), newEntry);
|
2007-06-20 10:29:49 +04:00
|
|
|
|
2014-05-13 01:37:46 +04:00
|
|
|
rv = info.EnsureURI();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2013-04-23 19:48:05 +04:00
|
|
|
RootedValue exception(callercx);
|
2017-07-22 01:11:02 +03:00
|
|
|
rv = ObjectForLocation(info, sourceFile, &newEntry->obj,
|
2013-12-20 00:49:52 +04:00
|
|
|
&newEntry->thisObjectKey,
|
2013-04-23 19:48:05 +04:00
|
|
|
&newEntry->location, true, &exception);
|
2007-06-20 10:29:49 +04:00
|
|
|
|
2014-05-13 01:37:46 +04:00
|
|
|
mInProgressImports.Remove(info.Key());
|
2007-06-20 10:29:49 +04:00
|
|
|
|
2007-05-16 03:27:40 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
2013-04-23 19:48:05 +04:00
|
|
|
if (!exception.isUndefined()) {
|
2008-08-04 21:03:34 +04:00
|
|
|
// An exception was thrown during compilation. Propagate it
|
|
|
|
// out to our caller so they can report it.
|
2013-10-26 20:19:05 +04:00
|
|
|
if (!JS_WrapValue(callercx, &exception))
|
2012-02-24 01:50:01 +04:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2013-04-23 19:48:05 +04:00
|
|
|
JS_SetPendingException(callercx, exception);
|
2008-08-04 21:03:34 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Something failed, but we don't know what it is, guess.
|
2008-08-05 05:04:19 +04:00
|
|
|
return NS_ERROR_FILE_NOT_FOUND;
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
2007-06-20 10:29:49 +04:00
|
|
|
|
2017-09-13 22:19:53 +03:00
|
|
|
#if defined(NIGHTLY_BUILD) || defined(DEBUG)
|
|
|
|
if (Preferences::GetBool("browser.startup.record", false)) {
|
|
|
|
newEntry->importStack =
|
|
|
|
xpc_PrintJSStack(callercx, false, false, false).get();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-05-16 03:27:40 +04:00
|
|
|
mod = newEntry;
|
|
|
|
}
|
|
|
|
|
2013-08-14 11:00:34 +04:00
|
|
|
MOZ_ASSERT(mod->obj, "Import table contains entry with no object");
|
2013-04-23 19:48:05 +04:00
|
|
|
vp.set(mod->obj);
|
2007-05-16 03:27:40 +04:00
|
|
|
|
|
|
|
if (targetObj) {
|
2017-05-17 01:51:14 +03:00
|
|
|
// cxhelper must be created before jsapi, so that jsapi is destroyed and
|
2014-08-08 16:52:16 +04:00
|
|
|
// pops any context it has pushed before we report to the caller context.
|
|
|
|
JSCLContextHelper cxhelper(callercx);
|
|
|
|
|
|
|
|
// Even though we are calling JS_SetPropertyById on targetObj, we want
|
|
|
|
// to ensure that we never run script here, so we use an AutoJSAPI and
|
|
|
|
// not an AutoEntryScript.
|
|
|
|
dom::AutoJSAPI jsapi;
|
|
|
|
jsapi.Init();
|
|
|
|
JSContext* cx = jsapi.cx();
|
|
|
|
JSAutoCompartment ac(cx, mod->obj);
|
|
|
|
|
|
|
|
RootedValue symbols(cx);
|
2015-10-07 00:00:29 +03:00
|
|
|
RootedObject exportedSymbolsHolder(cx, ResolveModuleObjectProperty(cx, mod->obj,
|
|
|
|
"EXPORTED_SYMBOLS"));
|
|
|
|
if (!exportedSymbolsHolder ||
|
|
|
|
!JS_GetProperty(cx, exportedSymbolsHolder,
|
2013-07-26 13:00:38 +04:00
|
|
|
"EXPORTED_SYMBOLS", &symbols)) {
|
2016-09-30 06:34:44 +03:00
|
|
|
nsCString location;
|
|
|
|
rv = info.GetLocation(location);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return ReportOnCallerUTF8(cxhelper, ERROR_NOT_PRESENT,
|
|
|
|
location.get());
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
|
|
|
|
2015-08-29 07:55:40 +03:00
|
|
|
bool isArray;
|
|
|
|
if (!JS_IsArrayObject(cx, symbols, &isArray)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
if (!isArray) {
|
2016-09-30 06:34:44 +03:00
|
|
|
nsCString location;
|
|
|
|
rv = info.GetLocation(location);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return ReportOnCallerUTF8(cxhelper, ERROR_NOT_AN_ARRAY,
|
|
|
|
location.get());
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
|
|
|
|
2014-08-08 16:52:16 +04:00
|
|
|
RootedObject symbolsObj(cx, &symbols.toObject());
|
2012-05-11 19:46:26 +04:00
|
|
|
|
2007-05-16 03:27:40 +04:00
|
|
|
// Iterate over symbols array, installing symbols on targetObj:
|
|
|
|
|
2012-03-07 03:52:55 +04:00
|
|
|
uint32_t symbolCount = 0;
|
2014-08-08 16:52:16 +04:00
|
|
|
if (!JS_GetArrayLength(cx, symbolsObj, &symbolCount)) {
|
2016-09-30 06:34:44 +03:00
|
|
|
nsCString location;
|
|
|
|
rv = info.GetLocation(location);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return ReportOnCallerUTF8(cxhelper, ERROR_GETTING_ARRAY_LENGTH,
|
|
|
|
location.get());
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
2007-06-18 19:36:16 +04:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString logBuffer;
|
2007-06-18 19:36:16 +04:00
|
|
|
#endif
|
|
|
|
|
2014-08-08 16:52:16 +04:00
|
|
|
RootedValue value(cx);
|
|
|
|
RootedId symbolId(cx);
|
2015-10-07 00:00:29 +03:00
|
|
|
RootedObject symbolHolder(cx);
|
2012-03-07 03:52:55 +04:00
|
|
|
for (uint32_t i = 0; i < symbolCount; ++i) {
|
2014-08-08 16:52:16 +04:00
|
|
|
if (!JS_GetElement(cx, symbolsObj, i, &value) ||
|
2013-04-23 19:48:05 +04:00
|
|
|
!value.isString() ||
|
2014-08-08 16:52:16 +04:00
|
|
|
!JS_ValueToId(cx, value, &symbolId)) {
|
2016-09-30 06:34:44 +03:00
|
|
|
nsCString location;
|
|
|
|
rv = info.GetLocation(location);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return ReportOnCallerUTF8(cxhelper, ERROR_ARRAY_ELEMENT,
|
|
|
|
location.get(), i);
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
|
|
|
|
2015-10-07 00:00:29 +03:00
|
|
|
symbolHolder = ResolveModuleObjectPropertyById(cx, mod->obj, symbolId);
|
|
|
|
if (!symbolHolder ||
|
|
|
|
!JS_GetPropertyById(cx, symbolHolder, symbolId, &value)) {
|
2016-09-30 06:34:44 +03:00
|
|
|
JSAutoByteString bytes;
|
|
|
|
RootedString symbolStr(cx, JSID_TO_STRING(symbolId));
|
|
|
|
if (!bytes.encodeUtf8(cx, symbolStr))
|
2010-11-11 23:40:29 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-09-30 06:34:44 +03:00
|
|
|
nsCString location;
|
|
|
|
rv = info.GetLocation(location);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return ReportOnCallerUTF8(cxhelper, ERROR_GETTING_SYMBOL,
|
|
|
|
location.get(), bytes.ptr());
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
|
|
|
|
2014-08-08 16:52:16 +04:00
|
|
|
JSAutoCompartment target_ac(cx, targetObj);
|
2010-09-29 21:00:52 +04:00
|
|
|
|
2017-05-17 01:51:14 +03:00
|
|
|
JS_MarkCrossZoneId(cx, symbolId);
|
2017-01-30 16:31:47 +03:00
|
|
|
|
2014-08-08 16:52:16 +04:00
|
|
|
if (!JS_WrapValue(cx, &value) ||
|
|
|
|
!JS_SetPropertyById(cx, targetObj, symbolId, value)) {
|
2016-09-30 06:34:44 +03:00
|
|
|
JSAutoByteString bytes;
|
|
|
|
RootedString symbolStr(cx, JSID_TO_STRING(symbolId));
|
|
|
|
if (!bytes.encodeUtf8(cx, symbolStr))
|
2010-11-11 23:40:29 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-09-30 06:34:44 +03:00
|
|
|
nsCString location;
|
|
|
|
rv = info.GetLocation(location);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return ReportOnCallerUTF8(cxhelper, ERROR_SETTING_SYMBOL,
|
|
|
|
location.get(), bytes.ptr());
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (i == 0) {
|
2007-06-18 19:36:16 +04:00
|
|
|
logBuffer.AssignLiteral("Installing symbols [ ");
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
2014-08-08 16:52:16 +04:00
|
|
|
JSAutoByteString bytes(cx, JSID_TO_STRING(symbolId));
|
2010-11-11 23:40:29 +03:00
|
|
|
if (!!bytes)
|
|
|
|
logBuffer.Append(bytes.ptr());
|
2014-05-22 07:48:51 +04:00
|
|
|
logBuffer.Append(' ');
|
2007-05-16 03:27:40 +04:00
|
|
|
if (i == symbolCount - 1) {
|
2016-09-30 06:34:44 +03:00
|
|
|
nsCString location;
|
|
|
|
rv = info.GetLocation(location);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
LOG(("%s] from %s\n", logBuffer.get(), location.get()));
|
2007-05-16 03:27:40 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cache this module for later
|
|
|
|
if (newEntry) {
|
2014-05-13 01:37:46 +04:00
|
|
|
mImports.Put(info.Key(), newEntry);
|
2007-05-16 03:27:40 +04:00
|
|
|
newEntry.forget();
|
|
|
|
}
|
2011-10-14 21:52:47 +04:00
|
|
|
|
2007-05-16 03:27:40 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-07-18 03:11:06 +03:00
|
|
|
nsresult
|
2011-06-15 22:08:43 +04:00
|
|
|
mozJSComponentLoader::Unload(const nsACString & aLocation)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (!mInitialized) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-05-13 01:37:46 +04:00
|
|
|
ComponentLoaderInfo info(aLocation);
|
|
|
|
rv = info.EnsureKey();
|
2011-06-15 22:08:43 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
ModuleEntry* mod;
|
2014-05-13 01:37:46 +04:00
|
|
|
if (mImports.Get(info.Key(), &mod)) {
|
2017-07-25 06:32:42 +03:00
|
|
|
mLocations.Remove(mod->resolvedURL);
|
2014-05-13 01:37:46 +04:00
|
|
|
mImports.Remove(info.Key());
|
2011-06-15 22:08:43 +04:00
|
|
|
}
|
|
|
|
|
2017-07-19 00:47:27 +03:00
|
|
|
// If this is the last module to be unloaded, we will leak mLoaderGlobal
|
|
|
|
// until UnloadModules is called. So be it.
|
|
|
|
|
2011-06-15 22:08:43 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-10-20 20:39:24 +04:00
|
|
|
NS_IMETHODIMP
|
2015-03-29 01:22:11 +03:00
|
|
|
mozJSComponentLoader::Observe(nsISupports* subject, const char* topic,
|
|
|
|
const char16_t* data)
|
2005-10-20 20:39:24 +04:00
|
|
|
{
|
2010-08-12 23:37:52 +04:00
|
|
|
if (!strcmp(topic, "xpcom-shutdown-loaders")) {
|
2005-12-13 20:55:43 +03:00
|
|
|
UnloadModules();
|
2011-10-14 21:52:48 +04:00
|
|
|
} else {
|
2005-12-13 20:55:43 +03:00
|
|
|
NS_ERROR("Unexpected observer topic.");
|
2005-10-20 20:39:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-12-06 01:54:30 +04:00
|
|
|
size_t
|
|
|
|
mozJSComponentLoader::ModuleEntry::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|
|
|
{
|
|
|
|
size_t n = aMallocSizeOf(this);
|
|
|
|
n += aMallocSizeOf(location);
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2010-06-12 00:13:26 +04:00
|
|
|
/* static */ already_AddRefed<nsIFactory>
|
|
|
|
mozJSComponentLoader::ModuleEntry::GetFactory(const mozilla::Module& module,
|
|
|
|
const mozilla::Module::CIDEntry& entry)
|
|
|
|
{
|
|
|
|
const ModuleEntry& self = static_cast<const ModuleEntry&>(module);
|
2013-08-14 11:00:34 +04:00
|
|
|
MOZ_ASSERT(self.getfactoryobj, "Handing out an uninitialized module?");
|
2010-06-12 00:13:26 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIFactory> f;
|
|
|
|
nsresult rv = self.getfactoryobj->Get(*entry.cid, getter_AddRefs(f));
|
|
|
|
if (NS_FAILED(rv))
|
2013-06-12 11:00:09 +04:00
|
|
|
return nullptr;
|
2010-06-12 00:13:26 +04:00
|
|
|
|
|
|
|
return f.forget();
|
|
|
|
}
|
|
|
|
|
1999-10-01 01:47:04 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2013-04-29 22:16:19 +04:00
|
|
|
JSCLContextHelper::JSCLContextHelper(JSContext* aCx)
|
|
|
|
: mContext(aCx)
|
|
|
|
, mBuf(nullptr)
|
2000-09-21 08:30:32 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-05-13 19:56:26 +04:00
|
|
|
JSCLContextHelper::~JSCLContextHelper()
|
2000-09-21 08:30:32 +04:00
|
|
|
{
|
2011-05-13 19:56:26 +04:00
|
|
|
if (mBuf) {
|
2017-03-04 01:10:11 +03:00
|
|
|
JS_ReportErrorUTF8(mContext, "%s", mBuf.get());
|
2009-02-18 07:11:09 +03:00
|
|
|
}
|
2011-05-13 19:56:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-03-04 01:10:11 +03:00
|
|
|
JSCLContextHelper::reportErrorAfterPop(UniqueChars&& buf)
|
2011-05-13 19:56:26 +04:00
|
|
|
{
|
2013-08-14 11:00:34 +04:00
|
|
|
MOZ_ASSERT(!mBuf, "Already called reportErrorAfterPop");
|
2017-03-04 01:10:11 +03:00
|
|
|
mBuf = Move(buf);
|
2009-02-18 07:11:09 +03:00
|
|
|
}
|