bool VsPyProf::GetUserToken()

in Python/Product/VsPyProf/PythonApi.cpp [128:240]


bool VsPyProf::GetUserToken(PyFrameObject* frameObj, DWORD_PTR& func, DWORD_PTR& module) {
    auto codeObj = frameObj->f_code;
    if (codeObj->ob_type == PyCode_Type) {
        // extract func and module tokens
        PyObject *filename = nullptr;
        func = (DWORD_PTR)codeObj;

        if (PyCodeObject25_27::IsFor(MajorVersion, MinorVersion)) {
            filename = ((PyCodeObject25_27*)codeObj)->co_filename;
        } else if (PyCodeObject30_32::IsFor(MajorVersion, MinorVersion)) {
            filename = ((PyCodeObject30_32*)codeObj)->co_filename;
        } else if (PyCodeObject33_35::IsFor(MajorVersion, MinorVersion)) {
            filename = ((PyCodeObject33_35*)codeObj)->co_filename;
        } else if (PyCodeObject36::IsFor(MajorVersion, MinorVersion)) {
            filename = ((PyCodeObject36*)codeObj)->co_filename;
        } else if (PyCodeObject37::IsFor(MajorVersion, MinorVersion)) {
            filename = ((PyCodeObject37*)codeObj)->co_filename;
        } else if (PyCodeObject38::IsFor(MajorVersion, MinorVersion)) {
            filename = ((PyCodeObject38*)codeObj)->co_filename;
        }
        module = (DWORD_PTR)filename;

        // see if the function is registered
        if (_registeredObjects.find(func) == _registeredObjects.end()) {
            // get module name and register it if not already registered
            auto moduleIter = _registeredModules.find(module);

            wstring moduleName;
            if (moduleIter == _registeredModules.end()) {
                ReferenceObject(filename);

                wstring filenameStr;
                GetName(filename, filenameStr);

                // make sure we have a fully qualified path so the profiler can find our files...
                if ((filenameStr.length() >= 2 && (filenameStr[0] != '\\' || filenameStr[1] != '\\')) &&
                    (filenameStr.length() >= 3 && (filenameStr[1] != ':' || filenameStr[2] != '\\'))) {
                        // not a fully qualified path, fully qualify it.
                        wchar_t buffer[MAX_PATH];
                        if (GetCurrentDirectory(MAX_PATH, buffer) != 0) {
                            if (filenameStr[0] != '\\' && wcslen(buffer) > 0 && buffer[wcslen(buffer) - 1] != '\\') {
                                filenameStr.insert(0, L"\\");
                            }
                            filenameStr.insert(0, buffer);
                        }
                }

                GetModuleName(filenameStr, moduleName);

                _registeredModules[module] = moduleName;

                // make sure we only have valid path chars, vsperfreport doesn't like invalid chars
                for (size_t i = 0; i < filenameStr.length(); i++) {
                    if (filenameStr[i] == '<') {
                        filenameStr[i] = '(';
                    } else if (filenameStr[i] == '>') {
                        filenameStr[i] = ')';
                    } else if (filenameStr[i] == '|' ||
                        filenameStr[i] == '"' ||
                        filenameStr[i] == 124 ||
                        filenameStr[i] < 32) {
                            filenameStr[i] = '_';
                    }
                }
                _nameToken(module, filenameStr.c_str());
            } else {
                moduleName = (*moduleIter).second;
            }

            auto className = GetClassNameFromFrame(frameObj, codeObj);
            if (className.length() != 0) {
                if (moduleName.length() != 0) {
                    moduleName.append(L".");
                    moduleName.append(className);
                } else {
                    moduleName = className;
                }
            }

            ReferenceObject(codeObj);

            // register function
            _registeredObjects.insert(func);

            // associate source information
            int lineno = 0;
            if (PyCodeObject25_27::IsFor(MajorVersion, MinorVersion)) {
                RegisterName(func, ((PyCodeObject25_27*)codeObj)->co_name, &moduleName);
                lineno = ((PyCodeObject25_27*)codeObj)->co_firstlineno;
            } else if (PyCodeObject30_32::IsFor(MajorVersion, MinorVersion)) {
                RegisterName(func, ((PyCodeObject30_32*)codeObj)->co_name, &moduleName);
                lineno = ((PyCodeObject30_32*)codeObj)->co_firstlineno;
            } else if (PyCodeObject33_35::IsFor(MajorVersion, MinorVersion)) {
                RegisterName(func, ((PyCodeObject33_35*)codeObj)->co_name, &moduleName);
                lineno = ((PyCodeObject33_35*)codeObj)->co_firstlineno;
            } else if (PyCodeObject36::IsFor(MajorVersion, MinorVersion)) {
                RegisterName(func, ((PyCodeObject36*)codeObj)->co_name, &moduleName);
                lineno = ((PyCodeObject36*)codeObj)->co_firstlineno;
            } else if (PyCodeObject37::IsFor(MajorVersion, MinorVersion)) {
                RegisterName(func, ((PyCodeObject37*)codeObj)->co_name, &moduleName);
                lineno = ((PyCodeObject37*)codeObj)->co_firstlineno;
            } else if (PyCodeObject38::IsFor(MajorVersion, MinorVersion)) {
                RegisterName(func, ((PyCodeObject38*)codeObj)->co_name, &moduleName);
                lineno = ((PyCodeObject38*)codeObj)->co_firstlineno;
            }

            // give the profiler the line number of this function
            _sourceLine(func, module, lineno);
        }
        return true;
    }
    return false;
}