gecko-dev/xpcom/glue/standalone/nsXPCOMGlue.cpp

928 строки
21 KiB
C++

/* -*- 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);
}