From a99b758dd96bac879f2bcaa7ab69af351c5ff72b Mon Sep 17 00:00:00 2001 From: ussrhero Date: Sun, 29 Sep 2019 21:55:29 +0300 Subject: [PATCH] reworked symbol enumeration --- kdlibcpp | 2 +- pykd/pymod.cpp | 19 +++++++++++-------- pykd/pytypeinfo.h | 33 +++++++++++++++++++++++++++------ test/scripts/typeinfo.py | 2 +- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/kdlibcpp b/kdlibcpp index daa1b20..cddc386 160000 --- a/kdlibcpp +++ b/kdlibcpp @@ -1 +1 @@ -Subproject commit daa1b20092839ad58c77d9747ce672545ef1dc3c +Subproject commit cddc38648e9ea0c9fd84c51655cc822d0014ff09 diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 99fca22..21feb46 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -106,7 +106,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( TypeInfo_ptrTo, TypeInfoAdapter::ptrTo, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getTypeFromSource_, pykd::getTypeFromSource, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getTypeInfoProviderFromPdb_, pykd::getTypeInfoProviderFromPdb, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getTypeInfoProviderFromSource_, pykd::getTypeInfoProviderFromSource, 1, 2); -BOOST_PYTHON_FUNCTION_OVERLOADS( getSymbolEnumeratorFromSource_, pykd::getSymbolEnumeratorFromSource, 1, 2); +BOOST_PYTHON_FUNCTION_OVERLOADS( getSymbolProviderFromSource_, pykd::getSymbolProviderFromSource, 1, 2); BOOST_PYTHON_FUNCTION_OVERLOADS(evalExpr_, pykd::evalExpr, 1, 3); BOOST_PYTHON_FUNCTION_OVERLOADS( addSyntheticModule_, pykd::addSyntheticModule, 3, 4 ); @@ -445,8 +445,8 @@ void pykd_init() "Create typeInfo provider from C/C++ source code") ); python::def( "getTypeInfoProviderFromPdb", &pykd::getTypeInfoProviderFromPdb, getTypeInfoProviderFromPdb_( python::args("filePath", "baseOffset"), "Create typeInfo provider from pdb file") ); - python::def("getSymbolEnumeratorFromSource", &pykd::getSymbolEnumeratorFromSource, getSymbolEnumeratorFromSource_(python::args("sourceCode", "compileOptions"), - "Create symbol enumerator for source code")); + python::def("getSymbolProviderFromSource", &pykd::getSymbolProviderFromSource, getSymbolProviderFromSource_(python::args("sourceCode", "compileOptions"), + "Create symbol provider for source code")); python::def("evalExpr", &pykd::evalExpr, evalExpr_(python::args("expression", "scope", "typeProvider"), "Evaluate C++ expression with typed information")); @@ -1312,7 +1312,6 @@ void pykd_init() #endif ; - python::class_("typeInfoProvider", "Get abstaract access to different type info sources", python::no_init) .def( "getTypeByName", TypeInfoProviderAdapter::getTypeByName, @@ -1323,17 +1322,21 @@ void pykd_init() .def( "__getattr__", TypeInfoProviderAdapter::getTypeAsAttr ) ; - python::class_("symbolEnumerator", - "Get symbol enumerator", python::no_init) + python::class_("symbolIterator", "Iterator for symbols", python::no_init) .def("__iter__", SymbolEnumeratorAdapter::getIter) #if PY_VERSION_HEX < 0x03000000 .def("next", &SymbolEnumeratorAdapter::next) #else - .def("__next__", SymbolEnumeratorAdapter::next) + .def("__next__", &SymbolEnumeratorAdapter::next) #endif ; - + python::class_("symbolProvider", + "Get abstaract access to different type info sources", python::no_init) + .def("iter", SymbolProviderAdapter::getIterWithMask, python::return_value_policy(), + "Return type iterator with specified mask") + .def("__iter__", SymbolProviderAdapter::getIter, python::return_value_policy()) + ; python::enum_("eventResult", "Return value of event handler") .value("Proceed", kdlib::DebugCallbackProceed) diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h index a675ac5..9500997 100644 --- a/pykd/pytypeinfo.h +++ b/pykd/pytypeinfo.h @@ -69,10 +69,10 @@ inline kdlib::TypeInfoProviderPtr getTypeInfoProviderFromSource(const std::wstri return kdlib::getTypeInfoProviderFromSource(sourceCode, compileOptions); } -inline kdlib::SymbolEnumeratorPtr getSymbolEnumeratorFromSource(const std::wstring& sourceCode, const std::wstring& compileOptions = L"") +inline kdlib::SymbolProviderPtr getSymbolProviderFromSource(const std::wstring& sourceCode, const std::wstring& compileOptions = L"") { AutoRestorePyState pystate; - return kdlib::getSymbolEnumeratorFromSource(sourceCode, compileOptions); + return kdlib::getSymbolProviderFromSource(sourceCode, compileOptions); } inline kdlib::TypeInfoProviderPtr getTypeInfoProviderFromPdb(const std::wstring& fileName, kdlib::MEMOFFSET_64 offset = 0UL) @@ -440,21 +440,42 @@ struct TypeInfoProviderAdapter : public kdlib::TypeInfoProvider struct SymbolEnumeratorAdapter { + SymbolEnumeratorAdapter(const kdlib::SymbolEnumeratorPtr& symEnum) + : m_symEnum(symEnum) + {} - static kdlib::SymbolEnumeratorPtr getIter(kdlib::SymbolEnumeratorPtr& symEnum) + + static python::object getIter(const python::object& obj) { - return symEnum; + return obj; } - static std::wstring next(kdlib::SymbolEnumeratorPtr& symEnum) + std::wstring next() { - auto symName = symEnum->Next(); + auto symName = m_symEnum->Next(); if (symName.empty()) throw StopIteration("No more data."); return symName; } + +private: + + kdlib::SymbolEnumeratorPtr m_symEnum; +}; + +struct SymbolProviderAdapter +{ + static SymbolEnumeratorAdapter* getIter(const kdlib::SymbolProviderPtr &symProvider) + { + return new SymbolEnumeratorAdapter(symProvider->getSymbolEnumerator()); + }; + + static SymbolEnumeratorAdapter* getIterWithMask(const kdlib::SymbolProviderPtr &symProvider, const std::wstring& mask) + { + return new SymbolEnumeratorAdapter(symProvider->getSymbolEnumerator(mask)); + } }; struct BaseTypesEnum { diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index b01266d..1f13ad7 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -390,6 +390,6 @@ class TypeInfoTest( unittest.TestCase ): def testClangCompile(self): src = "#include \r\n"; opt = "-I\"C:/Program Files (x86)/Windows Kits/8.1/Include/um\" -I\"C:/Program Files (x86)/Windows Kits/8.1/Include/shared\" -w"; - symEnum = pykd.getSymbolEnumeratorFromSource(src, opt) + symEnum = pykd.getSymbolProviderFromSource(src, opt) for sym in symEnum: print(sym) \ No newline at end of file