summaryrefslogtreecommitdiffstats
path: root/xpcom/glue/standalone
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/glue/standalone')
-rw-r--r--xpcom/glue/standalone/moz.build58
-rw-r--r--xpcom/glue/standalone/nsXPCOMGlue.cpp927
-rw-r--r--xpcom/glue/standalone/nsXPCOMGlue.h49
-rw-r--r--xpcom/glue/standalone/staticruntime/moz.build50
4 files changed, 1084 insertions, 0 deletions
diff --git a/xpcom/glue/standalone/moz.build b/xpcom/glue/standalone/moz.build
new file mode 100644
index 000000000..fd91fa0bb
--- /dev/null
+++ b/xpcom/glue/standalone/moz.build
@@ -0,0 +1,58 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# On win we build two glue libs - glue linked to crt dlls here and in staticruntime we build
+# a statically linked glue lib.
+if CONFIG['OS_ARCH'] == 'WINNT':
+ DIRS += ['staticruntime']
+
+include('../objs.mozbuild')
+
+SOURCES += xpcom_glue_src_cppsrcs
+
+SOURCES += [
+ '../nsStringAPI.cpp',
+ 'nsXPCOMGlue.cpp',
+]
+
+Library('xpcomglue')
+
+EXPORTS += [
+ 'nsXPCOMGlue.h',
+]
+
+SDK_LIBRARY = True
+
+FORCE_STATIC_LIB = True
+
+if CONFIG['_MSC_VER']:
+ DEFINES['_USE_ANSI_CPP'] = True
+ # Don't include directives about which CRT to use
+ CFLAGS += ['-Zl']
+ CXXFLAGS += ['-Zl']
+
+DEFINES['XPCOM_GLUE'] = True
+
+LOCAL_INCLUDES += [
+ '../../build',
+ '../../threads',
+]
+
+# Don't use STL wrappers here (i.e. wrapped <new>); they require mozalloc
+DISABLE_STL_WRAPPING = True
+
+# Include fallible for third party code using the xpcom glue
+USE_LIBS += [
+ 'fallible',
+]
+
+# Force to build a static library only
+NO_EXPAND_LIBS = True
+
+DIST_INSTALL = True
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
+ CXXFLAGS += CONFIG['GLIB_CFLAGS']
diff --git a/xpcom/glue/standalone/nsXPCOMGlue.cpp b/xpcom/glue/standalone/nsXPCOMGlue.cpp
new file mode 100644
index 000000000..b657d7050
--- /dev/null
+++ b/xpcom/glue/standalone/nsXPCOMGlue.cpp
@@ -0,0 +1,927 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsXPCOMGlue.h"
+
+#include "nspr.h"
+#include "nsDebug.h"
+#include "nsIServiceManager.h"
+#include "nsXPCOMPrivate.h"
+#include "nsCOMPtr.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mozilla/FileUtils.h"
+#include "mozilla/Sprintf.h"
+
+using namespace mozilla;
+
+#define XPCOM_DEPENDENT_LIBS_LIST "dependentlibs.list"
+
+static XPCOMFunctions xpcomFunctions;
+static bool do_preload = false;
+
+#if defined(XP_WIN)
+#define READ_TEXTMODE L"rt"
+#else
+#define READ_TEXTMODE "r"
+#endif
+
+#if defined(XP_WIN)
+#include <windows.h>
+#include <mbstring.h>
+
+typedef HINSTANCE LibHandleType;
+
+static LibHandleType
+GetLibHandle(pathstr_t aDependentLib)
+{
+ LibHandleType libHandle =
+ LoadLibraryExW(aDependentLib, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
+
+#ifdef DEBUG
+ if (!libHandle) {
+ DWORD err = GetLastError();
+ LPWSTR lpMsgBuf;
+ FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPWSTR)&lpMsgBuf,
+ 0,
+ nullptr
+ );
+ wprintf(L"Error loading %ls: %s\n", aDependentLib, lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ }
+#endif
+
+ return libHandle;
+}
+
+static NSFuncPtr
+GetSymbol(LibHandleType aLibHandle, const char* aSymbol)
+{
+ return (NSFuncPtr)GetProcAddress(aLibHandle, aSymbol);
+}
+
+static void
+CloseLibHandle(LibHandleType aLibHandle)
+{
+ FreeLibrary(aLibHandle);
+}
+
+#else
+#include <dlfcn.h>
+
+#if defined(MOZ_LINKER) && !defined(ANDROID)
+extern "C" {
+NS_HIDDEN __typeof(dlopen) __wrap_dlopen;
+NS_HIDDEN __typeof(dlsym) __wrap_dlsym;
+NS_HIDDEN __typeof(dlclose) __wrap_dlclose;
+}
+
+#define dlopen __wrap_dlopen
+#define dlsym __wrap_dlsym
+#define dlclose __wrap_dlclose
+#endif
+
+typedef void* LibHandleType;
+
+static LibHandleType
+GetLibHandle(pathstr_t aDependentLib)
+{
+ LibHandleType libHandle = dlopen(aDependentLib,
+ RTLD_GLOBAL | RTLD_LAZY
+#ifdef XP_MACOSX
+ | RTLD_FIRST
+#endif
+ );
+ if (!libHandle) {
+ fprintf(stderr, "XPCOMGlueLoad error for file %s:\n%s\n", aDependentLib,
+ dlerror());
+ }
+ return libHandle;
+}
+
+static NSFuncPtr
+GetSymbol(LibHandleType aLibHandle, const char* aSymbol)
+{
+ return (NSFuncPtr)dlsym(aLibHandle, aSymbol);
+}
+
+static void
+CloseLibHandle(LibHandleType aLibHandle)
+{
+ dlclose(aLibHandle);
+}
+#endif
+
+struct DependentLib
+{
+ LibHandleType libHandle;
+ DependentLib* next;
+};
+
+static DependentLib* sTop;
+
+static void
+AppendDependentLib(LibHandleType aLibHandle)
+{
+ DependentLib* d = new DependentLib;
+ if (!d) {
+ return;
+ }
+
+ d->next = sTop;
+ d->libHandle = aLibHandle;
+
+ sTop = d;
+}
+
+static bool
+ReadDependentCB(pathstr_t aDependentLib, bool aDoPreload)
+{
+ if (aDoPreload) {
+ ReadAheadLib(aDependentLib);
+ }
+ LibHandleType libHandle = GetLibHandle(aDependentLib);
+ if (libHandle) {
+ AppendDependentLib(libHandle);
+ }
+
+ return libHandle;
+}
+
+#ifdef XP_WIN
+static bool
+ReadDependentCB(const char* aDependentLib, bool do_preload)
+{
+ wchar_t wideDependentLib[MAX_PATH];
+ MultiByteToWideChar(CP_UTF8, 0, aDependentLib, -1, wideDependentLib, MAX_PATH);
+ return ReadDependentCB(wideDependentLib, do_preload);
+}
+
+inline FILE*
+TS_tfopen(const char* path, const wchar_t* mode)
+{
+ wchar_t wPath[MAX_PATH];
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, wPath, MAX_PATH);
+ return _wfopen(wPath, mode);
+}
+#else
+inline FILE*
+TS_tfopen(const char* aPath, const char* aMode)
+{
+ return fopen(aPath, aMode);
+}
+#endif
+
+/* RAII wrapper for FILE descriptors */
+struct ScopedCloseFileTraits
+{
+ typedef FILE* type;
+ static type empty() { return nullptr; }
+ static void release(type aFile)
+ {
+ if (aFile) {
+ fclose(aFile);
+ }
+ }
+};
+typedef Scoped<ScopedCloseFileTraits> ScopedCloseFile;
+
+static void
+XPCOMGlueUnload()
+{
+ while (sTop) {
+ CloseLibHandle(sTop->libHandle);
+
+ DependentLib* temp = sTop;
+ sTop = sTop->next;
+
+ delete temp;
+ }
+}
+
+#if defined(XP_WIN)
+// like strpbrk but finds the *last* char, not the first
+static const char*
+ns_strrpbrk(const char* string, const char* strCharSet)
+{
+ const char* found = nullptr;
+ for (; *string; ++string) {
+ for (const char* search = strCharSet; *search; ++search) {
+ if (*search == *string) {
+ found = string;
+ // Since we're looking for the last char, we save "found"
+ // until we're at the end of the string.
+ }
+ }
+ }
+
+ return found;
+}
+#endif
+
+static GetFrozenFunctionsFunc
+XPCOMGlueLoad(const char* aXPCOMFile)
+{
+ char xpcomDir[MAXPATHLEN];
+#ifdef XP_WIN
+ const char* lastSlash = ns_strrpbrk(aXPCOMFile, "/\\");
+#elif XP_MACOSX
+ // On OSX, the dependentlibs.list file lives under Contents/Resources.
+ // However, the actual libraries listed in dependentlibs.list live under
+ // Contents/MacOS. We want to read the list from Contents/Resources, then
+ // load the libraries from Contents/MacOS.
+ const char *tempSlash = strrchr(aXPCOMFile, '/');
+ size_t tempLen = size_t(tempSlash - aXPCOMFile);
+ if (tempLen > MAXPATHLEN) {
+ return nullptr;
+ }
+ char tempBuffer[MAXPATHLEN];
+ memcpy(tempBuffer, aXPCOMFile, tempLen);
+ tempBuffer[tempLen] = '\0';
+ const char *slash = strrchr(tempBuffer, '/');
+ tempLen = size_t(slash - tempBuffer);
+ const char *lastSlash = aXPCOMFile + tempLen;
+#else
+ const char* lastSlash = strrchr(aXPCOMFile, '/');
+#endif
+ char* cursor;
+ if (lastSlash) {
+ size_t len = size_t(lastSlash - aXPCOMFile);
+
+ if (len > MAXPATHLEN - sizeof(XPCOM_FILE_PATH_SEPARATOR
+#ifdef XP_MACOSX
+ "Resources"
+ XPCOM_FILE_PATH_SEPARATOR
+#endif
+ XPCOM_DEPENDENT_LIBS_LIST)) {
+ return nullptr;
+ }
+ memcpy(xpcomDir, aXPCOMFile, len);
+ strcpy(xpcomDir + len, XPCOM_FILE_PATH_SEPARATOR
+#ifdef XP_MACOSX
+ "Resources"
+ XPCOM_FILE_PATH_SEPARATOR
+#endif
+ XPCOM_DEPENDENT_LIBS_LIST);
+ cursor = xpcomDir + len + 1;
+ } else {
+ strcpy(xpcomDir, XPCOM_DEPENDENT_LIBS_LIST);
+ cursor = xpcomDir;
+ }
+
+ if (getenv("MOZ_RUN_GTEST")) {
+ strcat(xpcomDir, ".gtest");
+ }
+
+ ScopedCloseFile flist;
+ flist = TS_tfopen(xpcomDir, READ_TEXTMODE);
+ if (!flist) {
+ return nullptr;
+ }
+
+#ifdef XP_MACOSX
+ tempLen = size_t(cursor - xpcomDir);
+ if (tempLen > MAXPATHLEN - sizeof("MacOS" XPCOM_FILE_PATH_SEPARATOR) - 1) {
+ return nullptr;
+ }
+ strcpy(cursor, "MacOS" XPCOM_FILE_PATH_SEPARATOR);
+ cursor += strlen(cursor);
+#endif
+ *cursor = '\0';
+
+ char buffer[MAXPATHLEN];
+
+ while (fgets(buffer, sizeof(buffer), flist)) {
+ int l = strlen(buffer);
+
+ // ignore empty lines and comments
+ if (l == 0 || *buffer == '#') {
+ continue;
+ }
+
+ // cut the trailing newline, if present
+ if (buffer[l - 1] == '\n') {
+ buffer[l - 1] = '\0';
+ }
+
+ if (l + size_t(cursor - xpcomDir) > MAXPATHLEN) {
+ return nullptr;
+ }
+
+ strcpy(cursor, buffer);
+ if (!ReadDependentCB(xpcomDir, do_preload)) {
+ XPCOMGlueUnload();
+ return nullptr;
+ }
+ }
+
+ GetFrozenFunctionsFunc sym =
+ (GetFrozenFunctionsFunc)GetSymbol(sTop->libHandle,
+ "NS_GetFrozenFunctions");
+
+ if (!sym) { // No symbol found.
+ XPCOMGlueUnload();
+ return nullptr;
+ }
+
+ return sym;
+}
+
+nsresult
+XPCOMGlueLoadXULFunctions(const nsDynamicFunctionLoad* aSymbols)
+{
+ // We don't null-check sXULLibHandle because this might work even
+ // if it is null (same as RTLD_DEFAULT)
+
+ nsresult rv = NS_OK;
+ while (aSymbols->functionName) {
+ char buffer[512];
+ SprintfLiteral(buffer, "%s", aSymbols->functionName);
+
+ *aSymbols->function = (NSFuncPtr)GetSymbol(sTop->libHandle, buffer);
+ if (!*aSymbols->function) {
+ rv = NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
+ }
+
+ ++aSymbols;
+ }
+ return rv;
+}
+
+void
+XPCOMGlueEnablePreload()
+{
+ do_preload = true;
+}
+
+#if defined(MOZ_WIDGET_GTK) && (defined(MOZ_MEMORY) || defined(__FreeBSD__) || defined(__NetBSD__))
+#define MOZ_GSLICE_INIT
+#endif
+
+#ifdef MOZ_GSLICE_INIT
+#include <glib.h>
+
+class GSliceInit {
+public:
+ GSliceInit() {
+ mHadGSlice = bool(getenv("G_SLICE"));
+ if (!mHadGSlice) {
+ // Disable the slice allocator, since jemalloc already uses similar layout
+ // algorithms, and using a sub-allocator tends to increase fragmentation.
+ // This must be done before g_thread_init() is called.
+ // glib >= 2.36 initializes g_slice as a side effect of its various static
+ // initializers, so this needs to happen before glib is loaded, which is
+ // this is hooked in XPCOMGlueStartup before libxul is loaded. This
+ // relies on the main executable not depending on glib.
+ setenv("G_SLICE", "always-malloc", 1);
+ }
+ }
+
+ ~GSliceInit() {
+#if MOZ_WIDGET_GTK == 2
+ if (sTop) {
+ auto XRE_GlibInit = (void (*)(void)) GetSymbol(sTop->libHandle,
+ "XRE_GlibInit");
+ // Initialize glib enough for G_SLICE to have an effect before it is unset.
+ // unset.
+ XRE_GlibInit();
+ }
+#endif
+ if (!mHadGSlice) {
+ unsetenv("G_SLICE");
+ }
+ }
+
+private:
+ bool mHadGSlice;
+};
+#endif
+
+nsresult
+XPCOMGlueStartup(const char* aXPCOMFile)
+{
+#ifdef MOZ_GSLICE_INIT
+ GSliceInit gSliceInit;
+#endif
+ xpcomFunctions.version = XPCOM_GLUE_VERSION;
+ xpcomFunctions.size = sizeof(XPCOMFunctions);
+
+ if (!aXPCOMFile) {
+ aXPCOMFile = XPCOM_DLL;
+ }
+
+ GetFrozenFunctionsFunc func = XPCOMGlueLoad(aXPCOMFile);
+ if (!func) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ nsresult rv = (*func)(&xpcomFunctions, nullptr);
+ if (NS_FAILED(rv)) {
+ XPCOMGlueUnload();
+ return rv;
+ }
+
+ return NS_OK;
+}
+
+XPCOM_API(nsresult)
+NS_InitXPCOM2(nsIServiceManager** aResult,
+ nsIFile* aBinDirectory,
+ nsIDirectoryServiceProvider* aAppFileLocationProvider)
+{
+ if (!xpcomFunctions.init) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.init(aResult, aBinDirectory, aAppFileLocationProvider);
+}
+
+XPCOM_API(nsresult)
+NS_ShutdownXPCOM(nsIServiceManager* aServMgr)
+{
+ if (!xpcomFunctions.shutdown) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.shutdown(aServMgr);
+}
+
+XPCOM_API(nsresult)
+NS_GetServiceManager(nsIServiceManager** aResult)
+{
+ if (!xpcomFunctions.getServiceManager) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.getServiceManager(aResult);
+}
+
+XPCOM_API(nsresult)
+NS_GetComponentManager(nsIComponentManager** aResult)
+{
+ if (!xpcomFunctions.getComponentManager) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.getComponentManager(aResult);
+}
+
+XPCOM_API(nsresult)
+NS_GetComponentRegistrar(nsIComponentRegistrar** aResult)
+{
+ if (!xpcomFunctions.getComponentRegistrar) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.getComponentRegistrar(aResult);
+}
+
+XPCOM_API(nsresult)
+NS_GetMemoryManager(nsIMemory** aResult)
+{
+ if (!xpcomFunctions.getMemoryManager) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.getMemoryManager(aResult);
+}
+
+XPCOM_API(nsresult)
+NS_NewLocalFile(const nsAString& aPath, bool aFollowLinks, nsIFile** aResult)
+{
+ if (!xpcomFunctions.newLocalFile) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.newLocalFile(aPath, aFollowLinks, aResult);
+}
+
+XPCOM_API(nsresult)
+NS_NewNativeLocalFile(const nsACString& aPath, bool aFollowLinks,
+ nsIFile** aResult)
+{
+ if (!xpcomFunctions.newNativeLocalFile) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.newNativeLocalFile(aPath, aFollowLinks, aResult);
+}
+
+XPCOM_API(nsresult)
+NS_GetDebug(nsIDebug2** aResult)
+{
+ if (!xpcomFunctions.getDebug) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.getDebug(aResult);
+}
+
+
+XPCOM_API(nsresult)
+NS_StringContainerInit(nsStringContainer& aStr)
+{
+ if (!xpcomFunctions.stringContainerInit) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.stringContainerInit(aStr);
+}
+
+XPCOM_API(nsresult)
+NS_StringContainerInit2(nsStringContainer& aStr, const char16_t* aData,
+ uint32_t aDataLength, uint32_t aFlags)
+{
+ if (!xpcomFunctions.stringContainerInit2) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.stringContainerInit2(aStr, aData, aDataLength, aFlags);
+}
+
+XPCOM_API(void)
+NS_StringContainerFinish(nsStringContainer& aStr)
+{
+ if (xpcomFunctions.stringContainerFinish) {
+ xpcomFunctions.stringContainerFinish(aStr);
+ }
+}
+
+XPCOM_API(uint32_t)
+NS_StringGetData(const nsAString& aStr, const char16_t** aBuf, bool* aTerm)
+{
+ if (!xpcomFunctions.stringGetData) {
+ *aBuf = nullptr;
+ return 0;
+ }
+ return xpcomFunctions.stringGetData(aStr, aBuf, aTerm);
+}
+
+XPCOM_API(uint32_t)
+NS_StringGetMutableData(nsAString& aStr, uint32_t aLen, char16_t** aBuf)
+{
+ if (!xpcomFunctions.stringGetMutableData) {
+ *aBuf = nullptr;
+ return 0;
+ }
+ return xpcomFunctions.stringGetMutableData(aStr, aLen, aBuf);
+}
+
+XPCOM_API(char16_t*)
+NS_StringCloneData(const nsAString& aStr)
+{
+ if (!xpcomFunctions.stringCloneData) {
+ return nullptr;
+ }
+ return xpcomFunctions.stringCloneData(aStr);
+}
+
+XPCOM_API(nsresult)
+NS_StringSetData(nsAString& aStr, const char16_t* aBuf, uint32_t aCount)
+{
+ if (!xpcomFunctions.stringSetData) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ return xpcomFunctions.stringSetData(aStr, aBuf, aCount);
+}
+
+XPCOM_API(nsresult)
+NS_StringSetDataRange(nsAString& aStr, uint32_t aCutStart, uint32_t aCutLength,
+ const char16_t* aBuf, uint32_t aCount)
+{
+ if (!xpcomFunctions.stringSetDataRange) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.stringSetDataRange(aStr, aCutStart, aCutLength, aBuf,
+ aCount);
+}
+
+XPCOM_API(nsresult)
+NS_StringCopy(nsAString& aDest, const nsAString& aSrc)
+{
+ if (!xpcomFunctions.stringCopy) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.stringCopy(aDest, aSrc);
+}
+
+XPCOM_API(void)
+NS_StringSetIsVoid(nsAString& aStr, const bool aIsVoid)
+{
+ if (xpcomFunctions.stringSetIsVoid) {
+ xpcomFunctions.stringSetIsVoid(aStr, aIsVoid);
+ }
+}
+
+XPCOM_API(bool)
+NS_StringGetIsVoid(const nsAString& aStr)
+{
+ if (!xpcomFunctions.stringGetIsVoid) {
+ return false;
+ }
+ return xpcomFunctions.stringGetIsVoid(aStr);
+}
+
+XPCOM_API(nsresult)
+NS_CStringContainerInit(nsCStringContainer& aStr)
+{
+ if (!xpcomFunctions.cstringContainerInit) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.cstringContainerInit(aStr);
+}
+
+XPCOM_API(nsresult)
+NS_CStringContainerInit2(nsCStringContainer& aStr, const char* aData,
+ uint32_t aDataLength, uint32_t aFlags)
+{
+ if (!xpcomFunctions.cstringContainerInit2) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.cstringContainerInit2(aStr, aData, aDataLength, aFlags);
+}
+
+XPCOM_API(void)
+NS_CStringContainerFinish(nsCStringContainer& aStr)
+{
+ if (xpcomFunctions.cstringContainerFinish) {
+ xpcomFunctions.cstringContainerFinish(aStr);
+ }
+}
+
+XPCOM_API(uint32_t)
+NS_CStringGetData(const nsACString& aStr, const char** aBuf, bool* aTerm)
+{
+ if (!xpcomFunctions.cstringGetData) {
+ *aBuf = nullptr;
+ return 0;
+ }
+ return xpcomFunctions.cstringGetData(aStr, aBuf, aTerm);
+}
+
+XPCOM_API(uint32_t)
+NS_CStringGetMutableData(nsACString& aStr, uint32_t aLen, char** aBuf)
+{
+ if (!xpcomFunctions.cstringGetMutableData) {
+ *aBuf = nullptr;
+ return 0;
+ }
+ return xpcomFunctions.cstringGetMutableData(aStr, aLen, aBuf);
+}
+
+XPCOM_API(char*)
+NS_CStringCloneData(const nsACString& aStr)
+{
+ if (!xpcomFunctions.cstringCloneData) {
+ return nullptr;
+ }
+ return xpcomFunctions.cstringCloneData(aStr);
+}
+
+XPCOM_API(nsresult)
+NS_CStringSetData(nsACString& aStr, const char* aBuf, uint32_t aCount)
+{
+ if (!xpcomFunctions.cstringSetData) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.cstringSetData(aStr, aBuf, aCount);
+}
+
+XPCOM_API(nsresult)
+NS_CStringSetDataRange(nsACString& aStr, uint32_t aCutStart,
+ uint32_t aCutLength, const char* aBuf, uint32_t aCount)
+{
+ if (!xpcomFunctions.cstringSetDataRange) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.cstringSetDataRange(aStr, aCutStart, aCutLength, aBuf,
+ aCount);
+}
+
+XPCOM_API(nsresult)
+NS_CStringCopy(nsACString& aDest, const nsACString& aSrc)
+{
+ if (!xpcomFunctions.cstringCopy) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.cstringCopy(aDest, aSrc);
+}
+
+XPCOM_API(void)
+NS_CStringSetIsVoid(nsACString& aStr, const bool aIsVoid)
+{
+ if (xpcomFunctions.cstringSetIsVoid) {
+ xpcomFunctions.cstringSetIsVoid(aStr, aIsVoid);
+ }
+}
+
+XPCOM_API(bool)
+NS_CStringGetIsVoid(const nsACString& aStr)
+{
+ if (!xpcomFunctions.cstringGetIsVoid) {
+ return false;
+ }
+ return xpcomFunctions.cstringGetIsVoid(aStr);
+}
+
+XPCOM_API(nsresult)
+NS_CStringToUTF16(const nsACString& aSrc, nsCStringEncoding aSrcEncoding,
+ nsAString& aDest)
+{
+ if (!xpcomFunctions.cstringToUTF16) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.cstringToUTF16(aSrc, aSrcEncoding, aDest);
+}
+
+XPCOM_API(nsresult)
+NS_UTF16ToCString(const nsAString& aSrc, nsCStringEncoding aDestEncoding,
+ nsACString& aDest)
+{
+ if (!xpcomFunctions.utf16ToCString) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return xpcomFunctions.utf16ToCString(aSrc, aDestEncoding, aDest);
+}
+
+XPCOM_API(void*)
+NS_Alloc(size_t aSize)
+{
+ if (!xpcomFunctions.allocFunc) {
+ return nullptr;
+ }
+ return xpcomFunctions.allocFunc(aSize);
+}
+
+XPCOM_API(void*)
+NS_Realloc(void* aPtr, size_t aSize)
+{
+ if (!xpcomFunctions.reallocFunc) {
+ return nullptr;
+ }
+ return xpcomFunctions.reallocFunc(aPtr, aSize);
+}
+
+XPCOM_API(void)
+NS_Free(void* aPtr)
+{
+ if (xpcomFunctions.freeFunc) {
+ xpcomFunctions.freeFunc(aPtr);
+ }
+}
+
+XPCOM_API(void)
+NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr,
+ const char* aFile, int32_t aLine)
+{
+ if (xpcomFunctions.debugBreakFunc) {
+ xpcomFunctions.debugBreakFunc(aSeverity, aStr, aExpr, aFile, aLine);
+ }
+}
+
+XPCOM_API(void)
+NS_LogInit()
+{
+ if (xpcomFunctions.logInitFunc) {
+ xpcomFunctions.logInitFunc();
+ }
+}
+
+XPCOM_API(void)
+NS_LogTerm()
+{
+ if (xpcomFunctions.logTermFunc) {
+ xpcomFunctions.logTermFunc();
+ }
+}
+
+XPCOM_API(void)
+NS_LogAddRef(void* aPtr, nsrefcnt aNewRefCnt,
+ const char* aTypeName, uint32_t aInstanceSize)
+{
+ if (xpcomFunctions.logAddRefFunc)
+ xpcomFunctions.logAddRefFunc(aPtr, aNewRefCnt,
+ aTypeName, aInstanceSize);
+}
+
+XPCOM_API(void)
+NS_LogRelease(void* aPtr, nsrefcnt aNewRefCnt, const char* aTypeName)
+{
+ if (xpcomFunctions.logReleaseFunc) {
+ xpcomFunctions.logReleaseFunc(aPtr, aNewRefCnt, aTypeName);
+ }
+}
+
+XPCOM_API(void)
+NS_LogCtor(void* aPtr, const char* aTypeName, uint32_t aInstanceSize)
+{
+ if (xpcomFunctions.logCtorFunc) {
+ xpcomFunctions.logCtorFunc(aPtr, aTypeName, aInstanceSize);
+ }
+}
+
+XPCOM_API(void)
+NS_LogDtor(void* aPtr, const char* aTypeName, uint32_t aInstanceSize)
+{
+ if (xpcomFunctions.logDtorFunc) {
+ xpcomFunctions.logDtorFunc(aPtr, aTypeName, aInstanceSize);
+ }
+}
+
+XPCOM_API(void)
+NS_LogCOMPtrAddRef(void* aCOMPtr, nsISupports* aObject)
+{
+ if (xpcomFunctions.logCOMPtrAddRefFunc) {
+ xpcomFunctions.logCOMPtrAddRefFunc(aCOMPtr, aObject);
+ }
+}
+
+XPCOM_API(void)
+NS_LogCOMPtrRelease(void* aCOMPtr, nsISupports* aObject)
+{
+ if (xpcomFunctions.logCOMPtrReleaseFunc) {
+ xpcomFunctions.logCOMPtrReleaseFunc(aCOMPtr, aObject);
+ }
+}
+
+XPCOM_API(nsresult)
+NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
+ nsISomeInterface** aStub)
+{
+ if (!xpcomFunctions.getXPTCallStubFunc) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ return xpcomFunctions.getXPTCallStubFunc(aIID, aOuter, aStub);
+}
+
+XPCOM_API(void)
+NS_DestroyXPTCallStub(nsISomeInterface* aStub)
+{
+ if (xpcomFunctions.destroyXPTCallStubFunc) {
+ xpcomFunctions.destroyXPTCallStubFunc(aStub);
+ }
+}
+
+XPCOM_API(nsresult)
+NS_InvokeByIndex(nsISupports* aThat, uint32_t aMethodIndex,
+ uint32_t aParamCount, nsXPTCVariant* aParams)
+{
+ if (!xpcomFunctions.invokeByIndexFunc) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ return xpcomFunctions.invokeByIndexFunc(aThat, aMethodIndex,
+ aParamCount, aParams);
+}
+
+XPCOM_API(bool)
+NS_CycleCollectorSuspect(nsISupports* aObj)
+{
+ if (!xpcomFunctions.cycleSuspectFunc) {
+ return false;
+ }
+
+ return xpcomFunctions.cycleSuspectFunc(aObj);
+}
+
+XPCOM_API(bool)
+NS_CycleCollectorForget(nsISupports* aObj)
+{
+ if (!xpcomFunctions.cycleForgetFunc) {
+ return false;
+ }
+
+ return xpcomFunctions.cycleForgetFunc(aObj);
+}
+
+XPCOM_API(nsPurpleBufferEntry*)
+NS_CycleCollectorSuspect2(void* aObj, nsCycleCollectionParticipant* aCp)
+{
+ if (!xpcomFunctions.cycleSuspect2Func) {
+ return nullptr;
+ }
+
+ return xpcomFunctions.cycleSuspect2Func(aObj, aCp);
+}
+
+XPCOM_API(void)
+NS_CycleCollectorSuspect3(void* aObj, nsCycleCollectionParticipant* aCp,
+ nsCycleCollectingAutoRefCnt* aRefCnt,
+ bool* aShouldDelete)
+{
+ if (xpcomFunctions.cycleSuspect3Func) {
+ xpcomFunctions.cycleSuspect3Func(aObj, aCp, aRefCnt, aShouldDelete);
+ }
+}
+
+XPCOM_API(bool)
+NS_CycleCollectorForget2(nsPurpleBufferEntry* aEntry)
+{
+ if (!xpcomFunctions.cycleForget2Func) {
+ return false;
+ }
+
+ return xpcomFunctions.cycleForget2Func(aEntry);
+}
diff --git a/xpcom/glue/standalone/nsXPCOMGlue.h b/xpcom/glue/standalone/nsXPCOMGlue.h
new file mode 100644
index 000000000..e23bfa498
--- /dev/null
+++ b/xpcom/glue/standalone/nsXPCOMGlue.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsXPCOMGlue_h__
+#define nsXPCOMGlue_h__
+
+#include "nscore.h"
+
+#ifdef XPCOM_GLUE
+
+/**
+ * The following functions are only available in the standalone glue.
+ */
+
+/**
+ * Enabled preloading of dynamically loaded libraries
+ */
+extern "C" NS_HIDDEN_(void) XPCOMGlueEnablePreload();
+
+/**
+ * Initialize the XPCOM glue by dynamically linking against the XPCOM
+ * shared library indicated by xpcomFile.
+ */
+extern "C" NS_HIDDEN_(nsresult) XPCOMGlueStartup(const char* aXPCOMFile);
+
+typedef void (*NSFuncPtr)();
+
+struct nsDynamicFunctionLoad
+{
+ const char* functionName;
+ NSFuncPtr* function;
+};
+
+/**
+ * Dynamically load functions from libxul.
+ *
+ * @throws NS_ERROR_NOT_INITIALIZED if XPCOMGlueStartup() was not called or
+ * if the libxul DLL was not found.
+ * @throws NS_ERROR_LOSS_OF_SIGNIFICANT_DATA if only some of the required
+ * functions were found.
+ */
+extern "C" NS_HIDDEN_(nsresult)
+XPCOMGlueLoadXULFunctions(const nsDynamicFunctionLoad* aSymbols);
+
+#endif // XPCOM_GLUE
+#endif // nsXPCOMGlue_h__
diff --git a/xpcom/glue/standalone/staticruntime/moz.build b/xpcom/glue/standalone/staticruntime/moz.build
new file mode 100644
index 000000000..735086ab0
--- /dev/null
+++ b/xpcom/glue/standalone/staticruntime/moz.build
@@ -0,0 +1,50 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+include('../../objs.mozbuild')
+
+SOURCES += xpcom_glue_src_cppsrcs
+
+SOURCES += [
+ '../../nsStringAPI.cpp',
+ '../nsXPCOMGlue.cpp',
+]
+
+Library('xpcomglue_staticruntime')
+
+SDK_LIBRARY = True
+
+# create a static lib
+FORCE_STATIC_LIB = True
+
+if CONFIG['_MSC_VER']:
+ DEFINES['_USE_ANSI_CPP'] = True
+ # Don't include directives about which CRT to use
+ CFLAGS += ['-Zl']
+ CXXFLAGS += ['-Zl']
+
+DEFINES['XPCOM_GLUE'] = True
+
+LOCAL_INCLUDES += [
+ '../../../build',
+ '../../../threads',
+]
+
+# Statically link to the CRT on Windows
+USE_STATIC_LIBS = True
+
+# Don't use STL wrappers here (i.e. wrapped <new>); they require mozalloc
+DISABLE_STL_WRAPPING = True
+
+# Include fallible for third party code using the xpcom glue
+USE_LIBS += [
+ 'fallible',
+]
+
+# Force to build a static library only
+NO_EXPAND_LIBS = True
+
+DIST_INSTALL = True