demangle 0.5.2__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {demangle-0.5.2 → demangle-0.6.0}/.gitignore +3 -0
- {demangle-0.5.2 → demangle-0.6.0}/CHANGELOG.md +28 -1
- {demangle-0.5.2 → demangle-0.6.0}/CITATION.cff +1 -1
- {demangle-0.5.2 → demangle-0.6.0}/CONTRIBUTING.md +16 -1
- {demangle-0.5.2 → demangle-0.6.0}/PKG-INFO +8 -2
- {demangle-0.5.2 → demangle-0.6.0}/README.md +7 -1
- {demangle-0.5.2 → demangle-0.6.0}/SECURITY.md +2 -2
- demangle-0.6.0/benchmarks/baseline.json +68 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/bench.py +79 -8
- demangle-0.6.0/docs/hooks.py +80 -0
- demangle-0.6.0/docs/playground.md +34 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/reference/core.md +1 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/reference/schemes.md +1 -0
- {demangle-0.5.2 → demangle-0.6.0}/mkdocs.yml +4 -0
- demangle-0.6.0/playground/README.md +48 -0
- demangle-0.6.0/playground/index.html +275 -0
- demangle-0.6.0/playground/playground-worker.js +48 -0
- demangle-0.6.0/playground/playground.js +622 -0
- demangle-0.6.0/playground/playground_bridge.py +112 -0
- demangle-0.6.0/playground/style.css +932 -0
- {demangle-0.5.2 → demangle-0.6.0}/pyproject.toml +8 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/__init__.py +1 -1
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/cache.py +2 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/decorations.py +7 -1
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/errors.py +10 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/limits.py +2 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/plugin.py +2 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/reader.py +8 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/registry.py +13 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/spelling.py +10 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/style.py +8 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/itanium/options.py +2 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/msvc/__init__.py +3 -1
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/msvc/_parser.py +24 -2
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/msvc/nodes.py +35 -6
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/rust/__init__.py +11 -1
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/_printer.py +5 -2
- demangle-0.6.0/tests/browser/test_playground_browser.py +437 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/swift-upstream.txt +1 -1
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_benchmarks.py +16 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_msvc.py +96 -1
- demangle-0.6.0/tests/test_playground.py +173 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_swift.py +42 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/enumerate.py +8 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/upstream_drift.py +5 -1
- demangle-0.5.2/benchmarks/baseline.json +0 -38
- {demangle-0.5.2 → demangle-0.6.0}/ARCHITECTURE.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/CODE_OF_CONDUCT.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/CONFORMANCE.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/LICENSE +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/NOTICE +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_api.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_api_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_ast_optimization_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_cli_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_core.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_followup_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_graph.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_integrated_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_jni.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_nim.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_nim_optimization_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_objc.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_rust.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_rust_optimization_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_stream.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_swift.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/benchmarks/audit_swift_unicode_results.json +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/ARCHITECTURE.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/CHANGELOG.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/CONFORMANCE.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/CONTRIBUTING.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/SECURITY.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/adding-a-scheme.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/analysing-a-binary.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/index.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/labelling-a-symbol-table.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/reference/api.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/specs/itanium-grammar.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/docs/testing.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/__main__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/_signature.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/api.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/cli.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/ast.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/core/builder.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/filter.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/py.typed +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/ada/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/ada/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/ada/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/codewarrior/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/codewarrior/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/codewarrior/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/codewarrior/options.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/d/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/d/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/d/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/delphi/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/delphi/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/delphi/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/gnuv2/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/gnuv2/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/gnuv2/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/gnuv2/options.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/go/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/go/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/go/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/itanium/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/itanium/parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/itanium/substitutions.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/itanium/tables.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/jni/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/jni/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/jni/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/msvc/options.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/nim/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/nim/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/nim/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/objc/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/objc/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/objc/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/pascal/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/pascal/_parser.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/pascal/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/rust/_dispatch.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/rust/_legacy.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/rust/_v0.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/rust/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/rust/options.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/_demangler.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/_node.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/_old_demangler.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/_punycode.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/nodes.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/options.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/resolve.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/src/demangle/schemes/swift/symbolic.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/__init__.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/ada-libiberty.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/ada-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/codewarrior-cwdemangle.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/d-libiberty.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/d-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/delphi-constructs.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/delphi-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/delphi-refusals.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/delphi-tdump.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/gnuv2-libiberty.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/gnuv2-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/go-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/itanium-libcxxabi.txt.gz +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/itanium-libstdcxx.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/itanium-real-world-gnu.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/itanium-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/itanium-reference-defects.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/itanium-types-llvm.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/itanium-types.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/jni-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-arm64ec.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-boost.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-clang.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-dbghelp.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-llvm-corpus.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-name-only.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-reference-defects.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-suppressions.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/msvc-type-descriptors.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/nim-lossy.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/nim-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/objc-lossy.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/objc-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/objc-refusals.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/pascal-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/pascal-refusals.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/reported/d-gnu.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/reported/gnuv2-gnu.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/reported/itanium-gnu.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/reported/itanium.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/reported/rust.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/reported/swift.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/rust-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/rust-toolchain.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/rustc-upstream.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/swift-real-world.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/swift-reference-defects.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/swift-refusals.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/swift-simplified.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conformance/swift-symbolic.txt +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/conftest.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_ada.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_address_of.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_api.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_api_surface.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_architecture.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_cli.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_codewarrior.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_concurrency.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_conformance.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_core.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_d.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_delphi.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_differential.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_docs.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_expressions.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_gnu_expressions.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_gnuv2.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_go.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_invariants.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_itanium_apple_auto.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_itanium_closure_prefix.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_itanium_import_thunk.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_itanium_utf8.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_jni.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_limits.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_local_names.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_msvc_arm64ec.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_msvc_ast.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_msvc_descriptors.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_msvc_options.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_nim.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_objc.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_parity.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_pascal.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_readme.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_repro.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_robustness.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_rust.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_rust_ast.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_rust_consts.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_signature.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_special_names.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_substitution_parameters.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_swift_simplified.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_swift_symbolic.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_types.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tests/test_upstream_drift.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/features.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/go/go.mod +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/go/main.go +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/go/plain/lib.go +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/go/v2.5/lib.go +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/go/weird.pkg.name/lib.go +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/modern.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/modern23.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/msvc/modern.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/msvc/msvc.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/README.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/auto_marshall.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/closure_prefix.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/division.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/generic_lambda.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/inheriting_constructor.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/insort.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/insort_composite.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/member_template_lambda.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/prepare_execution.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/template_template_param.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/reference_defects/value_init_new.cpp +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/rust/consts.rs +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/rust/features.rs +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/rust/library.rs +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/corpus_sources/rust/types.rs +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/cplus-dem-reference/README.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/cplus-dem-reference/SHA256SUMS +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/cplus-dem-reference/build.sh +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/cplus-dem-reference/main.c +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/differential.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/generate_ada_corpus.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/generate_corpus.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/generate_d_corpus.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/generate_delphi_corpus.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/generate_go_corpus.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/generate_msvc_dbghelp_corpus.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/generate_rust_corpus.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/invariants.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/mutate.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/probe_substitutions.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/repro.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/rustc-demangle-reference/Cargo.lock +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/rustc-demangle-reference/Cargo.toml +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/rustc-demangle-reference/README.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/rustc-demangle-reference/src/main.rs +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/sweep_rust_chars.py +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/swift-demangle-reference/README.md +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/swift-demangle-reference/build.sh +0 -0
- {demangle-0.5.2 → demangle-0.6.0}/tools/swift-demangle-reference/main.cpp +0 -0
|
@@ -8,6 +8,32 @@ the reference demanglers, and a **Performance** section.
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [0.6.0] - 2026-10-11
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Preserve playground input and selected settings while its runtime loads. Scheme
|
|
16
|
+
selectors and output controls stay inside their columns on narrow screens and with
|
|
17
|
+
enlarged text. AST references reveal collapsed ancestors and support keyboard use.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- MSVC C++20 three-way comparison (`operator<=>`) and ARM64e pointer authentication
|
|
22
|
+
qualifiers, including their structured AST representation.
|
|
23
|
+
- Swift inverse conformance to `~Deinitable`, with module-name display options respected.
|
|
24
|
+
- A standalone browser playground with theme switching and keyboard shortcuts.
|
|
25
|
+
- Shareable playground links and the loaded library version, runtime retry controls,
|
|
26
|
+
and browser regression tests including a real Pyodide smoke test in CI.
|
|
27
|
+
- Bounded Swift and cross-scheme signature benchmarks with successful-work checks.
|
|
28
|
+
|
|
29
|
+
### Performance
|
|
30
|
+
|
|
31
|
+
- Run playground parsing in a worker and derive signature and AST data from one parse.
|
|
32
|
+
Output view changes reuse the result; AST expansion is lazy and paged with a display
|
|
33
|
+
budget while raw JSON remains complete.
|
|
34
|
+
- Deliver a deterministic, zipimportable source archive instead of a synthetic wheel
|
|
35
|
+
and duplicate base64 bundle.
|
|
36
|
+
|
|
11
37
|
## [0.5.2] - 2026-10-10
|
|
12
38
|
|
|
13
39
|
### Fixed
|
|
@@ -4037,7 +4063,8 @@ substitution table contents, pinned by name.
|
|
|
4037
4063
|
faster by doing less work.
|
|
4038
4064
|
- API reference published from docstrings at <https://r0ny123.github.io/demangle/>.
|
|
4039
4065
|
|
|
4040
|
-
[Unreleased]: https://github.com/r0ny123/demangle/compare/v0.
|
|
4066
|
+
[Unreleased]: https://github.com/r0ny123/demangle/compare/v0.6.0...HEAD
|
|
4067
|
+
[0.6.0]: https://github.com/r0ny123/demangle/compare/v0.5.2...v0.6.0
|
|
4041
4068
|
[0.5.2]: https://github.com/r0ny123/demangle/compare/v0.5.1...v0.5.2
|
|
4042
4069
|
[0.5.1]: https://github.com/r0ny123/demangle/compare/v0.5.0...v0.5.1
|
|
4043
4070
|
[0.5.0]: https://github.com/r0ny123/demangle/compare/v0.4.0...v0.5.0
|
|
@@ -40,7 +40,22 @@ Development requirements are [dependency groups](https://peps.python.org/pep-073
|
|
|
40
40
|
not extras. An extra is a *published* feature of the distribution -- `pip install
|
|
41
41
|
demangle[dev]` would appear on PyPI as something users are invited to install -- and a
|
|
42
42
|
linter is not a feature of a demangler. The groups are `test`, `format`, `lint`, `docs`,
|
|
43
|
-
and `dev`, which includes the first three.
|
|
43
|
+
`browser`, and `dev`, which includes the first three.
|
|
44
|
+
|
|
45
|
+
The browser suite is opt-in: it needs the browser dependency group, a built docs site,
|
|
46
|
+
and Chromium. It uses a deterministic fake worker for UI regressions; the real Pyodide
|
|
47
|
+
CDN smoke test is separately opt-in.
|
|
48
|
+
|
|
49
|
+
```console
|
|
50
|
+
uv pip install -e . --group browser --group docs --group test
|
|
51
|
+
python -m playwright install chromium
|
|
52
|
+
mkdocs build --strict
|
|
53
|
+
DEMANGLE_BROWSER_TESTS=1 python -m pytest -q tests/browser/test_playground_browser.py
|
|
54
|
+
|
|
55
|
+
# Also exercise Pyodide from its CDN, as the browser CI job does.
|
|
56
|
+
DEMANGLE_BROWSER_TESTS=1 DEMANGLE_PYODIDE_SMOKE=1 \
|
|
57
|
+
python -m pytest -q tests/browser/test_playground_browser.py
|
|
58
|
+
```
|
|
44
59
|
|
|
45
60
|
The toolchain is deliberately the fast one: **ruff** for linting and formatting (it
|
|
46
61
|
replaces black, isort, flake8 and pyupgrade), **ty** for type checking (it replaces
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: demangle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Read mangled symbol names -- Itanium C++, MSVC, Rust, Swift, Objective-C, Go, D, Nim, Free Pascal, Delphi, Ada/GNAT, JNI and pre-Itanium C++ (g++ 2.x, cfront/ARM, Lucid, HP aCC, CodeWarrior) -- in pure Python, with no dependencies.
|
|
5
5
|
Project-URL: Homepage, https://github.com/r0ny123/demangle
|
|
6
6
|
Project-URL: Documentation, https://r0ny123.github.io/demangle/
|
|
@@ -37,6 +37,7 @@ Description-Content-Type: text/markdown
|
|
|
37
37
|
[](https://www.python.org/downloads/)
|
|
38
38
|
[](https://github.com/r0ny123/demangle/blob/main/LICENSE)
|
|
39
39
|
[](https://r0ny123.github.io/demangle/)
|
|
40
|
+
[](https://r0ny123.github.io/demangle/playground/)
|
|
40
41
|
|
|
41
42
|
**Read mangled symbol names in pure Python** — Itanium C++ (GCC/Clang), MSVC, Rust,
|
|
42
43
|
Swift, Objective-C, Go, D, Nim, Free Pascal, Delphi, Ada/GNAT, JNI, and the pre-Itanium
|
|
@@ -89,7 +90,8 @@ pip install demangle
|
|
|
89
90
|
Python 3.11 or newer, on CPython or PyPy. That is the whole dependency list.
|
|
90
91
|
|
|
91
92
|
The documentation, API reference included, is published at
|
|
92
|
-
<https://r0ny123.github.io/demangle/>.
|
|
93
|
+
<https://r0ny123.github.io/demangle/>. An interactive in-browser playground is available
|
|
94
|
+
at <https://r0ny123.github.io/demangle/playground/>.
|
|
93
95
|
|
|
94
96
|
## Use
|
|
95
97
|
|
|
@@ -320,6 +322,9 @@ Swift's own 217 vectors:
|
|
|
320
322
|
```console
|
|
321
323
|
$ nm -a libfoo.so | demangle
|
|
322
324
|
$ demangle _ZNSt6vectorIiSaIiEE9push_backERKi
|
|
325
|
+
$ demangle -b _ZN3foo3barEv # `mangled ==> demangled`
|
|
326
|
+
$ demangle -m _ZN3foo3barEv # only print successfully demangled symbols
|
|
327
|
+
$ demangle -s gnu _ZNSt6vectorIiSaIiEE9push_backERKi # choose output style (llvm, gnu)
|
|
323
328
|
$ demangle --tree _Z1fPKc
|
|
324
329
|
$ demangle --detect _RNvC6_123foo3bar
|
|
325
330
|
$ demangle --detect --strict _ZN3Foo # the scheme that reads it, or an error
|
|
@@ -338,6 +343,7 @@ $ demangle --json _Z1fPi # the parse tree as JSON
|
|
|
338
343
|
$ nm -a libfoo.so | demangle --json-lines # a JSON object per symbol
|
|
339
344
|
$ demangle --json-lines --signature _Z1fPi # ... with the parts of the name
|
|
340
345
|
$ printf '%s\0' "$name" | demangle -0 # whole names ended by NUL, in and out
|
|
346
|
+
$ demangle --list-languages # list supported schemes and aliases
|
|
341
347
|
```
|
|
342
348
|
|
|
343
349
|
`--json-lines` writes one object per name, `{"mangled": ..., "demangled": ...,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://www.python.org/downloads/)
|
|
5
5
|
[](https://github.com/r0ny123/demangle/blob/main/LICENSE)
|
|
6
6
|
[](https://r0ny123.github.io/demangle/)
|
|
7
|
+
[](https://r0ny123.github.io/demangle/playground/)
|
|
7
8
|
|
|
8
9
|
**Read mangled symbol names in pure Python** — Itanium C++ (GCC/Clang), MSVC, Rust,
|
|
9
10
|
Swift, Objective-C, Go, D, Nim, Free Pascal, Delphi, Ada/GNAT, JNI, and the pre-Itanium
|
|
@@ -56,7 +57,8 @@ pip install demangle
|
|
|
56
57
|
Python 3.11 or newer, on CPython or PyPy. That is the whole dependency list.
|
|
57
58
|
|
|
58
59
|
The documentation, API reference included, is published at
|
|
59
|
-
<https://r0ny123.github.io/demangle/>.
|
|
60
|
+
<https://r0ny123.github.io/demangle/>. An interactive in-browser playground is available
|
|
61
|
+
at <https://r0ny123.github.io/demangle/playground/>.
|
|
60
62
|
|
|
61
63
|
## Use
|
|
62
64
|
|
|
@@ -287,6 +289,9 @@ Swift's own 217 vectors:
|
|
|
287
289
|
```console
|
|
288
290
|
$ nm -a libfoo.so | demangle
|
|
289
291
|
$ demangle _ZNSt6vectorIiSaIiEE9push_backERKi
|
|
292
|
+
$ demangle -b _ZN3foo3barEv # `mangled ==> demangled`
|
|
293
|
+
$ demangle -m _ZN3foo3barEv # only print successfully demangled symbols
|
|
294
|
+
$ demangle -s gnu _ZNSt6vectorIiSaIiEE9push_backERKi # choose output style (llvm, gnu)
|
|
290
295
|
$ demangle --tree _Z1fPKc
|
|
291
296
|
$ demangle --detect _RNvC6_123foo3bar
|
|
292
297
|
$ demangle --detect --strict _ZN3Foo # the scheme that reads it, or an error
|
|
@@ -305,6 +310,7 @@ $ demangle --json _Z1fPi # the parse tree as JSON
|
|
|
305
310
|
$ nm -a libfoo.so | demangle --json-lines # a JSON object per symbol
|
|
306
311
|
$ demangle --json-lines --signature _Z1fPi # ... with the parts of the name
|
|
307
312
|
$ printf '%s\0' "$name" | demangle -0 # whole names ended by NUL, in and out
|
|
313
|
+
$ demangle --list-languages # list supported schemes and aliases
|
|
308
314
|
```
|
|
309
315
|
|
|
310
316
|
`--json-lines` writes one object per name, `{"mangled": ..., "demangled": ...,
|
|
@@ -91,8 +91,8 @@ name that caused it rather than being killed.
|
|
|
91
91
|
|
|
92
92
|
| Version | Supported |
|
|
93
93
|
| --- | --- |
|
|
94
|
-
| 0.
|
|
95
|
-
| < 0.
|
|
94
|
+
| 0.5.x | yes |
|
|
95
|
+
| < 0.5 | no |
|
|
96
96
|
|
|
97
97
|
Until 1.0, security fixes land on the latest released minor version only. There is no
|
|
98
98
|
long-term support branch and no backporting; upgrading to the current minor version is
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cold": {
|
|
3
|
+
"names": 14101,
|
|
4
|
+
"seconds": 0.648513,
|
|
5
|
+
"per_second": 21744,
|
|
6
|
+
"microseconds_each": 45.991,
|
|
7
|
+
"normalised": 1329.407,
|
|
8
|
+
"relative_to_pivot": 123.19
|
|
9
|
+
},
|
|
10
|
+
"warm": {
|
|
11
|
+
"names": 42303,
|
|
12
|
+
"seconds": 0.015793,
|
|
13
|
+
"per_second": 2678592,
|
|
14
|
+
"microseconds_each": 0.373,
|
|
15
|
+
"normalised": 10.792
|
|
16
|
+
},
|
|
17
|
+
"negative": {
|
|
18
|
+
"names": 14101,
|
|
19
|
+
"seconds": 0.011647,
|
|
20
|
+
"per_second": 1210698,
|
|
21
|
+
"microseconds_each": 0.826,
|
|
22
|
+
"normalised": 23.876,
|
|
23
|
+
"relative_to_pivot": 2.2124
|
|
24
|
+
},
|
|
25
|
+
"structured": {
|
|
26
|
+
"names": 636,
|
|
27
|
+
"seconds": 0.035171,
|
|
28
|
+
"per_second": 18083,
|
|
29
|
+
"microseconds_each": 55.3,
|
|
30
|
+
"parsed": 636,
|
|
31
|
+
"normalised": 1598.062,
|
|
32
|
+
"relative_to_pivot": 148.0849
|
|
33
|
+
},
|
|
34
|
+
"calibration": {
|
|
35
|
+
"seconds": 0.034605,
|
|
36
|
+
"rounds": 200000
|
|
37
|
+
},
|
|
38
|
+
"swift": {
|
|
39
|
+
"names": 256,
|
|
40
|
+
"seconds": 0.0181,
|
|
41
|
+
"per_second": 14174,
|
|
42
|
+
"microseconds_each": 70.55,
|
|
43
|
+
"succeeded": 256,
|
|
44
|
+
"normalised": 2303.46,
|
|
45
|
+
"relative_to_pivot": 336.776,
|
|
46
|
+
"recorded_on": "GitHub Actions ubuntu-24.04, CPython 3.13.16; run 38108232827"
|
|
47
|
+
},
|
|
48
|
+
"swift_parse": {
|
|
49
|
+
"names": 256,
|
|
50
|
+
"seconds": 0.0213,
|
|
51
|
+
"per_second": 12046,
|
|
52
|
+
"microseconds_each": 83.02,
|
|
53
|
+
"succeeded": 256,
|
|
54
|
+
"normalised": 2710.43,
|
|
55
|
+
"relative_to_pivot": 396.277,
|
|
56
|
+
"recorded_on": "GitHub Actions ubuntu-24.04, CPython 3.13.16; run 38108232827"
|
|
57
|
+
},
|
|
58
|
+
"signature": {
|
|
59
|
+
"names": 1280,
|
|
60
|
+
"seconds": 0.0963,
|
|
61
|
+
"per_second": 13289,
|
|
62
|
+
"microseconds_each": 75.25,
|
|
63
|
+
"succeeded": 1280,
|
|
64
|
+
"normalised": 2456.81,
|
|
65
|
+
"relative_to_pivot": 359.197,
|
|
66
|
+
"recorded_on": "GitHub Actions ubuntu-24.04, CPython 3.13.16; run 38108232827"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -22,6 +22,10 @@ reproducible on a given interpreter, and fewer calls for the same output is stri
|
|
|
22
22
|
less work, so it reports what the clock cannot. It is a report and not a gate: the count
|
|
23
23
|
moves with the interpreter version as well as with this package, and a gate that fails
|
|
24
24
|
on someone else's Python would be worse than none.
|
|
25
|
+
|
|
26
|
+
The Swift phases use a bounded prefix of the real-world corpus, so the additional AST
|
|
27
|
+
work stays quick. `signature` exercises extraction across several schemes without
|
|
28
|
+
making the main corpus-sized workloads larger.
|
|
25
29
|
"""
|
|
26
30
|
|
|
27
31
|
import argparse
|
|
@@ -58,6 +62,7 @@ TOLERANCE = 1.25
|
|
|
58
62
|
PIVOT = "warm"
|
|
59
63
|
|
|
60
64
|
CALIBRATION_ROUNDS = 200_000
|
|
65
|
+
SPECIALIZED_SAMPLE_SIZE = 256
|
|
61
66
|
|
|
62
67
|
|
|
63
68
|
def calibrate():
|
|
@@ -135,6 +140,11 @@ def corpus_names(*files):
|
|
|
135
140
|
return names
|
|
136
141
|
|
|
137
142
|
|
|
143
|
+
def corpus_sample(filename, limit):
|
|
144
|
+
"""Read at most `limit` manglings from one conformance corpus."""
|
|
145
|
+
return corpus_names(filename)[:limit]
|
|
146
|
+
|
|
147
|
+
|
|
138
148
|
def time_it(function, repeats=5):
|
|
139
149
|
"""Best-of-N wall time. Best, not mean: the minimum is the least noisy estimator."""
|
|
140
150
|
timings = []
|
|
@@ -163,6 +173,16 @@ def benchmarks():
|
|
|
163
173
|
)
|
|
164
174
|
negatives = [f"not_a_mangled_symbol_{index}" for index in range(len(sampled))]
|
|
165
175
|
|
|
176
|
+
# Keep these focused paths representative without making the benchmark unbounded.
|
|
177
|
+
swift = corpus_sample("swift-real-world.txt", SPECIALIZED_SAMPLE_SIZE)
|
|
178
|
+
signature_inputs = [
|
|
179
|
+
("itanium", corpus_sample("itanium-real-world.txt", SPECIALIZED_SAMPLE_SIZE)),
|
|
180
|
+
("msvc", corpus_sample("msvc-llvm-corpus.txt", SPECIALIZED_SAMPLE_SIZE)),
|
|
181
|
+
("rust", corpus_sample("rust-real-world.txt", SPECIALIZED_SAMPLE_SIZE)),
|
|
182
|
+
("go", corpus_sample("go-real-world.txt", SPECIALIZED_SAMPLE_SIZE)),
|
|
183
|
+
("swift", swift),
|
|
184
|
+
]
|
|
185
|
+
|
|
166
186
|
def cold():
|
|
167
187
|
demangle.cache_clear()
|
|
168
188
|
for name in sampled:
|
|
@@ -193,17 +213,59 @@ def benchmarks():
|
|
|
193
213
|
count += 1
|
|
194
214
|
parsed.append(count)
|
|
195
215
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
216
|
+
swift_demangled = []
|
|
217
|
+
|
|
218
|
+
def swift_demangle():
|
|
219
|
+
# Keep this parse-oriented measurement independent of the cache left by
|
|
220
|
+
# `time_it`'s earlier repeats.
|
|
221
|
+
demangle.cache_clear()
|
|
222
|
+
count = 0
|
|
223
|
+
for name in swift:
|
|
224
|
+
# `demangle` intentionally returns unsupported input unchanged. Counting
|
|
225
|
+
# changed spellings prevents a fast refusal from looking successful.
|
|
226
|
+
count += demangle.demangle(name, language="swift") != name
|
|
227
|
+
swift_demangled.append(count)
|
|
228
|
+
|
|
229
|
+
swift_parsed = []
|
|
230
|
+
|
|
231
|
+
def swift_parse():
|
|
232
|
+
count = 0
|
|
233
|
+
for name in swift:
|
|
234
|
+
with contextlib.suppress(Exception):
|
|
235
|
+
demangle.parse(name, language="swift")
|
|
236
|
+
count += 1
|
|
237
|
+
swift_parsed.append(count)
|
|
238
|
+
|
|
239
|
+
signatures = []
|
|
240
|
+
|
|
241
|
+
def signature():
|
|
242
|
+
count = 0
|
|
243
|
+
for language, names in signature_inputs:
|
|
244
|
+
for name in names:
|
|
245
|
+
with contextlib.suppress(Exception):
|
|
246
|
+
demangle.signature(name, language=language)
|
|
247
|
+
count += 1
|
|
248
|
+
signatures.append(count)
|
|
249
|
+
|
|
250
|
+
successes = {"swift": swift_demangled, "swift_parse": swift_parsed, "signature": signatures}
|
|
251
|
+
return (
|
|
252
|
+
parsed,
|
|
253
|
+
successes,
|
|
254
|
+
[
|
|
255
|
+
("cold", cold, len(sampled)),
|
|
256
|
+
("warm", warm, len(sampled) * 3),
|
|
257
|
+
("negative", negative, len(negatives)),
|
|
258
|
+
("structured", structured, len(itanium) * structured_passes),
|
|
259
|
+
("swift", swift_demangle, len(swift)),
|
|
260
|
+
("swift_parse", swift_parse, len(swift)),
|
|
261
|
+
("signature", signature, sum(len(names) for _, names in signature_inputs)),
|
|
262
|
+
],
|
|
263
|
+
)
|
|
202
264
|
|
|
203
265
|
|
|
204
266
|
def run():
|
|
205
267
|
results = {}
|
|
206
|
-
parsed, cases = benchmarks()
|
|
268
|
+
parsed, successes, cases = benchmarks()
|
|
207
269
|
reference = calibrate()
|
|
208
270
|
for name, function, count in cases:
|
|
209
271
|
if not count:
|
|
@@ -218,6 +280,9 @@ def run():
|
|
|
218
280
|
}
|
|
219
281
|
if "structured" in results:
|
|
220
282
|
results["structured"]["parsed"] = parsed[-1] if parsed else 0
|
|
283
|
+
for name, counts in successes.items():
|
|
284
|
+
if name in results:
|
|
285
|
+
results[name]["succeeded"] = counts[-1] if counts else 0
|
|
221
286
|
for data in results.values():
|
|
222
287
|
data["normalised"] = round(data["seconds"] / data["names"] / reference * 1e6, 3)
|
|
223
288
|
|
|
@@ -258,7 +323,7 @@ def calls():
|
|
|
258
323
|
import pstats
|
|
259
324
|
|
|
260
325
|
counted = {}
|
|
261
|
-
_, cases = benchmarks()
|
|
326
|
+
_, _, cases = benchmarks()
|
|
262
327
|
for name, function, count in cases:
|
|
263
328
|
if not count:
|
|
264
329
|
continue
|
|
@@ -315,6 +380,12 @@ def main():
|
|
|
315
380
|
print(f"\nstructured benchmark parsed {structured.get('parsed')} of {structured.get('names')} names")
|
|
316
381
|
print("a timing that improved because the work stopped happening is not an improvement")
|
|
317
382
|
return 1
|
|
383
|
+
for name in ("swift", "swift_parse", "signature"):
|
|
384
|
+
phase = results.get(name, {})
|
|
385
|
+
if phase.get("succeeded") != phase.get("names"):
|
|
386
|
+
print(f"\n{name} benchmark succeeded on {phase.get('succeeded', 0)} of {phase.get('names', 0)} names")
|
|
387
|
+
print("a timing that improved because the work stopped happening is not an improvement")
|
|
388
|
+
return 1
|
|
318
389
|
# A shrunken corpus would also time as an improvement.
|
|
319
390
|
shrunk = [
|
|
320
391
|
(name, results[name]["names"], baseline[name]["names"])
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""MkDocs hook: package the pure-Python source for the browser playground and merge standalone app."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import io
|
|
6
|
+
import shutil
|
|
7
|
+
import stat
|
|
8
|
+
import zipfile
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
_ZIP_EPOCH = (1980, 1, 1, 0, 0, 0)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def build_assets(root_dir: Path | None = None) -> Path:
|
|
16
|
+
"""Build a deterministic zipimportable archive of ``src/demangle``."""
|
|
17
|
+
if root_dir is None:
|
|
18
|
+
root_dir = Path(__file__).resolve().parent.parent
|
|
19
|
+
|
|
20
|
+
src = root_dir / "src" / "demangle"
|
|
21
|
+
if not (src / "__init__.py").is_file():
|
|
22
|
+
raise FileNotFoundError(f"demangle source package missing: {src}")
|
|
23
|
+
|
|
24
|
+
buf = io.BytesIO()
|
|
25
|
+
notices = [root_dir / name for name in ("LICENSE", "NOTICE")]
|
|
26
|
+
with zipfile.ZipFile(buf, "w") as archive:
|
|
27
|
+
for path in [*sorted(src.rglob("*")), *notices]:
|
|
28
|
+
if not path.is_file() or path.suffix == ".pyc" or "__pycache__" in path.parts:
|
|
29
|
+
continue
|
|
30
|
+
name = path.name if path in notices else path.relative_to(src.parent).as_posix()
|
|
31
|
+
info = zipfile.ZipInfo(name, _ZIP_EPOCH)
|
|
32
|
+
info.compress_type = zipfile.ZIP_DEFLATED
|
|
33
|
+
info.create_system = 3
|
|
34
|
+
info.external_attr = (stat.S_IFREG | 0o644) << 16
|
|
35
|
+
archive.writestr(info, path.read_bytes(), compress_type=zipfile.ZIP_DEFLATED, compresslevel=9)
|
|
36
|
+
|
|
37
|
+
archive_bytes = buf.getvalue()
|
|
38
|
+
|
|
39
|
+
# Emit to playground/assets/ (for standalone playground)
|
|
40
|
+
playground_assets = root_dir / "playground" / "assets"
|
|
41
|
+
playground_assets.mkdir(parents=True, exist_ok=True)
|
|
42
|
+
playground_zip = playground_assets / "demangle.zip"
|
|
43
|
+
playground_zip.write_bytes(archive_bytes)
|
|
44
|
+
|
|
45
|
+
# Also emit to docs/assets/ for backwards compatibility
|
|
46
|
+
docs_assets = root_dir / "docs" / "assets"
|
|
47
|
+
docs_assets.mkdir(parents=True, exist_ok=True)
|
|
48
|
+
docs_zip = docs_assets / "demangle.zip"
|
|
49
|
+
docs_zip.write_bytes(archive_bytes)
|
|
50
|
+
|
|
51
|
+
(docs_assets / "demangle.whl").unlink(missing_ok=True)
|
|
52
|
+
(docs_assets / "demangle_bundle.js").unlink(missing_ok=True)
|
|
53
|
+
(playground_assets / "demangle.whl").unlink(missing_ok=True)
|
|
54
|
+
(playground_assets / "demangle_bundle.js").unlink(missing_ok=True)
|
|
55
|
+
|
|
56
|
+
return playground_zip
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def on_pre_build(config: Any) -> None:
|
|
60
|
+
"""MkDocs pre-build event hook."""
|
|
61
|
+
build_assets()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def on_post_build(config: Any) -> None:
|
|
65
|
+
"""MkDocs post-build event hook: merge standalone playground into site output."""
|
|
66
|
+
site_dir = Path(config["site_dir"])
|
|
67
|
+
playground_src = Path(__file__).resolve().parent.parent / "playground"
|
|
68
|
+
playground_dest = site_dir / "playground"
|
|
69
|
+
if playground_src.exists():
|
|
70
|
+
shutil.copytree(
|
|
71
|
+
playground_src,
|
|
72
|
+
playground_dest,
|
|
73
|
+
dirs_exist_ok=True,
|
|
74
|
+
ignore=shutil.ignore_patterns("__pycache__", "*.pyc"),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
path = build_assets()
|
|
80
|
+
print(f"Generated archive: {path} ({path.stat().st_size} bytes)")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Interactive Demangling Playground
|
|
2
|
+
|
|
3
|
+
Explore mangled symbols interactively in your browser. All demangling, scheme detection, structured signature extraction, and AST graph parsing run entirely client-side using **WebAssembly** via [Pyodide](https://pyodide.org/). Symbols stay in your browser. The runtime is downloaded from a CDN on first load; demangling needs no server requests after initialization.
|
|
4
|
+
|
|
5
|
+
<div style="margin: 2rem 0; text-align: center;">
|
|
6
|
+
<a href="https://r0ny123.github.io/demangle/playground/" class="md-button md-button--primary" style="font-size: 1.1rem; padding: 0.75rem 2.25rem;">
|
|
7
|
+
🚀 Launch Fullscreen Playground
|
|
8
|
+
</a>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **100% Client-Side Privacy**: Runs locally in your browser via [Pyodide](https://pyodide.org/) WebAssembly. No symbols or code leave your machine.
|
|
14
|
+
- **Dedicated Web Worker**: Parsing executes in a dedicated Web Worker off the main thread, keeping the user interface completely non-blocking during large syntax graph rendering.
|
|
15
|
+
- **14 Scheme Coverage**: Auto-detects or manually targets all 14 supported ABI schemes:
|
|
16
|
+
- Itanium C++ (GCC, Clang)
|
|
17
|
+
- Microsoft Visual C++ (MSVC)
|
|
18
|
+
- Swift (including Swift 6 invertible protocol constraints)
|
|
19
|
+
- Rust (legacy and v0)
|
|
20
|
+
- D
|
|
21
|
+
- Go
|
|
22
|
+
- Nim
|
|
23
|
+
- Free Pascal
|
|
24
|
+
- Delphi / C++Builder
|
|
25
|
+
- Ada / GNAT
|
|
26
|
+
- Java Native Interface (JNI)
|
|
27
|
+
- Objective-C
|
|
28
|
+
- CodeWarrior C++
|
|
29
|
+
- GNU v2 (pre-Itanium g++ 2.x, cfront/ARM, Lucid, HP aCC)
|
|
30
|
+
- **Formatting Styles**: Switch between standard LLVM style and GNU style (spacing, template formatting).
|
|
31
|
+
- **Output Formats**: Full demangled signature, both (input and demangled), base name only, or signature without parameters.
|
|
32
|
+
- **Structured Signature Decomposition**: Unpacks symbols into qualified name, base name, namespace scope, parameter list, return type, calling convention, and qualifiers via `demangle.signature()`.
|
|
33
|
+
- **Interactive AST Inspector**: Explore the abstract syntax tree hierarchically with collapsible nodes, lazy pagination for large graphs, jump navigation for shared references (`$ref`), or copy complete JSON syntax graphs.
|
|
34
|
+
- **Permalinks & Sharing**: State is automatically encoded into URL hash fragments for one-click sharing.
|
|
@@ -5,8 +5,12 @@ repo_url: https://github.com/r0ny123/demangle
|
|
|
5
5
|
repo_name: r0ny123/demangle
|
|
6
6
|
edit_uri: edit/main/
|
|
7
7
|
|
|
8
|
+
hooks:
|
|
9
|
+
- docs/hooks.py
|
|
10
|
+
|
|
8
11
|
nav:
|
|
9
12
|
- Home: index.md
|
|
13
|
+
- Playground: playground.md
|
|
10
14
|
- Working with the tree: analysing-a-binary.md
|
|
11
15
|
- Labelling a symbol table: labelling-a-symbol-table.md
|
|
12
16
|
- API reference:
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# demangle Playground
|
|
2
|
+
|
|
3
|
+
[](https://r0ny123.github.io/demangle/playground/)
|
|
4
|
+
|
|
5
|
+
Read, decompose and explore mangled symbol names interactively in your browser. Everything runs locally on **WebAssembly** via [Pyodide](https://pyodide.org/). Nothing to install, no backend servers, and zero network data transmission.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Zero-Network Privacy**: Demangling, signature extraction, and AST parsing execute 100% client-side in WebAssembly. Your symbol names and binary details never leave your machine.
|
|
10
|
+
- **Real-Time Evaluation**: Instant debounced demangling as you type or paste symbols.
|
|
11
|
+
- **Full Scheme Coverage**: Auto-detects or explicitly overrides all 14 supported ABI schemes:
|
|
12
|
+
- Itanium C++ (GCC, Clang)
|
|
13
|
+
- Microsoft Visual C++ (MSVC)
|
|
14
|
+
- Swift (including Swift 6 invertible protocol constraints)
|
|
15
|
+
- Rust (legacy and v0)
|
|
16
|
+
- D
|
|
17
|
+
- Go
|
|
18
|
+
- Nim
|
|
19
|
+
- Free Pascal
|
|
20
|
+
- Delphi / C++Builder
|
|
21
|
+
- Ada / GNAT
|
|
22
|
+
- Java Native Interface (JNI)
|
|
23
|
+
- Objective-C
|
|
24
|
+
- CodeWarrior C++
|
|
25
|
+
- GNU v2 (pre-Itanium g++ 2.x, cfront/ARM, Lucid, HP aCC)
|
|
26
|
+
- **Signature Decomposition**: Deconstructs symbols into qualified name, base name, namespace/scope, parameters list, return type, calling convention, and qualifiers.
|
|
27
|
+
- **Interactive AST Visualizer**: Collapsible syntax graph tree view with shared reference (`$ref`) jump navigation and formatted JSON export.
|
|
28
|
+
- **URL Permalinks**: Automatically syncs symbol and option state into URL hash fragments (`#symbol=...&language=...`) for one-click sharing.
|
|
29
|
+
- **Light & Dark Themes**: Synchronized with system preferences and persistent across reloads.
|
|
30
|
+
|
|
31
|
+
## Keyboard Shortcuts
|
|
32
|
+
|
|
33
|
+
| Shortcut | Action |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `Ctrl / Cmd + K` | Focus mangled symbol input |
|
|
36
|
+
| `Esc` | Clear symbol input |
|
|
37
|
+
| `Ctrl / Cmd + Enter` | Force re-evaluation |
|
|
38
|
+
|
|
39
|
+
## Running Locally
|
|
40
|
+
|
|
41
|
+
To run the standalone playground locally:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# From repository root:
|
|
45
|
+
python -m http.server 8000
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Then open `http://localhost:8000/playground/` in your browser.
|