Skip to content

Some optimizations#11

Merged
Mx-Iris merged 3 commits intomainfrom
develop
Jun 16, 2025
Merged

Some optimizations#11
Mx-Iris merged 3 commits intomainfrom
develop

Conversation

@Mx-Iris
Copy link
Member

@Mx-Iris Mx-Iris commented Jun 16, 2025

@Mx-Iris Mx-Iris requested a review from Copilot June 16, 2025 14:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements several optimizations including switching DumpCommand to an actor for improved concurrency safety, enabling experimental prebuilts for macros, and updating the DemangleOptions preset configuration.

  • Changed build scripts to pass the --enable-experimental-prebuilts flag
  • Refactored DumpCommand from a struct to a final actor and updated its async dump methods
  • Revised the DemangleOptions.interface preset and updated dependency version constraints in Package.swift

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
build-executable-product.sh Added the --enable-experimental-prebuilts flag to Swift build commands
Sources/swift-section/DumpCommand.swift Converted DumpCommand to an actor; updated async methods to use performDump for dumping
Sources/Semantic/SemanticStringBuilder.swift Added overloads for building a SemanticString from CustomStringConvertible values
Sources/MachOSwiftSection/MachOFile+Swift.swift Removed debugging prints
Sources/MachOExtensions/String+.swift Updated string comparison functions using withUnsafePointer and withCString
Sources/Demangle/Main/DemangleOptions.swift Updated DemangleOptions.interface to remove and insert options using a computed property
Package.swift Revised dependency versions and syntax for Swift packages

}

private mutating func dumpOrPrint(_ semanticString: SemanticString) {
private func dumpOrPrint(_ string: String) {
Copy link

Copilot AI Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The performDump closure returns a SemanticString, yet dumpOrPrint now expects a String. To ensure type consistency, convert the SemanticString to a String (e.g. using its string property) before passing it to dumpOrPrint.

Copilot uses AI. Check for mistakes.
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @Mx-Iris, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces several optimizations and refinements across the codebase. Key changes include migrating the DumpCommand to an actor for improved concurrency, enabling experimental prebuilts for faster compilation, and fine-tuning demangling options. Additionally, string comparison performance has been enhanced, and the semantic string building utility has been made more versatile. Dependency sources have also been updated to align with more official repositories.

Highlights

  • Concurrency Model Update: The DumpCommand struct has been refactored into a final actor, enabling safer concurrent operations and better managing its internal state. This change also involved removing mutating keywords and @MainActor attributes from its methods, as actor methods are implicitly isolated.
  • Build System Optimization: The build script (build-executable-product.sh) has been updated to enable experimental prebuilt modules (--enable-experimental-prebuilts) for both x86_64 and arm64 architectures, which can significantly speed up compilation times.
  • Demangling Options Refinement: The DemangleOptions.interface preset has been updated to provide a more refined and concise output by starting from the default options and then explicitly removing certain verbose flags (e.g., displayObjCModule, displayWhereClauses).
  • Performance Optimization: String comparison methods (isEqual) for CCharTuple16 and CCharTuple32 have been optimized to use strcmp directly on C strings, which is more performant than converting to Swift String objects for comparison. The @inline(__always) attribute was also added for further optimization hints.
  • Dependency Management: Several package dependencies in Package.resolved and Package.swift have been updated, primarily changing their source repositories from forks or precompiled versions to what appear to be their upstream or more official locations (e.g., swift-syntax from swift-precompiled to swiftlang, AssociatedObject from MxIris-Library-Forks to p-x9). Version constraints for swift-syntax and Rainbow were also adjusted.
  • Semantic String Builder Enhancement: The SemanticStringBuilder now includes new buildPartialBlock overloads, allowing it to directly accept any CustomStringConvertible type, improving its flexibility and ease of use when constructing semantic strings.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request includes several optimizations and updates, including switching a struct to an actor, enabling experimental prebuilts for macros, and updating preset demangle options. The changes also involve updates to package dependencies and improvements to string comparison and data dumping logic. Several suggestions were made to improve code safety, maintainability, and clarity.

Comment on lines +83 to +87
if let metadata: StructMetadata = try await metadataFinder?.metadata(for: structDescriptor) {
await performDump {
try metadata.fieldOffsets(for: structDescriptor, in: machO)
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The metadataFinder?.metadata call is fallible, but the result is force-cast to StructMetadata. If the metadata is not of the expected type, this will cause a crash. Use a conditional cast (as?) and handle the case where the metadata is not of the expected type.

                    if let metadata = try await metadataFinder?.metadata(for: structDescriptor) as? StructMetadata {
                        await performDump {
                            try metadata.fieldOffsets(for: structDescriptor, in: machO)
                        }
                    }

Comment on lines +93 to 97
if let metadata = try await metadataFinder?.metadata(for: classDescriptor) as ClassMetadataObjCInterop? {
await performDump {
try metadata.fieldOffsets(for: classDescriptor, in: machO)
}
} catch {
dumpError(error)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The metadataFinder?.metadata call is fallible, but the result is force-cast to ClassMetadataObjCInterop. If the metadata is not of the expected type, this will cause a crash. Use a conditional cast (as?) and handle the case where the metadata is not of the expected type.

                    if let metadata = try await metadataFinder?.metadata(for: classDescriptor) as? ClassMetadataObjCInterop {
                        await performDump {
                            try metadata.fieldOffsets(for: classDescriptor, in: machO)
                        }
                    }

Comment on lines 44 to +49
package func isEqual(to tuple: CCharTuple16) -> Bool {
self == String(tuple: tuple)
withUnsafePointer(to: tuple) { tuple in
withCString { str in
strcmp(str, tuple) == 0
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using strcmp directly can be unsafe if tuple is not null-terminated. While CCharTuple16 and CCharTuple32 are likely null-terminated due to the Data conversion in the init(tuple:) methods, it's better to use strncmp with a size limit to prevent potential buffer overflows if the data isn't properly null-terminated. This is especially important when dealing with C strings.

        withUnsafePointer(to: tuple) { tuple in
            withCString { str in
                strncmp(str, tuple, MemoryLayout.size(ofValue: tuple)) == 0
            }
        }

Comment on lines 53 to +58
package func isEqual(to tuple: CCharTuple32) -> Bool {
self == String(tuple: tuple)
withUnsafePointer(to: tuple) { tuple in
withCString { str in
strcmp(str, tuple) == 0
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using strcmp directly can be unsafe if tuple is not null-terminated. While CCharTuple16 and CCharTuple32 are likely null-terminated due to the Data conversion in the init(tuple:) methods, it's better to use strncmp with a size limit to prevent potential buffer overflows if the data isn't properly null-terminated. This is especially important when dealing with C strings.

        withUnsafePointer(to: tuple) { tuple in
            withCString { str in
                strncmp(str, tuple, MemoryLayout.size(ofValue: tuple)) == 0
            }
        }

.MachOKit,
.package(url: "https://github.com/swift-precompiled/swift-syntax.git", from: "601.0.1"),
.package(url: "https://github.com/MxIris-Library-Forks/AssociatedObject", from: "0.13.0"),
.package(url: "https://github.com/swiftlang/swift-syntax.git", "509.1.0"..<"602.0.0"),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider using a more specific version range for swift-syntax to avoid unexpected breaking changes. Using ..< is good, but consider tightening the lower bound if you know a specific version is required.

Suggested change
.package(url: "https://github.com/swiftlang/swift-syntax.git", "509.1.0"..<"602.0.0"),
.package(url: "https://github.com/swiftlang/swift-syntax.git", "601.0.1"..<"602.0.0"),


@MainActor
private mutating func dumpTypes(using options: DemangleOptions, in machO: MachOFile) async throws {
private func dumpTypes(using options: DemangleOptions, in machO: MachOFile) async throws {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The @MainActor attribute is applied to dumpTypes, but the operations within this function involve asynchronous calls to metadataFinder?.metadata. Ensure that MetadataFinder and its metadata method are also thread-safe or confined to the main actor to prevent potential race conditions or data corruption when accessing or modifying shared state.

Comment on lines +157 to 163
private func dumpOrPrint(_ string: String) {
if outputPath != nil {
dumpedString.append(semanticString.string)
dumpedString.append(string)
dumpedString.append("\n")
} else {
print(semanticString.components.map { $0.string.withColor(for: $0.type, colorScheme: colorScheme) }.joined())
print(string)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There are two dumpOrPrint methods, one taking a semanticString and another taking a String. The method taking a String is only used in dumpError. Consider unifying these methods to reduce code duplication and improve maintainability. You could have a single dumpOrPrint method that takes a CustomStringConvertible and handles both SemanticString and String types.

@Mx-Iris Mx-Iris merged commit 5efc747 into main Jun 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants