From 8abc40147112b88ce441fa5edc633728fa6a46f8 Mon Sep 17 00:00:00 2001 From: "mhammond%skippinet.com.au" Date: Wed, 2 Apr 2003 04:00:17 +0000 Subject: [PATCH] Add support for the timeline service. Not part of the build. git-svn-id: svn://10.0.0.236/trunk@140547 18797224-902f-48f8-a5cc-f745e15eee43 --- .../python/xpcom/src/VariantUtils.cpp | 33 +++++++++++-------- .../python/xpcom/src/loader/pyloader.cpp | 20 +++++++++-- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/mozilla/extensions/python/xpcom/src/VariantUtils.cpp b/mozilla/extensions/python/xpcom/src/VariantUtils.cpp index 8fc244ac44d..20a4becf456 100644 --- a/mozilla/extensions/python/xpcom/src/VariantUtils.cpp +++ b/mozilla/extensions/python/xpcom/src/VariantUtils.cpp @@ -1044,19 +1044,13 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor nsXPTCVariant &ns_v = m_var_array[value_index]; NS_ABORT_IF_FALSE(ns_v.type == td.type_flags, "Expecting variant all setup for us"); - // NOTE: We NEVER pass Python internal buffers, even when a param is - // only marked as "in", for 2 reasons: - // * Paranoia - passing the internal "char *" buffer for a Python string - // means that the caller could potentially modify it, even though they - // shouldnt. This will be hard to track down, and will appear as tho - // Python itself has the bug, rather than the naughty object. - // * Simplicity - if the param is marked "in/out", we _must_ make - // a buffer copy anyway. - // The downside is speed - if a large buffer is passed as an "in" param, - // it is a shame to make a copy, then pass it, then free it, when it should - // be fine to simply pass the buffer. - // (The discussion above doesnt apply to ints and stuff - we can't - // even really get at the internal "int *" of a PyInt object. + // We used to avoid passing internal buffers to PyString etc objects + // for 2 reasons: paranoia (so incorrect external components couldn't break + // Python) and simplicity (in vs in-out issues, etc) + // However, at least one C++ implemented component (nsITimelineService) + // uses a "char *", and keys on the address (assuming that the same + // *pointer* is passed rather than value. Therefore, we have a special case + // - T_CHAR_STR that is "in" gets the Python string pointer passed. void *&this_buffer_pointer = m_buffer_array[value_index]; // Freed at object destruction with PyMem_Free() NS_ABORT_IF_FALSE(this_buffer_pointer==nsnull, "We appear to already have a buffer"); int cb_this_buffer_pointer = 0; @@ -1216,6 +1210,13 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor ns_v.val.p = nsnull; break; } + // If an "in" char *, and we have a PyString, then pass the + // pointer (hoping everyone else plays by the rules too. + if (!XPT_PD_IS_OUT(td.param_flags) && PyString_Check(val)) { + ns_v.val.p = PyString_AS_STRING(val); + break; + } + if (!PyString_Check(val) && !PyUnicode_Check(val)) { PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object"); BREAK_FALSE; @@ -1237,6 +1238,12 @@ PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor ns_v.val.p = nsnull; break; } + // If an "in" char *, and we have a PyString, then pass the + // pointer (hoping everyone else plays by the rules too. + if (!XPT_PD_IS_OUT(td.param_flags) && PyUnicode_Check(val)) { + ns_v.val.p = PyUnicode_AS_UNICODE(val); + break; + } if (!PyString_Check(val) && !PyUnicode_Check(val)) { PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object"); BREAK_FALSE; diff --git a/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp b/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp index e6d5a3499b4..9f2982d1b2b 100644 --- a/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp +++ b/mozilla/extensions/python/xpcom/src/loader/pyloader.cpp @@ -59,6 +59,7 @@ static char *PyTraceback_AsString(PyObject *exc_tb); #endif +#include "nsITimelineService.h" typedef nsresult (*pfnPyXPCOM_NSGetModule)(nsIComponentManager *servMgr, nsIFile* location, @@ -108,6 +109,7 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, #endif PRBool bDidInitPython = !Py_IsInitialized(); // well, I will next line, anyway :-) if (bDidInitPython) { + NS_TIMELINE_START_TIMER("PyXPCOM: Python initializing"); Py_Initialize(); if (!Py_IsInitialized()) { LogError("Python initialization failed!\n"); @@ -118,8 +120,11 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, #endif // NS_DEBUG AddStandardPaths(); PyEval_InitThreads(); + NS_TIMELINE_STOP_TIMER("PyXPCOM: Python initializing"); + NS_TIMELINE_MARK_TIMER("PyXPCOM: Python initializing"); } // Get the Python interpreter state + NS_TIMELINE_START_TIMER("PyXPCOM: Python threadstate setup"); PyThreadState *threadStateCreated = NULL; PyThreadState *threadState = PyThreadState_Swap(NULL); if (threadState==NULL) { @@ -153,7 +158,12 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, LogError("Could not load main Python entry point\n"); return NS_ERROR_FAILURE; } - + +#ifdef MOZ_TIMELINE + // If the timeline service is installed, see if we can install our hooks. + if (NULL==PyImport_ImportModule("timeline_hook")) + PyErr_Clear(); // but don't care if we can't. +#endif // Abandon the thread-lock, as the first thing Python does // is re-establish the lock (the Python thread-state story SUCKS!!!) if (threadStateCreated) { @@ -165,7 +175,13 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, if (threadStateSave) PyThreadState_Delete(threadStateSave); } - return (*pfnEntryPoint)(servMgr, location, result); + NS_TIMELINE_STOP_TIMER("PyXPCOM: Python threadstate setup"); + NS_TIMELINE_MARK_TIMER("PyXPCOM: Python threadstate setup"); + NS_TIMELINE_START_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point"); + nsresult rc = (*pfnEntryPoint)(servMgr, location, result); + NS_TIMELINE_STOP_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point"); + NS_TIMELINE_MARK_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point"); + return rc; } // The internal helper that actually moves the