From 1034ad92c94a1b9a908a165796b59c76d226570d Mon Sep 17 00:00:00 2001 From: "markh%activestate.com" Date: Sat, 14 Apr 2001 13:41:35 +0000 Subject: [PATCH] A number of changes moving towards dynamic linking support on Linux. Not part of the build. --- extensions/python/xpcom/src/PyGModule.cpp | 64 ----------------- extensions/python/xpcom/src/PyXPCOM_std.h | 10 --- .../python/xpcom/src/loader/pyloader.cpp | 45 ++++++++++-- extensions/python/xpcom/src/xpcom.cpp | 72 ++++++++++++++++++- 4 files changed, 110 insertions(+), 81 deletions(-) diff --git a/extensions/python/xpcom/src/PyGModule.cpp b/extensions/python/xpcom/src/PyGModule.cpp index 04688ac436a..09df5c90022 100644 --- a/extensions/python/xpcom/src/PyGModule.cpp +++ b/extensions/python/xpcom/src/PyGModule.cpp @@ -37,70 +37,6 @@ #include #include -#ifdef XP_WIN -// Can only assume dynamic loading on Windows. -#define LOADER_LINKS_WITH_PYTHON - -#endif // XP_WIN - -extern void PyXPCOM_InterpreterState_Ensure(); - -//////////////////////////////////////////////////////////// -// This is the main entry point called by the Python component -// loader. -extern "C" NS_EXPORT nsresult PyXPCOM_NSGetModule(nsIComponentManager *servMgr, - nsIFile* location, - nsIModule** result) -{ - NS_PRECONDITION(result!=NULL, "null result pointer in PyXPCOM_NSGetModule!"); - NS_PRECONDITION(location!=NULL, "null nsIFile pointer in PyXPCOM_NSGetModule!"); - NS_PRECONDITION(servMgr!=NULL, "null servMgr pointer in PyXPCOM_NSGetModule!"); -#ifndef LOADER_LINKS_WITH_PYTHON - if (!Py_IsInitialized()) { - Py_Initialize(); - if (!Py_IsInitialized()) { - PyXPCOM_LogError("Python initialization failed!\n"); - return NS_ERROR_FAILURE; - } - PyEval_InitThreads(); - PyXPCOM_InterpreterState_Ensure(); - PyEval_SaveThread(); - } -#endif // LOADER_LINKS_WITH_PYTHON - CEnterLeavePython _celp; - PyObject *func = NULL; - PyObject *obServMgr = NULL; - PyObject *obLocation = NULL; - PyObject *wrap_ret = NULL; - PyObject *args = NULL; - PyObject *mod = PyImport_ImportModule("xpcom.server"); - if (!mod) goto done; - func = PyObject_GetAttrString(mod, "NS_GetModule"); - if (func==NULL) goto done; - obServMgr = Py_nsISupports::PyObjectFromInterface(servMgr, NS_GET_IID(nsIComponentManager), PR_TRUE); - if (obServMgr==NULL) goto done; - obLocation = Py_nsISupports::PyObjectFromInterface(location, NS_GET_IID(nsIFile), PR_TRUE); - if (obLocation==NULL) goto done; - args = Py_BuildValue("OO", obServMgr, obLocation); - if (args==NULL) goto done; - wrap_ret = PyEval_CallObject(func, args); - if (wrap_ret==NULL) goto done; - Py_nsISupports::InterfaceFromPyObject(wrap_ret, NS_GET_IID(nsIModule), (nsISupports **)result, PR_FALSE, PR_FALSE); -done: - nsresult nr = NS_OK; - if (PyErr_Occurred()) { - PyXPCOM_LogError("Obtaining the module object from Python failed.\n"); - nr = PyXPCOM_SetCOMErrorFromPyException(); - } - Py_XDECREF(func); - Py_XDECREF(obServMgr); - Py_XDECREF(obLocation); - Py_XDECREF(wrap_ret); - Py_XDECREF(mod); - Py_XDECREF(args); - return nr; -} - class PyG_nsIModule : public PyG_Base, public nsIModule { public: diff --git a/extensions/python/xpcom/src/PyXPCOM_std.h b/extensions/python/xpcom/src/PyXPCOM_std.h index 651ee4bed8d..83e15001521 100644 --- a/extensions/python/xpcom/src/PyXPCOM_std.h +++ b/extensions/python/xpcom/src/PyXPCOM_std.h @@ -34,16 +34,6 @@ // Main Mozilla cross-platform declarations. #include "xp_core.h" -#ifdef _DEBUG -# ifndef DEBUG -# define DEBUG -# endif - -# define DEVELOPER_DEBUG -# define NS_DEBUG -# define DEBUG_markh -#endif // DEBUG - #include #include #include diff --git a/extensions/python/xpcom/src/loader/pyloader.cpp b/extensions/python/xpcom/src/loader/pyloader.cpp index 679773c0d6d..1860cb08cc0 100644 --- a/extensions/python/xpcom/src/loader/pyloader.cpp +++ b/extensions/python/xpcom/src/loader/pyloader.cpp @@ -30,7 +30,10 @@ #include "nsIRegistry.h" #include "nsISupports.h" #include "nsIModule.h" - +#include "nsDirectoryServiceDefs.h" +#include "nsILocalFile.h" +#include "nsXPIDLString.h" + #include // For console logging. #ifdef HAVE_LONG_LONG @@ -78,6 +81,36 @@ pfnPyXPCOM_NSGetModule pfnEntryPoint = nsnull; static void LogError(const char *fmt, ...); +static void LogDebug(const char *fmt, ...); + +#ifdef LOADER_LINKS_WITH_PYTHON +// Ensure that any paths guaranteed by this package exist on sys.path +// Only called once as we are first loaded into the process. +void AddStandardPaths() +{ + // Put {bin}\Python on the path if it exists. + nsCOMPtr aFile; + nsCOMPtr aLocalFile; + NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(aFile)); + if (!aFile) { + LogError("The Python XPCOM loader could not locate the 'bin' directory\n"); + return; + } + aFile->Append("python"); + nsXPIDLCString pathBuf; + aFile->GetPath(getter_Copies(pathBuf)); + PyObject *obPath = PySys_GetObject("path"); + if (!obPath) { + LogError("The Python XPCOM loader could not get the Python sys.path variable\n"); + return; + } + LogDebug("The Python XPCOM loader is adding '%s' to sys.path\n", (const char *)pathBuf); +// DebugBreak(); + PyObject *newStr = PyString_FromString(pathBuf); + PyList_Insert(obPath, 0, newStr); + Py_XDECREF(newStr); +} +#endif extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, nsIFile* location, @@ -91,14 +124,12 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, #ifdef LOADER_LINKS_WITH_PYTHON PRBool bDidInitPython = !Py_IsInitialized(); // well, I will next line, anyway :-) if (bDidInitPython) { - // If Python was already initialized, we almost certainly - // do not have the thread-lock, so can not attempt to import anything - // We simply must assume/hope that Python already has our module loaded. Py_Initialize(); if (!Py_IsInitialized()) { LogError("Python initialization failed!\n"); return NS_ERROR_FAILURE; } + AddStandardPaths(); PyObject *mod = PyImport_ImportModule("xpcom._xpcom"); if (mod==NULL) { LogError("Could not import the Python XPCOM extension\n"); @@ -224,14 +255,16 @@ static void LogWarning(const char *fmt, ...) } #ifdef DEBUG -void LogDebug(const char *fmt, ...) +static void LogDebug(const char *fmt, ...) { va_list marker; va_start(marker, fmt); VLogF("PyXPCOM Loader Debug: ", fmt, marker); } #else -#define LogDebug() +static void LogDebug(const char *fmt, ...) +{ +} #endif #ifdef LOADER_LINKS_WITH_PYTHON diff --git a/extensions/python/xpcom/src/xpcom.cpp b/extensions/python/xpcom/src/xpcom.cpp index 2097bba7562..d01d16e3897 100644 --- a/extensions/python/xpcom/src/xpcom.cpp +++ b/extensions/python/xpcom/src/xpcom.cpp @@ -50,6 +50,69 @@ extern PRInt32 _PyXPCOM_GetGatewayCount(void); extern PRInt32 _PyXPCOM_GetInterfaceCount(void); extern void AddDefaultGateway(PyObject *instance, nsISupports *gateway); +extern void PyXPCOM_InterpreterState_Ensure(); + +#ifdef XP_WIN +// Can only assume dynamic loading on Windows. +#define LOADER_LINKS_WITH_PYTHON + +#endif // XP_WIN + +//////////////////////////////////////////////////////////// +// This is the main entry point called by the Python component +// loader. +extern "C" NS_EXPORT nsresult PyXPCOM_NSGetModule(nsIComponentManager *servMgr, + nsIFile* location, + nsIModule** result) +{ + NS_PRECONDITION(result!=NULL, "null result pointer in PyXPCOM_NSGetModule!"); + NS_PRECONDITION(location!=NULL, "null nsIFile pointer in PyXPCOM_NSGetModule!"); + NS_PRECONDITION(servMgr!=NULL, "null servMgr pointer in PyXPCOM_NSGetModule!"); +#ifndef LOADER_LINKS_WITH_PYTHON + if (!Py_IsInitialized()) { + Py_Initialize(); + if (!Py_IsInitialized()) { + PyXPCOM_LogError("Python initialization failed!\n"); + return NS_ERROR_FAILURE; + } + PyEval_InitThreads(); + PyXPCOM_InterpreterState_Ensure(); + PyEval_SaveThread(); + } +#endif // LOADER_LINKS_WITH_PYTHON + CEnterLeavePython _celp; + PyObject *func = NULL; + PyObject *obServMgr = NULL; + PyObject *obLocation = NULL; + PyObject *wrap_ret = NULL; + PyObject *args = NULL; + PyObject *mod = PyImport_ImportModule("xpcom.server"); + if (!mod) goto done; + func = PyObject_GetAttrString(mod, "NS_GetModule"); + if (func==NULL) goto done; + obServMgr = Py_nsISupports::PyObjectFromInterface(servMgr, NS_GET_IID(nsIComponentManager), PR_TRUE); + if (obServMgr==NULL) goto done; + obLocation = Py_nsISupports::PyObjectFromInterface(location, NS_GET_IID(nsIFile), PR_TRUE); + if (obLocation==NULL) goto done; + args = Py_BuildValue("OO", obServMgr, obLocation); + if (args==NULL) goto done; + wrap_ret = PyEval_CallObject(func, args); + if (wrap_ret==NULL) goto done; + Py_nsISupports::InterfaceFromPyObject(wrap_ret, NS_GET_IID(nsIModule), (nsISupports **)result, PR_FALSE, PR_FALSE); +done: + nsresult nr = NS_OK; + if (PyErr_Occurred()) { + PyXPCOM_LogError("Obtaining the module object from Python failed.\n"); + nr = PyXPCOM_SetCOMErrorFromPyException(); + } + Py_XDECREF(func); + Py_XDECREF(obServMgr); + Py_XDECREF(obLocation); + Py_XDECREF(wrap_ret); + Py_XDECREF(mod); + Py_XDECREF(args); + return nr; +} // Hrm - So we can't have templates, eh?? // preprocessor to the rescue, I guess. @@ -107,7 +170,6 @@ PyXPCOMMethod_NS_LocateSpecialSystemDirectory(PyObject *self, PyObject *args) int typ; if (!PyArg_ParseTuple(args, "i", &typ)) return NULL; - nsIFileSpec *spec = NULL; nsSpecialSystemDirectory systemDir((nsSpecialSystemDirectory::SystemDirectories)typ); return PyString_FromString(systemDir.GetNativePathCString()); } @@ -524,6 +586,14 @@ init_xpcom() { } PyDict_SetItemString(dict, "IIDType", (PyObject *)&Py_nsIID::type); + // register our entry point. + PyObject *obFuncPtr = PyLong_FromVoidPtr((void *)&PyXPCOM_NSGetModule); + if (obFuncPtr) + PyDict_SetItemString(dict, + "_NSGetModule_FuncPtr", + obFuncPtr); + Py_XDECREF(obFuncPtr); + REGISTER_IID(nsISupports); REGISTER_IID(nsISupportsString); REGISTER_IID(nsIModule);