2013-06-12 07:00:09 +00: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 11:12:37 +00: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 06:18:08 +00:00
|
|
|
|
2011-12-16 19:42:07 +00:00
|
|
|
#include "mozilla/Attributes.h"
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
#ifdef MOZ_LOGGING
|
|
|
|
#define FORCE_PR_LOG
|
|
|
|
#endif
|
|
|
|
|
2013-01-15 12:22:03 +00:00
|
|
|
#include <cstdarg>
|
2007-05-15 23:27:40 +00:00
|
|
|
|
2000-05-15 18:07:36 +00:00
|
|
|
#include "prlog.h"
|
2011-11-10 00:27:08 +00:00
|
|
|
#ifdef ANDROID
|
|
|
|
#include <android/log.h>
|
|
|
|
#endif
|
2012-08-06 20:41:40 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
2000-05-26 04:56:23 +00:00
|
|
|
|
2013-03-17 03:36:37 +00:00
|
|
|
#include "jsapi.h"
|
2000-05-26 04:56:23 +00:00
|
|
|
#include "nsCOMPtr.h"
|
2005-12-13 17:55:43 +00:00
|
|
|
#include "nsAutoPtr.h"
|
2000-05-26 04:56:23 +00:00
|
|
|
#include "nsICategoryManager.h"
|
1999-09-07 06:18:08 +00:00
|
|
|
#include "nsIComponentManager.h"
|
2010-06-10 18:11:11 +00:00
|
|
|
#include "mozilla/Module.h"
|
2012-06-06 02:08:30 +00:00
|
|
|
#include "nsIFile.h"
|
1999-09-07 06:18:08 +00:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsISupports.h"
|
|
|
|
#include "mozJSComponentLoader.h"
|
2011-07-10 03:21:16 +00:00
|
|
|
#include "mozJSLoaderUtils.h"
|
1999-09-07 06:18:08 +00:00
|
|
|
#include "nsIJSRuntimeService.h"
|
|
|
|
#include "nsIXPConnect.h"
|
|
|
|
#include "nsCRT.h"
|
2000-06-03 09:46:12 +00:00
|
|
|
#include "nsMemory.h"
|
2000-05-16 05:09:31 +00:00
|
|
|
#include "nsIObserverService.h"
|
2000-08-16 04:01:02 +00:00
|
|
|
#include "nsIXPCScriptable.h"
|
2003-08-02 19:33:52 +00:00
|
|
|
#include "nsString.h"
|
2000-05-26 04:56:23 +00:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2005-10-20 16:39:24 +00:00
|
|
|
#include "nsIURI.h"
|
2007-06-10 21:13:18 +00:00
|
|
|
#include "nsIFileURL.h"
|
2010-06-15 19:38:46 +00:00
|
|
|
#include "nsIJARURI.h"
|
2002-01-08 01:31:25 +00:00
|
|
|
#include "nsNetUtil.h"
|
2012-12-11 21:21:03 +00:00
|
|
|
#include "nsDOMBlobBuilder.h"
|
2007-05-15 23:27:40 +00:00
|
|
|
#include "jsprf.h"
|
2012-03-09 09:48:50 +00:00
|
|
|
#include "nsJSPrincipals.h"
|
2000-03-31 11:19:51 +00:00
|
|
|
// For reporting errors with the console service
|
|
|
|
#include "nsIScriptError.h"
|
|
|
|
#include "nsIConsoleService.h"
|
2010-08-12 19:37:52 +00:00
|
|
|
#include "nsIStorageStream.h"
|
|
|
|
#include "nsIStringStream.h"
|
2010-06-15 19:38:46 +00:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
#include "nsILocalFileWin.h"
|
|
|
|
#endif
|
2010-11-16 01:39:28 +00:00
|
|
|
#include "xpcprivate.h"
|
2011-12-28 08:13:38 +00:00
|
|
|
#include "xpcpublic.h"
|
2011-02-25 11:53:36 +00:00
|
|
|
#include "nsIResProtocolHandler.h"
|
2012-07-23 14:47:18 +00:00
|
|
|
#include "nsContentUtils.h"
|
2013-05-22 16:05:26 +00:00
|
|
|
#include "nsCxPusher.h"
|
2012-07-23 14:47:18 +00:00
|
|
|
#include "WrapperFactory.h"
|
2000-03-31 11:19:51 +00:00
|
|
|
|
2010-08-12 19:37:52 +00:00
|
|
|
#include "mozilla/scache/StartupCache.h"
|
|
|
|
#include "mozilla/scache/StartupCacheUtils.h"
|
2011-01-07 19:04:19 +00:00
|
|
|
#include "mozilla/Omnijar.h"
|
2012-06-07 02:52:14 +00:00
|
|
|
#include "mozilla/Preferences.h"
|
2010-08-12 19:37:52 +00:00
|
|
|
|
2008-01-20 02:31:10 +00:00
|
|
|
#include "jsdbgapi.h"
|
|
|
|
|
2010-05-19 23:22:19 +00:00
|
|
|
|
2011-11-08 17:10:51 +00:00
|
|
|
using namespace mozilla;
|
2011-07-20 07:39:09 +00:00
|
|
|
using namespace mozilla::scache;
|
2012-07-23 14:47:18 +00:00
|
|
|
using namespace xpc;
|
2013-04-23 15:48:05 +00:00
|
|
|
using namespace JS;
|
2011-07-20 07:39:09 +00:00
|
|
|
|
2012-11-26 22:41:59 +00:00
|
|
|
// This JSClass exists to trick silly code that expects toString()ing the
|
|
|
|
// global in a component scope to return something with "BackstagePass" in it
|
|
|
|
// to continue working.
|
|
|
|
static JSClass kFakeBackstagePassJSClass =
|
|
|
|
{
|
|
|
|
"FakeBackstagePass",
|
|
|
|
0,
|
|
|
|
JS_PropertyStub,
|
2013-04-06 04:22:55 +00:00
|
|
|
JS_DeletePropertyStub,
|
2012-11-26 22:41:59 +00:00
|
|
|
JS_PropertyStub,
|
|
|
|
JS_StrictPropertyStub,
|
|
|
|
JS_EnumerateStub,
|
|
|
|
JS_ResolveStub,
|
|
|
|
JS_ConvertStub
|
|
|
|
};
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
static const char kJSRuntimeServiceContractID[] = "@mozilla.org/js/xpc/RuntimeService;1";
|
|
|
|
static const char kXPConnectServiceContractID[] = "@mozilla.org/js/xpc/XPConnect;1";
|
|
|
|
static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1";
|
2011-06-16 04:54:47 +00:00
|
|
|
static const char kJSCachePrefix[] = "jsloader";
|
1999-11-10 00:34:26 +00:00
|
|
|
|
2005-10-03 23:34:58 +00:00
|
|
|
/* Some platforms don't have an implementation of PR_MemMap(). */
|
Bug 627277 - Remove (broken) BeOS support. r=biesi,dwitte,gavin,joe,jorendorff,josh,khuey,mfinkle,neil,Pike,roc,shaver,smontagu,taras
2011-02-19 19:10:24 +00:00
|
|
|
#ifndef XP_OS2
|
2005-10-03 23:34:58 +00:00
|
|
|
#define HAVE_PR_MEMMAP
|
|
|
|
#endif
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
/**
|
|
|
|
* Buffer sizes for serialization and deserialization of scripts.
|
2008-04-02 06:41:23 +00:00
|
|
|
* FIXME: bug #411579 (tune this macro!) Last updated: Jan 2008
|
2005-10-20 16:39:24 +00:00
|
|
|
*/
|
|
|
|
#define XPC_SERIALIZATION_BUFFER_SIZE (64 * 1024)
|
2008-04-02 06:41:23 +00:00
|
|
|
#define XPC_DESERIALIZATION_BUFFER_SIZE (12 * 8192)
|
2005-10-20 16:39:24 +00:00
|
|
|
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
// NSPR_LOG_MODULES=JSComponentLoader:5
|
|
|
|
static PRLogModuleInfo *gJSCLLog;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define LOG(args) PR_LOG(gJSCLLog, PR_LOG_DEBUG, args)
|
|
|
|
|
2007-05-15 23:27:40 +00: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."
|
|
|
|
|
2008-09-06 22:21:43 +00:00
|
|
|
void
|
2006-06-10 00:47:40 +00:00
|
|
|
mozJSLoaderErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
|
2001-03-27 05:35:52 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
/* Use the console service to register the error. */
|
|
|
|
nsCOMPtr<nsIConsoleService> consoleService =
|
2005-10-20 16:39:24 +00:00
|
|
|
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
2001-03-27 05:35:52 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make an nsIScriptError, populate it with information from this
|
|
|
|
* error, then log it with the console service. The UI can then
|
2006-05-25 21:22:32 +00:00
|
|
|
* poll the service to update the Error console.
|
2001-03-27 05:35:52 +00:00
|
|
|
*/
|
2011-10-14 17:52:47 +00:00
|
|
|
nsCOMPtr<nsIScriptError> errorObject =
|
2005-10-20 16:39:24 +00:00
|
|
|
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2001-03-27 05:35:52 +00:00
|
|
|
if (consoleService && errorObject) {
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t column = rep->uctokenptr - rep->uclinebuf;
|
2001-03-27 05:35:52 +00:00
|
|
|
|
2012-09-09 23:29:12 +00:00
|
|
|
const PRUnichar* ucmessage =
|
|
|
|
static_cast<const PRUnichar*>(rep->ucmessage);
|
|
|
|
const PRUnichar* uclinebuf =
|
|
|
|
static_cast<const PRUnichar*>(rep->uclinebuf);
|
|
|
|
|
|
|
|
rv = errorObject->Init(
|
|
|
|
ucmessage ? nsDependentString(ucmessage) : EmptyString(),
|
|
|
|
NS_ConvertASCIItoUTF16(rep->filename),
|
|
|
|
uclinebuf ? nsDependentString(uclinebuf) : EmptyString(),
|
|
|
|
rep->lineno, column, rep->flags,
|
|
|
|
"component javascript");
|
2001-03-27 05:35:52 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = consoleService->LogMessage(errorObject);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// We're done! Skip return to fall thru to stderr
|
|
|
|
// printout, for the benefit of those invoking the
|
|
|
|
// browser with -console
|
|
|
|
// return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If any of the above fails for some reason, fall back to
|
|
|
|
* printing to stderr.
|
|
|
|
*/
|
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 17:42:36 +00:00
|
|
|
#ifdef DEBUG
|
2001-03-27 05:35:52 +00:00
|
|
|
fprintf(stderr, "JS Component Loader: %s %s:%d\n"
|
|
|
|
" %s\n",
|
|
|
|
JSREPORT_IS_WARNING(rep->flags) ? "WARNING" : "ERROR",
|
|
|
|
rep->filename, rep->lineno,
|
|
|
|
message ? message : "<no message>");
|
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 17:42:36 +00:00
|
|
|
#endif
|
2001-03-27 05:35:52 +00:00
|
|
|
}
|
|
|
|
|
2008-09-06 22:21:43 +00:00
|
|
|
static JSBool
|
2012-02-28 23:11:11 +00:00
|
|
|
Dump(JSContext *cx, unsigned argc, jsval *vp)
|
1999-09-07 06:18:08 +00:00
|
|
|
{
|
|
|
|
JSString *str;
|
|
|
|
if (!argc)
|
2011-11-26 10:05:59 +00:00
|
|
|
return true;
|
2010-03-23 21:08:18 +00:00
|
|
|
|
2010-08-16 19:35:04 +00:00
|
|
|
str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
|
1999-09-07 06:18:08 +00:00
|
|
|
if (!str)
|
2011-11-26 10:05:59 +00:00
|
|
|
return false;
|
1999-09-07 06:18:08 +00:00
|
|
|
|
2010-12-03 08:24:17 +00:00
|
|
|
size_t length;
|
|
|
|
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
|
|
|
|
if (!chars)
|
2011-11-26 10:05:59 +00:00
|
|
|
return false;
|
2010-12-03 08:24:17 +00:00
|
|
|
|
2011-11-10 00:27:08 +00:00
|
|
|
NS_ConvertUTF16toUTF8 utf8str(reinterpret_cast<const PRUnichar*>(chars));
|
|
|
|
#ifdef ANDROID
|
2012-06-28 14:14:11 +00:00
|
|
|
__android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", utf8str.get());
|
2012-08-06 20:41:40 +00:00
|
|
|
#endif
|
|
|
|
#ifdef XP_WIN
|
|
|
|
if (IsDebuggerPresent()) {
|
|
|
|
OutputDebugStringW(reinterpret_cast<const PRUnichar*>(chars));
|
|
|
|
}
|
2011-11-10 00:27:08 +00:00
|
|
|
#endif
|
|
|
|
fputs(utf8str.get(), stdout);
|
2011-10-19 14:01:24 +00:00
|
|
|
fflush(stdout);
|
2011-11-26 10:05:59 +00:00
|
|
|
return true;
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2008-09-06 22:21:43 +00:00
|
|
|
static JSBool
|
2012-02-28 23:11:11 +00:00
|
|
|
Debug(JSContext *cx, unsigned argc, jsval *vp)
|
2000-05-26 04:56:23 +00:00
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
2010-08-16 19:35:04 +00:00
|
|
|
return Dump(cx, argc, vp);
|
2000-05-26 04:56:23 +00:00
|
|
|
#else
|
2011-11-26 10:05:59 +00:00
|
|
|
return true;
|
2000-05-26 04:56:23 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-09-06 22:21:43 +00:00
|
|
|
static JSBool
|
2012-02-28 23:11:11 +00:00
|
|
|
Atob(JSContext *cx, unsigned argc, jsval *vp)
|
2006-12-20 20:10:12 +00:00
|
|
|
{
|
|
|
|
if (!argc)
|
2011-11-26 10:05:59 +00:00
|
|
|
return true;
|
2006-12-20 20:10:12 +00:00
|
|
|
|
2011-12-28 08:13:38 +00:00
|
|
|
return xpc::Base64Decode(cx, JS_ARGV(cx, vp)[0], &JS_RVAL(cx, vp));
|
2006-12-20 20:10:12 +00:00
|
|
|
}
|
|
|
|
|
2008-09-06 22:21:43 +00:00
|
|
|
static JSBool
|
2012-02-28 23:11:11 +00:00
|
|
|
Btoa(JSContext *cx, unsigned argc, jsval *vp)
|
2006-12-20 20:10:12 +00:00
|
|
|
{
|
|
|
|
if (!argc)
|
2011-11-26 10:05:59 +00:00
|
|
|
return true;
|
2006-12-20 20:10:12 +00:00
|
|
|
|
2011-12-28 08:13:38 +00:00
|
|
|
return xpc::Base64Encode(cx, JS_ARGV(cx, vp)[0], &JS_RVAL(cx, vp));
|
2006-12-20 20:10:12 +00:00
|
|
|
}
|
|
|
|
|
2011-07-06 16:34:26 +00:00
|
|
|
static JSBool
|
2013-05-04 17:25:15 +00:00
|
|
|
File(JSContext *cx, unsigned argc, Value *vp)
|
2011-07-06 16:34:26 +00:00
|
|
|
{
|
2013-05-04 17:25:15 +00:00
|
|
|
CallArgs args = CallArgsFromVp(argc, vp);
|
2011-07-06 16:34:26 +00:00
|
|
|
|
2013-05-04 17:25:15 +00:00
|
|
|
if (args.length() == 0) {
|
2011-07-06 16:34:26 +00:00
|
|
|
XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
|
2011-11-26 10:05:59 +00:00
|
|
|
return false;
|
2011-07-06 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> native;
|
2013-05-04 17:25:15 +00:00
|
|
|
nsresult rv = nsDOMMultipartFile::NewFile(getter_AddRefs(native));
|
2011-07-06 16:34:26 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
XPCThrower::Throw(rv, cx);
|
2011-11-26 10:05:59 +00:00
|
|
|
return false;
|
2011-07-06 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIJSNativeInitializer> initializer = do_QueryInterface(native);
|
|
|
|
NS_ASSERTION(initializer, "what?");
|
|
|
|
|
2013-05-04 17:25:15 +00:00
|
|
|
rv = initializer->Initialize(nullptr, cx, nullptr, args);
|
2011-07-06 16:34:26 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
XPCThrower::Throw(rv, cx);
|
2011-11-26 10:05:59 +00:00
|
|
|
return false;
|
2011-07-06 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
2013-05-17 05:49:41 +00:00
|
|
|
nsXPConnect* xpc = nsXPConnect::XPConnect();
|
2011-07-06 16:34:26 +00:00
|
|
|
JSObject* glob = JS_GetGlobalForScopeChain(cx);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
2012-07-30 14:20:58 +00:00
|
|
|
rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
|
2011-07-06 16:34:26 +00:00
|
|
|
&NS_GET_IID(nsISupports),
|
2013-05-04 17:25:15 +00:00
|
|
|
true, args.rval().address(), nullptr);
|
2011-07-06 16:34:26 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
XPCThrower::Throw(rv, cx);
|
2011-11-26 10:05:59 +00:00
|
|
|
return false;
|
2011-07-06 16:34:26 +00:00
|
|
|
}
|
2011-11-26 10:05:59 +00:00
|
|
|
return true;
|
2011-07-06 16:34:26 +00:00
|
|
|
}
|
|
|
|
|
2013-01-04 07:53:25 +00:00
|
|
|
static JSBool
|
2013-05-04 17:25:15 +00:00
|
|
|
Blob(JSContext *cx, unsigned argc, Value *vp)
|
2013-01-04 07:53:25 +00:00
|
|
|
{
|
2013-05-04 17:25:15 +00:00
|
|
|
CallArgs args = CallArgsFromVp(argc, vp);
|
2013-01-04 07:53:25 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> native;
|
2013-05-04 17:25:15 +00:00
|
|
|
nsresult rv = nsDOMMultipartFile::NewBlob(getter_AddRefs(native));
|
2013-01-04 07:53:25 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
XPCThrower::Throw(rv, cx);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIJSNativeInitializer> initializer = do_QueryInterface(native);
|
|
|
|
NS_ASSERTION(initializer, "what?");
|
|
|
|
|
2013-05-04 17:25:15 +00:00
|
|
|
rv = initializer->Initialize(nullptr, cx, nullptr, args);
|
2013-01-04 07:53:25 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
XPCThrower::Throw(rv, cx);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-17 05:49:41 +00:00
|
|
|
nsXPConnect* xpc = nsXPConnect::XPConnect();
|
2013-01-04 07:53:25 +00:00
|
|
|
JSObject* glob = JS_GetGlobalForScopeChain(cx);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
|
|
|
rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
|
|
|
|
&NS_GET_IID(nsISupports),
|
2013-05-04 17:25:15 +00:00
|
|
|
true, args.rval().address(), nullptr);
|
2013-01-04 07:53:25 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
XPCThrower::Throw(rv, cx);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-04-22 21:15:49 +00:00
|
|
|
static const JSFunctionSpec gGlobalFun[] = {
|
2012-08-08 05:26:19 +00:00
|
|
|
JS_FS("dump", Dump, 1,0),
|
|
|
|
JS_FS("debug", Debug, 1,0),
|
|
|
|
JS_FS("atob", Atob, 1,0),
|
|
|
|
JS_FS("btoa", Btoa, 1,0),
|
|
|
|
JS_FS("File", File, 1,JSFUN_CONSTRUCTOR),
|
2013-01-04 07:53:25 +00:00
|
|
|
JS_FS("Blob", Blob, 2,JSFUN_CONSTRUCTOR),
|
2012-08-08 05:26:19 +00:00
|
|
|
JS_FS_END
|
1999-09-07 06:18:08 +00:00
|
|
|
};
|
|
|
|
|
2013-04-29 18:16:19 +00:00
|
|
|
class MOZ_STACK_CLASS JSCLContextHelper
|
2005-10-20 16:39:24 +00:00
|
|
|
{
|
|
|
|
public:
|
2013-04-29 18:16:19 +00:00
|
|
|
JSCLContextHelper(JSContext* aCx);
|
2011-05-13 15:56:26 +00:00
|
|
|
~JSCLContextHelper();
|
2009-02-18 04:11:09 +00:00
|
|
|
|
2011-05-13 15:56:26 +00:00
|
|
|
void reportErrorAfterPop(char *buf);
|
2005-10-20 16:39:24 +00:00
|
|
|
|
|
|
|
operator JSContext*() const {return mContext;}
|
|
|
|
|
|
|
|
private:
|
2013-04-29 18:16:19 +00:00
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
JSContext* mContext;
|
2013-04-29 18:16:19 +00:00
|
|
|
nsCxPusher mPusher;
|
2011-05-13 15:56:26 +00:00
|
|
|
char* mBuf;
|
2010-03-12 06:50:10 +00:00
|
|
|
|
|
|
|
// prevent copying and assignment
|
2011-12-16 19:42:07 +00:00
|
|
|
JSCLContextHelper(const JSCLContextHelper &) MOZ_DELETE;
|
|
|
|
const JSCLContextHelper& operator=(const JSCLContextHelper &) MOZ_DELETE;
|
2005-10-20 16:39:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class JSCLAutoErrorReporterSetter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
JSCLAutoErrorReporterSetter(JSContext* cx, JSErrorReporter reporter)
|
|
|
|
{mContext = cx; mOldReporter = JS_SetErrorReporter(cx, reporter);}
|
|
|
|
~JSCLAutoErrorReporterSetter()
|
2011-10-14 17:52:47 +00:00
|
|
|
{JS_SetErrorReporter(mContext, mOldReporter);}
|
2005-10-20 16:39:24 +00:00
|
|
|
private:
|
|
|
|
JSContext* mContext;
|
|
|
|
JSErrorReporter mOldReporter;
|
2011-12-16 19:42:07 +00:00
|
|
|
|
|
|
|
JSCLAutoErrorReporterSetter(const JSCLAutoErrorReporterSetter &) MOZ_DELETE;
|
|
|
|
const JSCLAutoErrorReporterSetter& operator=(const JSCLAutoErrorReporterSetter &) MOZ_DELETE;
|
2005-10-20 16:39:24 +00:00
|
|
|
};
|
|
|
|
|
2009-02-18 04:11:09 +00:00
|
|
|
static nsresult
|
2011-12-18 10:09:16 +00:00
|
|
|
ReportOnCaller(JSContext *callerContext,
|
2009-02-18 04:11:09 +00:00
|
|
|
const char *format, ...) {
|
2011-12-18 10:09:16 +00:00
|
|
|
if (!callerContext) {
|
2009-02-18 04:11:09 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2009-02-18 04:11:09 +00:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
|
|
|
|
2011-05-13 15:56:26 +00:00
|
|
|
char *buf = JS_vsmprintf(format, ap);
|
|
|
|
if (!buf) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
JS_ReportError(callerContext, buf);
|
|
|
|
JS_smprintf_free(buf);
|
|
|
|
|
|
|
|
return NS_OK;
|
2009-02-18 04:11:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
ReportOnCaller(JSCLContextHelper &helper,
|
|
|
|
const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
|
|
|
|
2011-05-13 15:56:26 +00:00
|
|
|
char *buf = JS_vsmprintf(format, ap);
|
|
|
|
if (!buf) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2009-02-18 04:11:09 +00:00
|
|
|
}
|
|
|
|
|
2011-05-13 15:56:26 +00:00
|
|
|
helper.reportErrorAfterPop(buf);
|
|
|
|
|
|
|
|
return NS_OK;
|
2009-02-18 04:11:09 +00:00
|
|
|
}
|
|
|
|
|
1999-09-25 20:07:20 +00:00
|
|
|
mozJSComponentLoader::mozJSComponentLoader()
|
2012-07-30 14:20:58 +00:00
|
|
|
: mRuntime(nullptr),
|
|
|
|
mContext(nullptr),
|
2012-10-31 16:13:28 +00:00
|
|
|
mInitialized(false),
|
|
|
|
mReuseLoaderGlobal(false)
|
1999-09-07 06:18:08 +00:00
|
|
|
{
|
2005-12-13 17:55:43 +00:00
|
|
|
NS_ASSERTION(!sSelf, "mozJSComponentLoader should be a singleton");
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
#ifdef PR_LOGGING
|
|
|
|
if (!gJSCLLog) {
|
|
|
|
gJSCLLog = PR_NewLogModule("JSComponentLoader");
|
|
|
|
}
|
|
|
|
#endif
|
1999-09-07 06:18:08 +00:00
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
sSelf = this;
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
mozJSComponentLoader::~mozJSComponentLoader()
|
1999-09-07 06:18:08 +00:00
|
|
|
{
|
2005-12-13 17:55:43 +00:00
|
|
|
if (mInitialized) {
|
|
|
|
NS_ERROR("'xpcom-shutdown-loaders' was not fired before cleaning up mozJSComponentLoader");
|
|
|
|
UnloadModules();
|
1999-11-10 00:34:26 +00:00
|
|
|
}
|
1999-09-07 06:18:08 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
sSelf = nullptr;
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
mozJSComponentLoader*
|
|
|
|
mozJSComponentLoader::sSelf;
|
1999-09-07 20:30:25 +00:00
|
|
|
|
2007-05-15 23:27:40 +00:00
|
|
|
NS_IMPL_ISUPPORTS3(mozJSComponentLoader,
|
2010-06-10 18:11:11 +00:00
|
|
|
mozilla::ModuleLoader,
|
2007-05-15 23:27:40 +00:00
|
|
|
xpcIJSModuleLoader,
|
|
|
|
nsIObserver)
|
2011-10-14 17:52:47 +00:00
|
|
|
|
1999-09-24 02:52:46 +00:00
|
|
|
nsresult
|
1999-09-24 01:37:44 +00:00
|
|
|
mozJSComponentLoader::ReallyInit()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-11-10 00:34:26 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
mReuseLoaderGlobal = Preferences::GetBool("jsloader.reuseGlobal");
|
2010-08-12 19:37:52 +00:00
|
|
|
|
2013-05-07 18:02:31 +00:00
|
|
|
// XXXkhuey B2G child processes have some sort of preferences race that
|
|
|
|
// results in getting the wrong value.
|
|
|
|
#ifdef MOZ_B2G
|
|
|
|
mReuseLoaderGlobal = true;
|
|
|
|
#endif
|
|
|
|
|
1999-11-10 00:34:26 +00:00
|
|
|
/*
|
|
|
|
* Get the JSRuntime from the runtime svc, if possible.
|
|
|
|
* We keep a reference around, because it's a Bad Thing if the runtime
|
|
|
|
* service gets shut down before we're done. Bad!
|
|
|
|
*/
|
2000-09-21 04:30:32 +00:00
|
|
|
|
2000-09-13 23:57:52 +00:00
|
|
|
mRuntimeService = do_GetService(kJSRuntimeServiceContractID, &rv);
|
1999-11-18 15:39:28 +00:00
|
|
|
if (NS_FAILED(rv) ||
|
|
|
|
NS_FAILED(rv = mRuntimeService->GetRuntime(&mRuntime)))
|
1999-09-07 20:30:25 +00:00
|
|
|
return rv;
|
1999-11-10 00:34:26 +00:00
|
|
|
|
2005-06-28 15:21:31 +00:00
|
|
|
// Create our compilation context.
|
|
|
|
mContext = JS_NewContext(mRuntime, 256);
|
|
|
|
if (!mContext)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2008-03-25 14:08:48 +00:00
|
|
|
// Always use the latest js version
|
|
|
|
JS_SetVersion(mContext, JSVERSION_LATEST);
|
|
|
|
|
2011-10-14 17:52:47 +00:00
|
|
|
nsCOMPtr<nsIScriptSecurityManager> secman =
|
2005-10-20 16:39:24 +00:00
|
|
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
2000-09-21 04:30:32 +00:00
|
|
|
if (!secman)
|
2000-08-16 04:01:02 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
rv = secman->GetSystemPrincipal(getter_AddRefs(mSystemPrincipal));
|
|
|
|
if (NS_FAILED(rv) || !mSystemPrincipal)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2012-05-18 17:30:49 +00:00
|
|
|
mModules.Init(32);
|
|
|
|
mImports.Init(32);
|
|
|
|
mInProgressImports.Init(32);
|
2012-11-13 19:13:27 +00:00
|
|
|
mThisObjects.Init(32);
|
1999-09-07 06:18:08 +00:00
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsSvc =
|
|
|
|
do_GetService(kObserverServiceContractID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
rv = obsSvc->AddObserver(this, "xpcom-shutdown-loaders", false);
|
2005-12-13 17:55:43 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
1999-11-10 00:34:26 +00:00
|
|
|
#ifdef DEBUG_shaver_off
|
2000-10-05 04:15:43 +00:00
|
|
|
fprintf(stderr, "mJCL: ReallyInit success!\n");
|
1999-09-07 06:18:08 +00:00
|
|
|
#endif
|
2011-10-17 14:59:28 +00:00
|
|
|
mInitialized = true;
|
1999-11-10 00:34:26 +00:00
|
|
|
|
1999-09-07 06:18:08 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-06-10 18:11:11 +00:00
|
|
|
const mozilla::Module*
|
2011-11-08 17:10:51 +00:00
|
|
|
mozJSComponentLoader::LoadModule(FileLocation &aFile)
|
2010-06-15 19:38:46 +00:00
|
|
|
{
|
2012-06-06 02:08:30 +00:00
|
|
|
nsCOMPtr<nsIFile> file = aFile.GetBaseFile();
|
2010-06-15 19:38:46 +00:00
|
|
|
|
2011-11-08 17:10:51 +00:00
|
|
|
nsCString spec;
|
|
|
|
aFile.GetURIString(spec);
|
2010-06-15 19:38:46 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
2011-11-08 17:10:51 +00:00
|
|
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), spec);
|
2010-06-21 15:41:42 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NULL;
|
2010-06-15 19:38:46 +00:00
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
if (!mInitialized) {
|
|
|
|
rv = ReallyInit();
|
2005-12-03 15:27:17 +00:00
|
|
|
if (NS_FAILED(rv))
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2005-10-20 16:39:24 +00:00
|
|
|
}
|
1999-09-27 02:22:25 +00:00
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
ModuleEntry* mod;
|
2011-11-08 17:10:51 +00:00
|
|
|
if (mModules.Get(spec, &mod))
|
2012-11-26 22:41:59 +00:00
|
|
|
return mod;
|
2005-12-03 15:27:17 +00:00
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
nsAutoPtr<ModuleEntry> entry(new ModuleEntry);
|
2005-12-03 15:27:17 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedValue dummy(mContext);
|
2012-10-31 16:13:28 +00:00
|
|
|
rv = ObjectForLocation(file, uri, &entry->obj,
|
2013-04-23 15:48:05 +00:00
|
|
|
&entry->location, false, &dummy);
|
2005-10-20 16:39:24 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
nsCOMPtr<nsIXPConnect> xpc = do_GetService(kXPConnectServiceContractID,
|
|
|
|
&rv);
|
2005-12-13 17:55:43 +00:00
|
|
|
if (NS_FAILED(rv))
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2005-12-13 17:55:43 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIComponentManager> cm;
|
|
|
|
rv = NS_GetComponentManager(getter_AddRefs(cm));
|
|
|
|
if (NS_FAILED(rv))
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2000-08-24 07:50:27 +00:00
|
|
|
|
2013-04-29 18:16:19 +00:00
|
|
|
JSCLContextHelper cx(mContext);
|
2012-10-31 16:13:28 +00:00
|
|
|
JSAutoCompartment ac(cx, entry->obj);
|
1999-11-18 15:39:28 +00:00
|
|
|
|
2000-10-05 04:15:43 +00:00
|
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> cm_holder;
|
2012-10-31 16:13:28 +00:00
|
|
|
rv = xpc->WrapNative(cx, entry->obj, cm,
|
2000-10-05 04:15:43 +00:00
|
|
|
NS_GET_IID(nsIComponentManager),
|
|
|
|
getter_AddRefs(cm_holder));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
#ifdef DEBUG_shaver
|
|
|
|
fprintf(stderr, "WrapNative(%p,%p,nsIComponentManager) failed: %x\n",
|
2001-03-27 05:35:52 +00:00
|
|
|
(void *)(JSContext*)cx, (void *)mCompMgr, rv);
|
2000-10-05 04:15:43 +00:00
|
|
|
#endif
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2000-10-05 04:15:43 +00:00
|
|
|
}
|
|
|
|
|
2013-05-20 12:44:18 +00:00
|
|
|
JSObject* cm_jsobj = cm_holder->GetJSObject();
|
|
|
|
if (!cm_jsobj) {
|
2000-10-05 04:15:43 +00:00
|
|
|
#ifdef DEBUG_shaver
|
|
|
|
fprintf(stderr, "GetJSObject of ComponentManager failed\n");
|
|
|
|
#endif
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2005-12-13 17:55:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> file_holder;
|
2012-10-31 16:13:28 +00:00
|
|
|
rv = xpc->WrapNative(cx, entry->obj, file,
|
2005-12-13 17:55:43 +00:00
|
|
|
NS_GET_IID(nsIFile),
|
|
|
|
getter_AddRefs(file_holder));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2005-12-13 17:55:43 +00:00
|
|
|
}
|
|
|
|
|
2013-05-20 12:44:18 +00:00
|
|
|
JSObject* file_jsobj = file_holder->GetJSObject();
|
|
|
|
if (!file_jsobj) {
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2000-10-05 04:15:43 +00:00
|
|
|
}
|
|
|
|
|
2006-06-10 00:47:40 +00:00
|
|
|
JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);
|
1999-11-18 15:39:28 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedValue NSGetFactory_val(cx);
|
|
|
|
if (!JS_GetProperty(cx, entry->obj, "NSGetFactory", NSGetFactory_val.address()) ||
|
2010-06-10 18:11:11 +00:00
|
|
|
JSVAL_IS_VOID(NSGetFactory_val)) {
|
|
|
|
return NULL;
|
2004-10-12 03:37:20 +00:00
|
|
|
}
|
|
|
|
|
2010-06-10 18:11:11 +00:00
|
|
|
if (JS_TypeOfValue(cx, NSGetFactory_val) != JSTYPE_FUNCTION) {
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString spec;
|
2011-11-08 17:10:51 +00:00
|
|
|
uri->GetSpec(spec);
|
2010-06-10 18:11:11 +00:00
|
|
|
JS_ReportError(cx, "%s has NSGetFactory property that is not a function",
|
2010-06-21 15:41:42 +00:00
|
|
|
spec.get());
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
2004-10-12 03:37:20 +00:00
|
|
|
}
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedObject jsGetFactoryObj(cx);
|
|
|
|
if (!JS_ValueToObject(cx, NSGetFactory_val, jsGetFactoryObj.address()) ||
|
2010-06-10 18:11:11 +00:00
|
|
|
!jsGetFactoryObj) {
|
1999-09-07 20:30:25 +00:00
|
|
|
/* XXX report error properly */
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2010-06-10 18:11:11 +00:00
|
|
|
rv = xpc->WrapJS(cx, jsGetFactoryObj,
|
2010-06-11 20:13:26 +00:00
|
|
|
NS_GET_IID(xpcIJSGetFactory), getter_AddRefs(entry->getfactoryobj));
|
2005-10-20 16:39:24 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
1999-09-07 20:30:25 +00: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 17:42:36 +00:00
|
|
|
#ifdef DEBUG
|
1999-09-07 06:18:08 +00: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 17:42:36 +00:00
|
|
|
#endif
|
2010-06-10 18:11:11 +00:00
|
|
|
return NULL;
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
// Cache this module for later
|
2012-05-18 17:30:49 +00:00
|
|
|
mModules.Put(spec, entry);
|
2000-09-21 04:30:32 +00:00
|
|
|
|
2012-05-16 17:42:10 +00:00
|
|
|
// Set the location information for the new global, so that tools like
|
|
|
|
// about:memory may use that information
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!mReuseLoaderGlobal) {
|
|
|
|
xpc::SetLocationForGlobal(entry->obj, spec);
|
|
|
|
}
|
2012-05-16 17:42:10 +00:00
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
// The hash owns the ModuleEntry now, forget about it
|
2010-06-11 20:13:26 +00:00
|
|
|
return entry.forget();
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2012-11-13 19:13:27 +00:00
|
|
|
nsresult
|
|
|
|
mozJSComponentLoader::FindTargetObject(JSContext* aCx,
|
2013-04-23 15:48:05 +00:00
|
|
|
JS::MutableHandleObject aTargetObject)
|
2012-11-13 19:13:27 +00:00
|
|
|
{
|
2013-04-23 15:48:05 +00:00
|
|
|
aTargetObject.set(nullptr);
|
2012-11-13 19:13:27 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedObject targetObject(aCx);
|
2012-11-13 19:13:27 +00:00
|
|
|
if (mReuseLoaderGlobal) {
|
|
|
|
JSScript* script =
|
|
|
|
js::GetOutermostEnclosingFunctionOfScriptedCaller(aCx);
|
|
|
|
if (script) {
|
|
|
|
targetObject = mThisObjects.Get(script);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The above could fail, even if mReuseLoaderGlobal, if the scripted
|
|
|
|
// caller is not a component/JSM (it could be a DOM scope, for
|
|
|
|
// instance).
|
|
|
|
if (!targetObject) {
|
|
|
|
// Our targetObject is the caller's global object. Let's get it.
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIXPConnect> xpc =
|
|
|
|
do_GetService(kXPConnectServiceContractID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsAXPCNativeCallContext *cc = nullptr;
|
|
|
|
rv = xpc->GetCurrentNativeCallContext(&cc);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIXPConnectWrappedNative> wn;
|
|
|
|
rv = cc->GetCalleeWrapper(getter_AddRefs(wn));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2013-05-20 12:44:18 +00:00
|
|
|
targetObject = wn->GetJSObject();
|
2012-11-13 19:13:27 +00:00
|
|
|
if (!targetObject) {
|
|
|
|
NS_ERROR("null calling object");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
targetObject = JS_GetGlobalForObject(aCx, targetObject);
|
|
|
|
}
|
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
aTargetObject.set(targetObject);
|
2012-11-13 19:13:27 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-11-26 22:41:55 +00:00
|
|
|
void
|
2013-04-26 17:50:18 +00:00
|
|
|
mozJSComponentLoader::NoteSubScript(HandleScript aScript, HandleObject aThisObject)
|
2012-11-26 22:41:55 +00:00
|
|
|
{
|
|
|
|
if (!mInitialized && NS_FAILED(ReallyInit())) {
|
2013-06-12 07:00:09 +00:00
|
|
|
MOZ_CRASH();
|
2012-11-26 22:41:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mThisObjects.Put(aScript, aThisObject);
|
|
|
|
}
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
// Some stack based classes for cleaning up on early return
|
|
|
|
#ifdef HAVE_PR_MEMMAP
|
|
|
|
class FileAutoCloser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit FileAutoCloser(PRFileDesc *file) : mFile(file) {}
|
|
|
|
~FileAutoCloser() { PR_Close(mFile); }
|
|
|
|
private:
|
|
|
|
PRFileDesc *mFile;
|
|
|
|
};
|
|
|
|
|
|
|
|
class FileMapAutoCloser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit FileMapAutoCloser(PRFileMap *map) : mMap(map) {}
|
|
|
|
~FileMapAutoCloser() { PR_CloseFileMap(mMap); }
|
|
|
|
private:
|
|
|
|
PRFileMap *mMap;
|
|
|
|
};
|
2011-12-16 19:08:59 +00:00
|
|
|
#else
|
|
|
|
class ANSIFileAutoCloser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit ANSIFileAutoCloser(FILE *file) : mFile(file) {}
|
|
|
|
~ANSIFileAutoCloser() { fclose(mFile); }
|
|
|
|
private:
|
|
|
|
FILE *mFile;
|
|
|
|
};
|
2005-10-20 16:39:24 +00:00
|
|
|
#endif
|
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
JSObject*
|
|
|
|
mozJSComponentLoader::PrepareObjectForLocation(JSCLContextHelper& aCx,
|
|
|
|
nsIFile *aComponentFile,
|
|
|
|
nsIURI *aURI,
|
|
|
|
bool aReuseLoaderGlobal,
|
|
|
|
bool *aRealFile)
|
1999-09-07 06:18:08 +00:00
|
|
|
{
|
2012-10-31 16:13:28 +00:00
|
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
|
|
|
if (aReuseLoaderGlobal) {
|
|
|
|
holder = mLoaderGlobal;
|
|
|
|
}
|
2012-10-31 08:35:11 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
nsresult rv = NS_OK;
|
2012-10-31 08:35:11 +00:00
|
|
|
nsCOMPtr<nsIXPConnect> xpc =
|
|
|
|
do_GetService(kXPConnectServiceContractID, &rv);
|
2012-10-31 16:13:28 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
|
|
|
|
if (!mLoaderGlobal) {
|
2013-04-04 09:27:38 +00:00
|
|
|
nsRefPtr<BackstagePass> backstagePass;
|
|
|
|
rv = NS_NewBackstagePass(getter_AddRefs(backstagePass));
|
2012-10-31 16:13:28 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
|
2013-04-04 09:27:38 +00:00
|
|
|
rv = xpc->InitClassesWithNewWrappedGlobal(aCx,
|
|
|
|
static_cast<nsIGlobalObject *>(backstagePass),
|
2012-10-31 16:13:28 +00:00
|
|
|
mSystemPrincipal,
|
|
|
|
0,
|
2013-03-17 03:36:37 +00:00
|
|
|
JS::SystemZone,
|
2012-10-31 16:13:28 +00:00
|
|
|
getter_AddRefs(holder));
|
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
|
2013-05-20 12:44:18 +00:00
|
|
|
RootedObject global(aCx, holder->GetJSObject());
|
|
|
|
NS_ENSURE_TRUE(global, nullptr);
|
2012-10-31 16:13:28 +00:00
|
|
|
|
2013-04-04 09:27:38 +00:00
|
|
|
backstagePass->SetGlobalObject(global);
|
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
JSAutoCompartment ac(aCx, global);
|
|
|
|
if (!JS_DefineFunctions(aCx, global, gGlobalFun) ||
|
|
|
|
!JS_DefineProfilingFunctions(aCx, global)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2012-10-30 15:26:12 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
if (aReuseLoaderGlobal) {
|
|
|
|
mLoaderGlobal = holder;
|
|
|
|
}
|
|
|
|
}
|
2012-10-30 19:28:11 +00:00
|
|
|
|
2013-05-20 12:44:18 +00:00
|
|
|
RootedObject obj(aCx, holder->GetJSObject());
|
|
|
|
NS_ENSURE_TRUE(obj, nullptr);
|
2012-10-30 19:28:11 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
JSAutoCompartment ac(aCx, obj);
|
|
|
|
|
|
|
|
if (aReuseLoaderGlobal) {
|
|
|
|
// If we're reusing the loader global, we don't actually use the
|
|
|
|
// global, but rather we use a different object as the 'this' object.
|
2013-04-23 15:48:05 +00:00
|
|
|
obj = JS_NewObject(aCx, &kFakeBackstagePassJSClass, nullptr, nullptr);
|
|
|
|
NS_ENSURE_TRUE(obj, nullptr);
|
2000-10-05 04:15:43 +00:00
|
|
|
}
|
2000-08-16 04:01:02 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
*aRealFile = false;
|
|
|
|
|
2010-06-15 19:38:46 +00: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
|
|
|
|
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
|
|
|
|
nsCOMPtr<nsIFile> testFile;
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
fileURL->GetFile(getter_AddRefs(testFile));
|
|
|
|
}
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
if (testFile) {
|
2012-10-31 16:13:28 +00:00
|
|
|
*aRealFile = true;
|
2005-10-20 16:39:24 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder;
|
2012-10-31 16:13:28 +00:00
|
|
|
rv = xpc->WrapNative(aCx, obj, aComponentFile,
|
2012-06-06 02:08:30 +00:00
|
|
|
NS_GET_IID(nsIFile),
|
2010-06-15 19:38:46 +00:00
|
|
|
getter_AddRefs(locationHolder));
|
2012-10-31 16:13:28 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
2005-10-20 16:39:24 +00:00
|
|
|
|
2013-05-20 12:44:18 +00:00
|
|
|
RootedObject locationObj(aCx, locationHolder->GetJSObject());
|
|
|
|
NS_ENSURE_TRUE(locationObj, nullptr);
|
2010-06-15 19:38:46 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!JS_DefineProperty(aCx, obj, "__LOCATION__",
|
2013-04-23 15:48:05 +00:00
|
|
|
JS::ObjectValue(*locationObj),
|
2012-10-31 16:13:28 +00:00
|
|
|
nullptr, nullptr, 0)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2005-10-20 16:39:24 +00:00
|
|
|
}
|
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString nativePath;
|
2010-06-15 19:38:46 +00:00
|
|
|
rv = aURI->GetSpec(nativePath);
|
2012-10-31 16:13:28 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
2000-01-24 21:28:28 +00:00
|
|
|
|
2011-04-13 22:10:13 +00:00
|
|
|
// Expose the URI from which the script was imported through a special
|
|
|
|
// variable that we insert into the JSM.
|
2012-10-31 16:13:28 +00:00
|
|
|
JSString *exposedUri = JS_NewStringCopyN(aCx, nativePath.get(),
|
|
|
|
nativePath.Length());
|
|
|
|
if (!JS_DefineProperty(aCx, obj, "__URI__",
|
|
|
|
STRING_TO_JSVAL(exposedUri), nullptr, nullptr, 0)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2012-10-30 19:28:11 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
|
|
|
nsIURI *aURI,
|
|
|
|
JSObject **aObject,
|
|
|
|
char **aLocation,
|
2013-04-23 15:48:05 +00:00
|
|
|
bool aPropagateExceptions,
|
|
|
|
JS::MutableHandleValue aException)
|
2012-10-31 16:13:28 +00:00
|
|
|
{
|
2013-04-29 18:16:19 +00:00
|
|
|
JSCLContextHelper cx(mContext);
|
2012-10-31 16:13:28 +00:00
|
|
|
|
|
|
|
JS_AbortIfWrongThread(JS_GetRuntime(cx));
|
|
|
|
|
|
|
|
JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);
|
|
|
|
|
|
|
|
bool realFile = false;
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedObject obj(cx, PrepareObjectForLocation(cx, aComponentFile, aURI,
|
|
|
|
mReuseLoaderGlobal, &realFile));
|
2012-10-31 16:13:28 +00:00
|
|
|
NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
JSAutoCompartment ac(cx, obj);
|
2000-01-24 21:28:28 +00:00
|
|
|
|
2013-04-26 17:50:18 +00:00
|
|
|
RootedScript script(cx);
|
|
|
|
RootedFunction function(cx);
|
2012-10-31 16:13:28 +00:00
|
|
|
|
|
|
|
nsAutoCString nativePath;
|
|
|
|
nsresult rv = aURI->GetSpec(nativePath);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2010-08-12 19:37:52 +00:00
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
// Before compiling the script, first check to see if we have it in
|
2010-08-12 19:37:52 +00:00
|
|
|
// the startupcache. Note: as a rule, startupcache errors are not fatal
|
2005-10-20 16:39:24 +00:00
|
|
|
// to loading the script, since we can always slow-load.
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool writeToCache = false;
|
2010-08-12 19:37:52 +00:00
|
|
|
StartupCache* cache = StartupCache::GetSingleton();
|
2005-10-20 16:39:24 +00:00
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString cachePath(kJSCachePrefix);
|
2011-07-20 07:39:09 +00:00
|
|
|
rv = PathifyURI(aURI, cachePath);
|
2011-07-10 03:21:16 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2010-08-12 19:37:52 +00:00
|
|
|
if (cache) {
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!mReuseLoaderGlobal) {
|
|
|
|
rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal,
|
2013-04-26 17:50:18 +00:00
|
|
|
script.address());
|
2012-10-31 16:13:28 +00:00
|
|
|
} else {
|
|
|
|
rv = ReadCachedFunction(cache, cachePath, cx, mSystemPrincipal,
|
2013-04-26 17:50:18 +00:00
|
|
|
function.address());
|
2012-10-31 16:13:28 +00:00
|
|
|
}
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2010-08-12 19:37:52 +00:00
|
|
|
LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
|
2005-10-20 16:39:24 +00:00
|
|
|
} else {
|
2010-08-12 19:37:52 +00:00
|
|
|
// 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.
|
2011-10-17 14:59:28 +00:00
|
|
|
writeToCache = true;
|
2005-10-20 16:39:24 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-24 18:24:09 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!script && !function) {
|
2010-08-12 19:37:52 +00:00
|
|
|
// The script wasn't in the cache , so compile it now.
|
2005-10-20 16:39:24 +00:00
|
|
|
LOG(("Slow loading %s\n", nativePath.get()));
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
// If aPropagateExceptions is true, then our caller wants us to propagate
|
2008-08-04 23:54:16 +00:00
|
|
|
// any exceptions out to our caller. Ensure that the engine doesn't
|
2008-08-04 17:03:34 +00:00
|
|
|
// eagerly report the exception.
|
2012-01-02 18:05:19 +00:00
|
|
|
uint32_t oldopts = JS_GetOptions(cx);
|
2013-04-23 15:48:05 +00:00
|
|
|
if (aPropagateExceptions)
|
2012-08-07 17:39:47 +00:00
|
|
|
JS_SetOptions(cx, oldopts | JSOPTION_DONT_REPORT_UNCAUGHT);
|
2013-04-23 15:48:05 +00:00
|
|
|
|
2012-08-07 17:39:47 +00:00
|
|
|
JS::CompileOptions options(cx);
|
|
|
|
options.setPrincipals(nsJSPrincipals::get(mSystemPrincipal))
|
2012-10-31 16:13:28 +00:00
|
|
|
.setNoScriptRval(mReuseLoaderGlobal ? false : true)
|
2012-08-07 17:39:47 +00:00
|
|
|
.setVersion(JSVERSION_LATEST)
|
|
|
|
.setFileAndLine(nativePath.get(), 1)
|
2012-10-31 16:13:28 +00:00
|
|
|
.setSourcePolicy(mReuseLoaderGlobal ?
|
|
|
|
JS::CompileOptions::NO_SOURCE :
|
|
|
|
JS::CompileOptions::LAZY_SOURCE);
|
2008-08-04 17:03:34 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
if (realFile) {
|
2005-10-03 23:34:58 +00:00
|
|
|
#ifdef HAVE_PR_MEMMAP
|
2012-08-22 15:56:38 +00:00
|
|
|
int64_t fileSize;
|
2010-06-15 19:38:46 +00:00
|
|
|
rv = aComponentFile->GetFileSize(&fileSize);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return rv;
|
|
|
|
}
|
2005-10-20 16:39:24 +00:00
|
|
|
|
2012-10-25 23:25:57 +00:00
|
|
|
int64_t maxSize = UINT32_MAX;
|
2012-10-03 14:13:19 +00:00
|
|
|
if (fileSize > maxSize) {
|
2010-06-15 19:38:46 +00:00
|
|
|
NS_ERROR("file too large");
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
PRFileDesc *fileHandle;
|
|
|
|
rv = aComponentFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return NS_ERROR_FILE_NOT_FOUND;
|
|
|
|
}
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
// Make sure the file is closed, no matter how we return.
|
|
|
|
FileAutoCloser fileCloser(fileHandle);
|
2005-10-20 16:39:24 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
PRFileMap *map = PR_CreateFileMap(fileHandle, fileSize,
|
|
|
|
PR_PROT_READONLY);
|
|
|
|
if (!map) {
|
|
|
|
NS_ERROR("Failed to create file map");
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
// Make sure the file map is closed, no matter how we return.
|
|
|
|
FileMapAutoCloser mapCloser(map);
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2012-10-12 17:29:11 +00:00
|
|
|
uint32_t fileSize32 = fileSize;
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32));
|
|
|
|
if (!buf) {
|
|
|
|
NS_WARNING("Failed to map file");
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!mReuseLoaderGlobal) {
|
2013-04-23 15:48:05 +00:00
|
|
|
script = JS::Compile(cx, obj, options, buf,
|
2012-10-31 16:13:28 +00:00
|
|
|
fileSize32);
|
|
|
|
} else {
|
2013-04-23 15:48:05 +00:00
|
|
|
function = JS::CompileFunction(cx, obj, options,
|
2012-10-31 16:13:28 +00:00
|
|
|
nullptr, 0, nullptr,
|
|
|
|
buf, fileSize32);
|
|
|
|
}
|
2010-11-02 00:33:22 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
PR_MemUnmap(buf, fileSize32);
|
2005-10-03 23:34:58 +00:00
|
|
|
|
|
|
|
#else /* HAVE_PR_MEMMAP */
|
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
/**
|
2011-12-16 19:08:59 +00:00
|
|
|
* No memmap implementation, so fall back to
|
|
|
|
* reading in the file
|
2010-06-15 19:38:46 +00:00
|
|
|
*/
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
FILE *fileHandle;
|
|
|
|
rv = aComponentFile->OpenANSIFileDesc("r", &fileHandle);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return NS_ERROR_FILE_NOT_FOUND;
|
|
|
|
}
|
2005-10-20 16:39:24 +00:00
|
|
|
|
2011-12-16 19:08:59 +00:00
|
|
|
// Ensure file fclose
|
|
|
|
ANSIFileAutoCloser fileCloser(fileHandle);
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
int64_t len;
|
2011-12-16 19:08:59 +00:00
|
|
|
rv = aComponentFile->GetFileSize(&len);
|
|
|
|
if (NS_FAILED(rv) || len < 0) {
|
|
|
|
NS_WARNING("Failed to get file size");
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *buf = (char *) malloc(len * sizeof(char));
|
|
|
|
if (!buf) {
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t rlen = fread(buf, 1, len, fileHandle);
|
2012-08-22 15:56:38 +00:00
|
|
|
if (rlen != (uint64_t)len) {
|
2011-12-16 19:08:59 +00:00
|
|
|
free(buf);
|
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
NS_WARNING("Failed to read file");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2012-10-31 16:13:28 +00:00
|
|
|
|
|
|
|
if (!mReuseLoaderGlobal) {
|
2013-04-23 15:48:05 +00:00
|
|
|
script = JS::Compile(cx, obj, options, buf,
|
2012-10-31 16:13:28 +00:00
|
|
|
fileSize32);
|
|
|
|
} else {
|
2013-04-23 15:48:05 +00:00
|
|
|
function = JS::CompileFunction(cx, obj, options,
|
2012-10-31 16:13:28 +00:00
|
|
|
nullptr, 0, nullptr,
|
|
|
|
buf, fileSize32);
|
|
|
|
}
|
2011-12-16 19:08:59 +00:00
|
|
|
|
|
|
|
free(buf);
|
2005-10-03 23:34:58 +00:00
|
|
|
|
2008-08-04 18:12:51 +00:00
|
|
|
#endif /* HAVE_PR_MEMMAP */
|
2010-06-15 19:38:46 +00:00
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIChannel> scriptChannel;
|
|
|
|
rv = ioService->NewChannelFromURI(aURI, getter_AddRefs(scriptChannel));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIInputStream> scriptStream;
|
|
|
|
rv = scriptChannel->Open(getter_AddRefs(scriptStream));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2008-08-04 17:03:34 +00:00
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
uint64_t len64;
|
|
|
|
uint32_t bytesRead;
|
2010-06-15 19:38:46 +00:00
|
|
|
|
2012-08-11 02:44:11 +00:00
|
|
|
rv = scriptStream->Available(&len64);
|
2010-06-15 19:38:46 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2012-09-28 06:57:33 +00:00
|
|
|
NS_ENSURE_TRUE(len64 < UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
|
2012-08-11 02:44:11 +00:00
|
|
|
if (!len64)
|
2010-06-15 19:38:46 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t len = (uint32_t)len64;
|
2010-06-15 19:38:46 +00:00
|
|
|
|
|
|
|
/* malloc an internal buf the size of the file */
|
|
|
|
nsAutoArrayPtr<char> buf(new char[len + 1]);
|
|
|
|
if (!buf)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
/* read the file in one swoop */
|
|
|
|
rv = scriptStream->Read(buf, len, &bytesRead);
|
|
|
|
if (bytesRead != len)
|
|
|
|
return NS_BASE_STREAM_OSERROR;
|
|
|
|
|
|
|
|
buf[len] = '\0';
|
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!mReuseLoaderGlobal) {
|
2013-04-23 15:48:05 +00:00
|
|
|
script = JS::Compile(cx, obj, options, buf, bytesRead);
|
2012-10-31 16:13:28 +00:00
|
|
|
} else {
|
2013-04-23 15:48:05 +00:00
|
|
|
function = JS::CompileFunction(cx, obj, options,
|
2012-10-31 16:13:28 +00:00
|
|
|
nullptr, 0, nullptr,
|
|
|
|
buf, bytesRead);
|
|
|
|
}
|
2010-06-15 19:38:46 +00:00
|
|
|
}
|
2008-08-04 17:03:34 +00:00
|
|
|
// Propagate the exception, if one exists. Also, don't leave the stale
|
|
|
|
// exception on this context.
|
2011-03-25 21:31:14 +00:00
|
|
|
JS_SetOptions(cx, oldopts);
|
2013-04-23 15:48:05 +00:00
|
|
|
if (!script && !function && aPropagateExceptions) {
|
|
|
|
JS_GetPendingException(cx, aException.address());
|
2011-03-25 21:31:14 +00:00
|
|
|
JS_ClearPendingException(cx);
|
2008-08-04 17:03:34 +00:00
|
|
|
}
|
2005-10-20 16:39:24 +00:00
|
|
|
}
|
2000-01-24 21:28:28 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!script && !function) {
|
2005-10-20 16:39:24 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
1999-09-07 20:30:25 +00:00
|
|
|
|
2010-08-12 19:37:52 +00:00
|
|
|
if (writeToCache) {
|
2011-10-14 17:52:47 +00:00
|
|
|
// We successfully compiled the script, so cache it.
|
2012-10-31 16:13:28 +00:00
|
|
|
if (script) {
|
|
|
|
rv = WriteCachedScript(cache, cachePath, cx, mSystemPrincipal,
|
|
|
|
script);
|
|
|
|
} else {
|
|
|
|
rv = WriteCachedFunction(cache, cachePath, cx, mSystemPrincipal,
|
|
|
|
function);
|
|
|
|
}
|
2005-10-20 16:39:24 +00:00
|
|
|
|
|
|
|
// Don't treat failure to write as fatal, since we might be working
|
2010-08-12 19:37:52 +00:00
|
|
|
// with a read-only cache.
|
2005-10-20 16:39:24 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2010-08-12 19:37:52 +00:00
|
|
|
LOG(("Successfully wrote to cache\n"));
|
2005-10-20 16:39:24 +00:00
|
|
|
} else {
|
2010-08-12 19:37:52 +00:00
|
|
|
LOG(("Failed to write to cache\n"));
|
2003-03-23 07:22:18 +00:00
|
|
|
}
|
1999-09-07 20:30:25 +00:00
|
|
|
}
|
2005-10-20 16:39:24 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
// Assign aObject here so that it's available to recursive imports.
|
2007-06-20 06:29:49 +00:00
|
|
|
// See bug 384168.
|
2012-10-31 16:13:28 +00:00
|
|
|
*aObject = obj;
|
2007-06-20 06:29:49 +00:00
|
|
|
|
2012-11-13 19:13:27 +00:00
|
|
|
JSScript* tableScript = script;
|
|
|
|
if (!tableScript) {
|
|
|
|
tableScript = JS_GetFunctionScript(cx, function);
|
|
|
|
MOZ_ASSERT(tableScript);
|
|
|
|
}
|
|
|
|
|
|
|
|
mThisObjects.Put(tableScript, obj);
|
|
|
|
|
2012-01-02 18:05:19 +00:00
|
|
|
uint32_t oldopts = JS_GetOptions(cx);
|
2013-04-23 15:48:05 +00:00
|
|
|
JS_SetOptions(cx, oldopts | (aPropagateExceptions ? JSOPTION_DONT_REPORT_UNCAUGHT : 0));
|
2012-10-31 16:13:28 +00:00
|
|
|
bool ok = false;
|
|
|
|
if (script) {
|
|
|
|
ok = JS_ExecuteScriptVersion(cx, obj, script, NULL, JSVERSION_LATEST);
|
|
|
|
} else {
|
|
|
|
jsval rval;
|
|
|
|
ok = JS_CallFunction(cx, obj, function, 0, nullptr, &rval);
|
|
|
|
}
|
2011-12-28 16:55:11 +00:00
|
|
|
JS_SetOptions(cx, oldopts);
|
|
|
|
|
|
|
|
if (!ok) {
|
2013-04-23 15:48:05 +00:00
|
|
|
if (aPropagateExceptions) {
|
|
|
|
JS_GetPendingException(cx, aException.address());
|
2011-12-28 16:55:11 +00:00
|
|
|
JS_ClearPendingException(cx);
|
|
|
|
}
|
2012-10-31 16:13:28 +00:00
|
|
|
*aObject = nullptr;
|
2005-10-20 16:39:24 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2003-03-23 07:22:18 +00:00
|
|
|
}
|
1999-09-07 20:30:25 +00:00
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
/* Freed when we remove from the table. */
|
2010-06-15 19:38:46 +00:00
|
|
|
*aLocation = ToNewCString(nativePath);
|
2007-06-20 06:29:49 +00:00
|
|
|
if (!*aLocation) {
|
2012-10-31 16:13:28 +00:00
|
|
|
*aObject = nullptr;
|
2005-12-13 17:55:43 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2007-06-20 06:29:49 +00:00
|
|
|
}
|
2000-09-21 04:30:32 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
JS_AddNamedObjectRoot(cx, aObject, *aLocation);
|
2005-10-20 16:39:24 +00:00
|
|
|
return NS_OK;
|
1999-09-07 06:18:08 +00:00
|
|
|
}
|
|
|
|
|
2010-06-11 20:13:26 +00:00
|
|
|
/* static */ PLDHashOperator
|
2011-11-08 17:08:49 +00:00
|
|
|
mozJSComponentLoader::ClearModules(const nsACString& key, ModuleEntry*& entry, void* cx)
|
2010-06-11 20:13:26 +00:00
|
|
|
{
|
|
|
|
entry->Clear();
|
|
|
|
return PL_DHASH_REMOVE;
|
|
|
|
}
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
void
|
|
|
|
mozJSComponentLoader::UnloadModules()
|
2005-12-03 15:27:17 +00:00
|
|
|
{
|
2011-10-17 14:59:28 +00:00
|
|
|
mInitialized = false;
|
2005-12-03 15:27:17 +00:00
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
if (mLoaderGlobal) {
|
|
|
|
MOZ_ASSERT(mReuseLoaderGlobal, "How did this happen?");
|
|
|
|
|
2013-05-20 12:44:18 +00:00
|
|
|
RootedObject global(mContext, mLoaderGlobal->GetJSObject());
|
|
|
|
if (global) {
|
2012-10-31 16:13:28 +00:00
|
|
|
JS_SetAllNonReservedSlotsToUndefined(mContext, global);
|
|
|
|
} else {
|
|
|
|
NS_WARNING("Going to leak!");
|
|
|
|
}
|
|
|
|
|
|
|
|
mLoaderGlobal = nullptr;
|
|
|
|
}
|
|
|
|
|
2007-06-20 06:29:49 +00:00
|
|
|
mInProgressImports.Clear();
|
2007-05-15 23:27:40 +00:00
|
|
|
mImports.Clear();
|
2012-11-13 19:13:27 +00:00
|
|
|
mThisObjects.Clear();
|
2010-06-11 20:13:26 +00:00
|
|
|
|
|
|
|
mModules.Enumerate(ClearModules, NULL);
|
1999-11-10 00:34:26 +00:00
|
|
|
|
2005-12-13 17:55:43 +00:00
|
|
|
// Destroying our context will force a GC.
|
|
|
|
JS_DestroyContext(mContext);
|
2012-07-30 14:20:58 +00:00
|
|
|
mContext = nullptr;
|
2003-03-23 07:22:18 +00:00
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
mRuntimeService = nullptr;
|
2001-03-27 05:35:52 +00:00
|
|
|
#ifdef DEBUG_shaver_off
|
1999-09-07 06:18:08 +00:00
|
|
|
fprintf(stderr, "mJCL: UnloadAll(%d)\n", aWhen);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-05-15 23:27:40 +00:00
|
|
|
NS_IMETHODIMP
|
2011-12-18 10:09:16 +00:00
|
|
|
mozJSComponentLoader::Import(const nsACString& registryLocation,
|
2013-04-23 15:48:05 +00:00
|
|
|
const JS::Value& targetValArg,
|
2011-12-18 10:09:16 +00:00
|
|
|
JSContext* cx,
|
2012-08-22 15:56:38 +00:00
|
|
|
uint8_t optionalArgc,
|
2011-12-18 10:09:16 +00:00
|
|
|
JS::Value* retval)
|
2007-05-15 23:27:40 +00:00
|
|
|
{
|
2012-10-25 23:10:53 +00:00
|
|
|
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
2013-04-23 15:48:05 +00:00
|
|
|
|
|
|
|
RootedValue targetVal(cx, targetValArg);
|
|
|
|
RootedObject targetObject(cx, nullptr);
|
2011-12-18 10:09:16 +00:00
|
|
|
if (optionalArgc) {
|
2007-05-15 23:27:40 +00:00
|
|
|
// The caller passed in the optional second argument. Get it.
|
2012-07-23 14:47:18 +00: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-04-23 15:48:05 +00:00
|
|
|
!WrapperFactory::WaiveXrayAndWrap(cx, targetVal.address()))
|
2012-07-23 14:47:18 +00: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|.
|
2011-12-18 10:09:16 +00:00
|
|
|
return ReportOnCaller(cx, ERROR_SCOPE_OBJ,
|
2012-07-23 14:47:18 +00:00
|
|
|
PromiseFlatCString(registryLocation).get());
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
} else {
|
2012-11-13 19:13:27 +00:00
|
|
|
nsresult rv = FindTargetObject(cx, &targetObject);
|
2011-12-18 10:09:16 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2012-08-22 01:42:53 +00:00
|
|
|
Maybe<JSAutoCompartment> ac;
|
|
|
|
if (targetObject) {
|
|
|
|
ac.construct(cx, targetObject);
|
2010-10-10 22:42:04 +00:00
|
|
|
}
|
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedObject global(cx);
|
|
|
|
nsresult rv = ImportInto(registryLocation, targetObject, cx, &global);
|
2010-10-10 22:42:04 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
if (global) {
|
|
|
|
if (!JS_WrapObject(cx, global.address())) {
|
|
|
|
NS_ERROR("can't wrap return value");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2007-05-15 23:27:40 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
*retval = JS::ObjectValue(*global);
|
|
|
|
}
|
2007-05-15 23:27:40 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* [noscript] JSObjectPtr importInto(in AUTF8String registryLocation,
|
|
|
|
in JSObjectPtr targetObj); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
mozJSComponentLoader::ImportInto(const nsACString & aLocation,
|
2013-04-23 15:48:05 +00:00
|
|
|
JSObject *aTargetObj,
|
2008-01-15 15:50:57 +00:00
|
|
|
nsAXPCNativeCallContext * cc,
|
2013-04-23 15:48:05 +00:00
|
|
|
JSObject **_retval)
|
2011-12-18 10:09:16 +00:00
|
|
|
{
|
|
|
|
JSContext *callercx;
|
|
|
|
nsresult rv = cc->GetJSContext(&callercx);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2013-04-23 15:48:05 +00:00
|
|
|
|
|
|
|
RootedObject targetObject(callercx, aTargetObj);
|
|
|
|
RootedObject global(callercx);
|
|
|
|
rv = ImportInto(aLocation, targetObject, callercx, &global);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
*_retval = global;
|
|
|
|
return NS_OK;
|
2011-12-18 10:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2013-04-23 15:48:05 +00:00
|
|
|
mozJSComponentLoader::ImportInto(const nsACString &aLocation,
|
|
|
|
JS::HandleObject targetObj,
|
|
|
|
JSContext *callercx,
|
|
|
|
JS::MutableHandleObject vp)
|
2007-05-15 23:27:40 +00:00
|
|
|
{
|
2013-04-23 15:48:05 +00:00
|
|
|
vp.set(nullptr);
|
2007-05-15 23:27:40 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
nsresult rv;
|
2007-05-15 23:27:40 +00:00
|
|
|
if (!mInitialized) {
|
|
|
|
rv = ReallyInit();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2007-06-10 21:13:18 +00:00
|
|
|
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
2007-05-15 23:27:40 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-06-10 21:13:18 +00:00
|
|
|
|
2007-12-01 06:45:04 +00:00
|
|
|
// Get the URI.
|
2007-06-10 21:13:18 +00:00
|
|
|
nsCOMPtr<nsIURI> resURI;
|
2012-07-30 14:20:58 +00:00
|
|
|
rv = ioService->NewURI(aLocation, nullptr, nullptr, getter_AddRefs(resURI));
|
2010-06-15 19:38:46 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-06-10 21:13:18 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
// figure out the resolved URI
|
|
|
|
nsCOMPtr<nsIChannel> scriptChannel;
|
|
|
|
rv = ioService->NewChannelFromURI(resURI, getter_AddRefs(scriptChannel));
|
2007-12-01 06:45:04 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
|
2007-06-10 21:13:18 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
nsCOMPtr<nsIURI> resolvedURI;
|
|
|
|
rv = scriptChannel->GetURI(getter_AddRefs(resolvedURI));
|
2007-05-15 23:27:40 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
// get the JAR if there is one
|
|
|
|
nsCOMPtr<nsIJARURI> jarURI;
|
|
|
|
jarURI = do_QueryInterface(resolvedURI, &rv);
|
|
|
|
nsCOMPtr<nsIFileURL> baseFileURL;
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
nsCOMPtr<nsIURI> baseURI;
|
2011-12-08 10:03:36 +00:00
|
|
|
while (jarURI) {
|
|
|
|
jarURI->GetJARFile(getter_AddRefs(baseURI));
|
|
|
|
jarURI = do_QueryInterface(baseURI, &rv);
|
|
|
|
}
|
2010-06-15 19:38:46 +00:00
|
|
|
baseFileURL = do_QueryInterface(baseURI, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else {
|
|
|
|
baseFileURL = do_QueryInterface(resolvedURI, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
nsCOMPtr<nsIFile> sourceFile;
|
|
|
|
rv = baseFileURL->GetFile(getter_AddRefs(sourceFile));
|
2007-05-15 23:27:40 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2010-06-15 19:38:46 +00:00
|
|
|
|
2012-06-06 02:08:30 +00:00
|
|
|
nsCOMPtr<nsIFile> sourceLocalFile;
|
2010-06-15 19:38:46 +00:00
|
|
|
sourceLocalFile = do_QueryInterface(sourceFile, &rv);
|
2007-05-15 23:27:40 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString key;
|
2011-11-08 17:08:49 +00:00
|
|
|
rv = resolvedURI->GetSpec(key);
|
2010-06-15 19:38:46 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-05-15 23:27:40 +00:00
|
|
|
|
|
|
|
ModuleEntry* mod;
|
|
|
|
nsAutoPtr<ModuleEntry> newEntry;
|
2010-06-15 19:38:46 +00:00
|
|
|
if (!mImports.Get(key, &mod) && !mInProgressImports.Get(key, &mod)) {
|
2007-05-15 23:27:40 +00:00
|
|
|
newEntry = new ModuleEntry;
|
2012-05-18 17:30:49 +00:00
|
|
|
if (!newEntry)
|
2007-05-15 23:27:40 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2012-05-18 17:30:49 +00:00
|
|
|
mInProgressImports.Put(key, newEntry);
|
2007-06-20 06:29:49 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedValue exception(callercx);
|
2012-10-31 16:13:28 +00:00
|
|
|
rv = ObjectForLocation(sourceLocalFile, resURI, &newEntry->obj,
|
2013-04-23 15:48:05 +00:00
|
|
|
&newEntry->location, true, &exception);
|
2007-06-20 06:29:49 +00:00
|
|
|
|
2010-06-15 19:38:46 +00:00
|
|
|
mInProgressImports.Remove(key);
|
2007-06-20 06:29:49 +00:00
|
|
|
|
2007-05-15 23:27:40 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2013-04-23 15:48:05 +00:00
|
|
|
if (!exception.isUndefined()) {
|
2008-08-04 17:03:34 +00:00
|
|
|
// An exception was thrown during compilation. Propagate it
|
|
|
|
// out to our caller so they can report it.
|
2013-04-23 15:48:05 +00:00
|
|
|
if (!JS_WrapValue(callercx, exception.address()))
|
2012-02-23 21:50:01 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2013-04-23 15:48:05 +00:00
|
|
|
JS_SetPendingException(callercx, exception);
|
2008-08-04 17:03:34 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Something failed, but we don't know what it is, guess.
|
2008-08-05 01:04:19 +00:00
|
|
|
return NS_ERROR_FILE_NOT_FOUND;
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
2007-06-20 06:29:49 +00:00
|
|
|
|
2012-05-16 17:42:10 +00:00
|
|
|
// Set the location information for the new global, so that tools like
|
|
|
|
// about:memory may use that information
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!mReuseLoaderGlobal) {
|
|
|
|
xpc::SetLocationForGlobal(newEntry->obj, aLocation);
|
|
|
|
}
|
2012-05-16 17:42:10 +00:00
|
|
|
|
2007-05-15 23:27:40 +00:00
|
|
|
mod = newEntry;
|
|
|
|
}
|
|
|
|
|
2012-10-31 16:13:28 +00:00
|
|
|
NS_ASSERTION(mod->obj, "Import table contains entry with no object");
|
2013-04-23 15:48:05 +00:00
|
|
|
vp.set(mod->obj);
|
2007-05-15 23:27:40 +00:00
|
|
|
|
|
|
|
if (targetObj) {
|
2013-04-29 18:16:19 +00:00
|
|
|
JSCLContextHelper cxhelper(mContext);
|
2012-10-31 16:13:28 +00:00
|
|
|
JSAutoCompartment ac(mContext, mod->obj);
|
2007-09-19 00:26:39 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedValue symbols(mContext);
|
2012-10-31 16:13:28 +00:00
|
|
|
if (!JS_GetProperty(mContext, mod->obj,
|
2013-04-23 15:48:05 +00:00
|
|
|
"EXPORTED_SYMBOLS", symbols.address())) {
|
2009-02-18 04:11:09 +00:00
|
|
|
return ReportOnCaller(cxhelper, ERROR_NOT_PRESENT,
|
2007-05-15 23:27:40 +00:00
|
|
|
PromiseFlatCString(aLocation).get());
|
|
|
|
}
|
|
|
|
|
2012-05-11 15:46:26 +00:00
|
|
|
if (!symbols.isObject() ||
|
|
|
|
!JS_IsArrayObject(mContext, &symbols.toObject())) {
|
2009-02-18 04:11:09 +00:00
|
|
|
return ReportOnCaller(cxhelper, ERROR_NOT_AN_ARRAY,
|
2007-05-15 23:27:40 +00:00
|
|
|
PromiseFlatCString(aLocation).get());
|
|
|
|
}
|
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedObject symbolsObj(mContext, &symbols.toObject());
|
2012-05-11 15:46:26 +00:00
|
|
|
|
2007-05-15 23:27:40 +00:00
|
|
|
// Iterate over symbols array, installing symbols on targetObj:
|
|
|
|
|
2012-03-06 23:52:55 +00:00
|
|
|
uint32_t symbolCount = 0;
|
2007-05-15 23:27:40 +00:00
|
|
|
if (!JS_GetArrayLength(mContext, symbolsObj, &symbolCount)) {
|
2009-02-18 04:11:09 +00:00
|
|
|
return ReportOnCaller(cxhelper, ERROR_GETTING_ARRAY_LENGTH,
|
2007-05-15 23:27:40 +00:00
|
|
|
PromiseFlatCString(aLocation).get());
|
|
|
|
}
|
2007-06-18 15:36:16 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString logBuffer;
|
2007-06-18 15:36:16 +00:00
|
|
|
#endif
|
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
RootedValue value(mContext);
|
|
|
|
RootedId symbolId(mContext);
|
2012-03-06 23:52:55 +00:00
|
|
|
for (uint32_t i = 0; i < symbolCount; ++i) {
|
2013-04-23 15:48:05 +00:00
|
|
|
if (!JS_GetElement(mContext, symbolsObj, i, value.address()) ||
|
|
|
|
!value.isString() ||
|
|
|
|
!JS_ValueToId(mContext, value, symbolId.address())) {
|
2009-02-18 04:11:09 +00:00
|
|
|
return ReportOnCaller(cxhelper, ERROR_ARRAY_ELEMENT,
|
2007-05-15 23:27:40 +00:00
|
|
|
PromiseFlatCString(aLocation).get(), i);
|
|
|
|
}
|
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
if (!JS_GetPropertyById(mContext, mod->obj, symbolId, value.address())) {
|
2010-11-11 20:40:29 +00:00
|
|
|
JSAutoByteString bytes(mContext, JSID_TO_STRING(symbolId));
|
|
|
|
if (!bytes)
|
|
|
|
return NS_ERROR_FAILURE;
|
2009-02-18 04:11:09 +00:00
|
|
|
return ReportOnCaller(cxhelper, ERROR_GETTING_SYMBOL,
|
2007-05-15 23:27:40 +00:00
|
|
|
PromiseFlatCString(aLocation).get(),
|
2010-11-11 20:40:29 +00:00
|
|
|
bytes.ptr());
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
|
2012-08-22 01:42:53 +00:00
|
|
|
JSAutoCompartment target_ac(mContext, targetObj);
|
2010-09-29 17:00:52 +00:00
|
|
|
|
2013-04-23 15:48:05 +00:00
|
|
|
if (!JS_WrapValue(mContext, value.address()) ||
|
|
|
|
!JS_SetPropertyById(mContext, targetObj, symbolId, value.address())) {
|
2010-11-11 20:40:29 +00:00
|
|
|
JSAutoByteString bytes(mContext, JSID_TO_STRING(symbolId));
|
|
|
|
if (!bytes)
|
|
|
|
return NS_ERROR_FAILURE;
|
2009-02-18 04:11:09 +00:00
|
|
|
return ReportOnCaller(cxhelper, ERROR_SETTING_SYMBOL,
|
2007-05-15 23:27:40 +00:00
|
|
|
PromiseFlatCString(aLocation).get(),
|
2010-11-11 20:40:29 +00:00
|
|
|
bytes.ptr());
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (i == 0) {
|
2007-06-18 15:36:16 +00:00
|
|
|
logBuffer.AssignLiteral("Installing symbols [ ");
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
2010-11-11 20:40:29 +00:00
|
|
|
JSAutoByteString bytes(mContext, JSID_TO_STRING(symbolId));
|
|
|
|
if (!!bytes)
|
|
|
|
logBuffer.Append(bytes.ptr());
|
2007-06-18 15:36:16 +00:00
|
|
|
logBuffer.AppendLiteral(" ");
|
2007-05-15 23:27:40 +00:00
|
|
|
if (i == symbolCount - 1) {
|
2011-08-15 22:56:46 +00:00
|
|
|
LOG(("%s] from %s\n", logBuffer.get(),
|
2011-10-14 17:52:48 +00:00
|
|
|
PromiseFlatCString(aLocation).get()));
|
2007-05-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cache this module for later
|
|
|
|
if (newEntry) {
|
2012-05-18 17:30:49 +00:00
|
|
|
mImports.Put(key, newEntry);
|
2007-05-15 23:27:40 +00:00
|
|
|
newEntry.forget();
|
|
|
|
}
|
2011-10-14 17:52:47 +00:00
|
|
|
|
2007-05-15 23:27:40 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-06-15 18:08:43 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
mozJSComponentLoader::Unload(const nsACString & aLocation)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (!mInitialized) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Get the URI.
|
|
|
|
nsCOMPtr<nsIURI> resURI;
|
2012-07-30 14:20:58 +00:00
|
|
|
rv = ioService->NewURI(aLocation, nullptr, nullptr, getter_AddRefs(resURI));
|
2011-06-15 18:08:43 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// figure out the resolved URI
|
|
|
|
nsCOMPtr<nsIChannel> scriptChannel;
|
|
|
|
rv = ioService->NewChannelFromURI(resURI, getter_AddRefs(scriptChannel));
|
|
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> resolvedURI;
|
|
|
|
rv = scriptChannel->GetURI(getter_AddRefs(resolvedURI));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2012-09-02 02:35:17 +00:00
|
|
|
nsAutoCString key;
|
2011-11-08 17:08:49 +00:00
|
|
|
rv = resolvedURI->GetSpec(key);
|
2011-06-15 18:08:43 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
ModuleEntry* mod;
|
|
|
|
if (mImports.Get(key, &mod)) {
|
|
|
|
mImports.Remove(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-10-20 16:39:24 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
mozJSComponentLoader::Observe(nsISupports *subject, const char *topic,
|
|
|
|
const PRUnichar *data)
|
|
|
|
{
|
2010-08-12 19:37:52 +00:00
|
|
|
if (!strcmp(topic, "xpcom-shutdown-loaders")) {
|
2005-12-13 17:55:43 +00:00
|
|
|
UnloadModules();
|
2011-10-14 17:52:48 +00:00
|
|
|
} else {
|
2005-12-13 17:55:43 +00:00
|
|
|
NS_ERROR("Unexpected observer topic.");
|
2005-10-20 16:39:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-06-11 20:13:26 +00: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);
|
|
|
|
NS_ASSERTION(self.getfactoryobj, "Handing out an uninitialized module?");
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFactory> f;
|
|
|
|
nsresult rv = self.getfactoryobj->Get(*entry.cid, getter_AddRefs(f));
|
|
|
|
if (NS_FAILED(rv))
|
2013-06-12 07:00:09 +00:00
|
|
|
return nullptr;
|
2010-06-11 20:13:26 +00:00
|
|
|
|
|
|
|
return f.forget();
|
|
|
|
}
|
|
|
|
|
1999-09-30 21:47:04 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2013-04-29 18:16:19 +00:00
|
|
|
JSCLContextHelper::JSCLContextHelper(JSContext* aCx)
|
|
|
|
: mContext(aCx)
|
|
|
|
, mBuf(nullptr)
|
2000-09-21 04:30:32 +00:00
|
|
|
{
|
2013-04-29 18:16:19 +00:00
|
|
|
mPusher.Push(mContext);
|
2011-07-18 21:54:48 +00:00
|
|
|
JS_BeginRequest(mContext);
|
2000-09-21 04:30:32 +00:00
|
|
|
}
|
|
|
|
|
2011-05-13 15:56:26 +00:00
|
|
|
JSCLContextHelper::~JSCLContextHelper()
|
2000-09-21 04:30:32 +00:00
|
|
|
{
|
2013-04-29 18:16:19 +00:00
|
|
|
JS_EndRequest(mContext);
|
|
|
|
mPusher.Pop();
|
|
|
|
JSContext *restoredCx = nsContentUtils::GetCurrentJSContext();
|
|
|
|
if (restoredCx && mBuf) {
|
|
|
|
JS_ReportError(restoredCx, mBuf);
|
2011-05-13 15:56:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mBuf) {
|
|
|
|
JS_smprintf_free(mBuf);
|
2009-02-18 04:11:09 +00:00
|
|
|
}
|
2011-05-13 15:56:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
JSCLContextHelper::reportErrorAfterPop(char *buf)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!mBuf, "Already called reportErrorAfterPop");
|
|
|
|
mBuf = buf;
|
2009-02-18 04:11:09 +00:00
|
|
|
}
|