Skip to content
Merged
Show file tree
Hide file tree
Changes from 114 commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
eb5f169
Basic LLDB remote protocol scaffolding
MaxDesiatov Oct 8, 2025
0baf7a5
Implement more packet handling, update naming
MaxDesiatov Oct 8, 2025
85a695a
Provide original license notice in `wasmkit-gdb-tool/Entrypoint.swift`
MaxDesiatov Oct 8, 2025
eba97a0
Apply formatter
MaxDesiatov Oct 8, 2025
6546754
Make naming of types more specific to avoid future collisions
MaxDesiatov Oct 8, 2025
7b2c6f6
More cleanups for type naming
MaxDesiatov Oct 8, 2025
4a1c998
Remove unused `import struct Foundation.Date`
MaxDesiatov Oct 8, 2025
f8c08dd
Remove unused `else` clause from command decoder
MaxDesiatov Oct 8, 2025
77bdb04
Add `swift-nio` in `SWIFTCI_USE_LOCAL_DEPS` clause
MaxDesiatov Oct 8, 2025
256c70c
Add FIXME note for `.supportedFeatures` response
MaxDesiatov Oct 8, 2025
111deb8
Use `Logger`, `NIOAsyncChannel`
MaxDesiatov Oct 9, 2025
e392d30
Add required dependencies to `[email protected]`
MaxDesiatov Oct 9, 2025
a7c62b0
Add `iSeqToWasmMapping` to `InstanceEntity`
MaxDesiatov Oct 9, 2025
21e1b44
Fix formatting and iOS compatibility
MaxDesiatov Oct 9, 2025
329e4f5
Update [email protected]
MaxDesiatov Oct 9, 2025
a3d20af
Update doc comment of `func instantiate` in `Module.swift`
MaxDesiatov Oct 9, 2025
8d15b99
Add `targetStatus`/`?` host command
MaxDesiatov Oct 10, 2025
d9b60b1
Fix use of `OK#9a` instead of incorrect `ok#da` response
MaxDesiatov Oct 10, 2025
05583d0
Add `CSystemExtras` to `[email protected]`
MaxDesiatov Oct 10, 2025
39242d6
Handle `targetStatus` in `WasmKitDebugger`
MaxDesiatov Oct 10, 2025
cbff974
Build only `wasmkit-cli` product for WASI in `main.yml`
MaxDesiatov Oct 10, 2025
982fa91
Fix formatting in `WasmKitDebugger.swift`
MaxDesiatov Oct 10, 2025
3a74a91
Fix `QStartNoAckMode` handling
MaxDesiatov Oct 14, 2025
bc539e8
Add `qRegisterInfo` parsing to `GDBHostCommand.init`
MaxDesiatov Oct 14, 2025
fb4e2a2
Use `KeyValuePairs` response for `.registerInfo`
MaxDesiatov Oct 14, 2025
042a2c4
Fix formatting and tests build error
MaxDesiatov Oct 14, 2025
197abd3
Exclude `wasmkit-gdb-tool` on Windows, address PR feedback
MaxDesiatov Oct 14, 2025
a2899f7
Remove retroactive `FilePath` conformance
MaxDesiatov Oct 14, 2025
0b42724
Handle more host commands, up to `qWasmCallStack`
MaxDesiatov Oct 14, 2025
1783176
Fix formatting
MaxDesiatov Oct 14, 2025
c0a9cf6
Address PR feedback, add comment for `DebuggingAddress` sendability
MaxDesiatov Oct 16, 2025
806e7ec
Add `DebuggerExecution` wrapper type
MaxDesiatov Oct 16, 2025
26ea4e5
Implement `.readMemory` command handling
MaxDesiatov Oct 16, 2025
8343902
Fix formatting
MaxDesiatov Oct 16, 2025
ff2fa0d
Pass `-package-name` in CMake to enable use of `package`
MaxDesiatov Oct 16, 2025
3ed9013
Disable `WasmKitGDBHandler` on Windows
MaxDesiatov Oct 16, 2025
3ea5aab
Fix formatting
MaxDesiatov Oct 16, 2025
3fc8fdc
Try nightly `main` for `build-cmake` job
MaxDesiatov Oct 17, 2025
ea83134
Revert "Try nightly `main` for `build-cmake` job"
MaxDesiatov Oct 17, 2025
2893799
Rename `DebuggerExecution` to `Debugger`, hide behind a trait
MaxDesiatov Oct 17, 2025
7bdb16c
Enable `WasmDebuggingSupport` on CI where possible
MaxDesiatov Oct 17, 2025
4ea0fb0
Fix formatting
MaxDesiatov Oct 17, 2025
ee3c7bf
Revert "Pass `-package-name` in CMake to enable use of `package`"
MaxDesiatov Oct 17, 2025
a6d0749
Disable traits in pre-6.1, guard use of `package` on trait
MaxDesiatov Oct 17, 2025
4909d3b
Remove use of `package` from CMake-built code
MaxDesiatov Oct 20, 2025
cce2105
Fix non-CMake build breakage
MaxDesiatov Oct 20, 2025
811589f
Fix formatting
MaxDesiatov Oct 20, 2025
bc2230d
Enable iseq -> wasm instruction mapping
MaxDesiatov Oct 20, 2025
db1ec2d
Fix formatting
MaxDesiatov Oct 20, 2025
62592f1
Add missing `mutating` to `Debugger.swift`
MaxDesiatov Oct 20, 2025
bbfcb45
Make `init` throw effect untyped in `Debugger.swift`
MaxDesiatov Oct 20, 2025
c6213eb
Make throwing method effects untyped in `Debugger.swift`
MaxDesiatov Oct 20, 2025
a993b50
Make `debugger: Debugger` property mutable
MaxDesiatov Oct 20, 2025
2d065e0
Clean up `WasmGen` code
MaxDesiatov Oct 21, 2025
fd0d1ee
Add reverse wasm->iseq mapping, breakpoints toggling PoC
MaxDesiatov Oct 21, 2025
a35b73e
Remove unused `functionAddresses` property from `Debugger`
MaxDesiatov Oct 21, 2025
16ac0cf
Remove changes unrelated to the protocol
MaxDesiatov Oct 22, 2025
410c470
Clarify licensing in `README.md`
MaxDesiatov Oct 22, 2025
977b939
Add license files for separate modules
MaxDesiatov Oct 22, 2025
2acd4f3
Basic doc comments for `GDBHostCommand`
MaxDesiatov Oct 22, 2025
3b2e30f
Add doc comments for `GDBHostCommandDecoder`
MaxDesiatov Oct 22, 2025
fc740e5
Add remaining doc comments
MaxDesiatov Oct 22, 2025
a297f2d
Fix formatting
MaxDesiatov Oct 22, 2025
ff2e940
Fix var naming typo
MaxDesiatov Oct 22, 2025
5f7fbb5
Clarify licensing in `README.md`
MaxDesiatov Oct 22, 2025
d100d1e
Add license files for separate modules
MaxDesiatov Oct 22, 2025
2407284
Basic doc comments for `GDBHostCommand`
MaxDesiatov Oct 22, 2025
f628219
Add doc comments for `GDBHostCommandDecoder`
MaxDesiatov Oct 22, 2025
ab295db
Add remaining doc comments
MaxDesiatov Oct 22, 2025
e3505bc
Fix formatting
MaxDesiatov Oct 22, 2025
c4f9b3f
Fix var naming typo
MaxDesiatov Oct 22, 2025
f6bab20
Remove unused `throws` in `GDBTargetResponseEncoder.swift`
MaxDesiatov Oct 22, 2025
f33dc82
Remove unused `throws` in `GDBTargetResponseEncoder.swift`
MaxDesiatov Oct 22, 2025
a1d5183
Merge branch 'maxd/lldb-remote-protocol' of github.com:swiftwasm/Wasm…
MaxDesiatov Oct 22, 2025
dccc6af
Revert "Remove changes unrelated to the protocol"
MaxDesiatov Oct 22, 2025
a25399d
Restore base branch state
MaxDesiatov Oct 22, 2025
6bb5df8
Merge branch 'main' into maxd/debugging-breakpoints
MaxDesiatov Oct 22, 2025
ae91e24
Add `DebuggerTests` test suite
MaxDesiatov Oct 22, 2025
169d406
Merge remote-tracking branch 'origin/maxd/debugging-breakpoints' into…
MaxDesiatov Oct 22, 2025
d5d1600
Fix build error, add debug logging
MaxDesiatov Oct 23, 2025
9d79c83
Fix `DebuggerTests`
MaxDesiatov Oct 23, 2025
f64bf23
Remove `print` debugging
MaxDesiatov Oct 23, 2025
8bf6849
Allocate and modify `Pc` directly as `Debugger` property
MaxDesiatov Oct 23, 2025
ea04cc3
Rewind Pc back by 1 word after catching `Breakpoint`
MaxDesiatov Oct 23, 2025
c4d3ac9
Revert "Allocate and modify `Pc` directly as `Debugger` property"
MaxDesiatov Oct 24, 2025
6246506
Fully implement `qWasmCallStack`
MaxDesiatov Oct 24, 2025
27dbbc7
Pass `Sp` in `Breakpoint`, add `executeWasm` instance method
MaxDesiatov Oct 24, 2025
036fcb8
Fix license header diff
MaxDesiatov Oct 24, 2025
a57ec75
Fix trailing comma compatibility with Swift 6.0
MaxDesiatov Oct 24, 2025
935f877
Fix breakpoint resumption test expectation
MaxDesiatov Oct 24, 2025
a7fac8e
Mark `Sp.currentFunction` as `internal`
MaxDesiatov Oct 24, 2025
4e8b062
Mark `Debugger.Error` as `@unchecked Sendable`
MaxDesiatov Oct 24, 2025
969b992
Handle `qThreadStopInfo`, run up to breakpoint in handler
MaxDesiatov Oct 24, 2025
2486ec8
Add missing `logger` argument in `Entrypoint.swift`
MaxDesiatov Oct 24, 2025
d594b49
Remove CLI harness for smaller diff
MaxDesiatov Oct 27, 2025
76b2317
Revert "Remove CLI harness for smaller diff"
MaxDesiatov Oct 27, 2025
beff9a7
Remove only `wasmkit-gdb-tool`
MaxDesiatov Oct 27, 2025
eb9001b
Make some functions `fileprivate`
MaxDesiatov Oct 27, 2025
687b223
Add doc comments for the debugger type
MaxDesiatov Oct 27, 2025
d25166b
Merge branch 'main' into maxd/debugging-breakpoints
MaxDesiatov Oct 27, 2025
8d78ab6
Fix formatting
MaxDesiatov Oct 27, 2025
c39f9e2
Refine doc comment Sources/WasmKit/Execution/Debugger.swift
MaxDesiatov Oct 27, 2025
55bfb6b
Refine doc comment in `Debugger.swift`
MaxDesiatov Oct 27, 2025
e7a5287
Refine doc comments wording
MaxDesiatov Oct 27, 2025
a2c701e
Fix build error
MaxDesiatov Oct 27, 2025
1b271d5
Fix formatting
MaxDesiatov Oct 27, 2025
dec6850
Apply formatting to `[email protected]`
MaxDesiatov Oct 27, 2025
b3953a5
Disable nightly toolchain in CI configuration
MaxDesiatov Oct 27, 2025
e81f68e
Pin `build-android` job to v2.6.4 of `swift-android-action`
MaxDesiatov Oct 27, 2025
ab8f080
Refine doc comments wording
MaxDesiatov Oct 27, 2025
0eda671
Revert "Pin `build-android` job to v2.6.4 of `swift-android-action`"
MaxDesiatov Oct 27, 2025
7f0e212
Merge branch 'main' of github.com:swiftwasm/WasmKit into maxd/debuggi…
MaxDesiatov Oct 28, 2025
da87018
Merge branch 'main' into maxd/debugging-breakpoints
MaxDesiatov Oct 28, 2025
ce6124c
Move mapping dictionaries to `DebuggerInstructionMapping`
MaxDesiatov Oct 28, 2025
dd36c4c
Fix formatting and CMake
MaxDesiatov Oct 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,21 @@ jobs:
wasi-swift-sdk-checksum: "b64dfad9e1c9ccdf06f35cf9b1a00317e000df0c0de0b3eb9f49d6db0fcba4d9"
test-args: "--traits WasmDebuggingSupport --enable-code-coverage"
build-dev-dashboard: true
- swift: "swiftlang/swift:nightly-main-noble"
development-toolchain-download: "https://download.swift.org/development/ubuntu2404/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a-ubuntu24.04.tar.gz"
wasi-swift-sdk-download: "https://download.swift.org/development/wasm-sdk/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm.artifactbundle.tar.gz"
wasi-swift-sdk-id: swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm
wasi-swift-sdk-checksum: "b64dfad9e1c9ccdf06f35cf9b1a00317e000df0c0de0b3eb9f49d6db0fcba4d9"
test-args: "--traits WasmDebuggingSupport -Xswiftc -DWASMKIT_CI_TOOLCHAIN_NIGHTLY"
- swift: "swiftlang/swift:nightly-main-noble"
development-toolchain-download: "https://download.swift.org/development/ubuntu2404/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a-ubuntu24.04.tar.gz"
wasi-swift-sdk-download: "https://download.swift.org/development/wasm-sdk/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm.artifactbundle.tar.gz"
wasi-swift-sdk-id: swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm
wasi-swift-sdk-checksum: "b64dfad9e1c9ccdf06f35cf9b1a00317e000df0c0de0b3eb9f49d6db0fcba4d9"
test-args: "--traits WasmDebuggingSupport -Xswiftc -DWASMKIT_CI_TOOLCHAIN_NIGHTLY --build-system swiftbuild"
label: " --build-system swiftbuild"
# Disabled until a toolchain containing https://github.com/swiftlang/swift/commit/b219d4089c922ceb8b700424236ca97f6087a9a1
# is tagged.
# - swift: "swiftlang/swift:nightly-main-noble"
# development-toolchain-download: "https://download.swift.org/development/ubuntu2404/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a-ubuntu24.04.tar.gz"
# wasi-swift-sdk-download: "https://download.swift.org/development/wasm-sdk/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm.artifactbundle.tar.gz"
# wasi-swift-sdk-id: swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm
# wasi-swift-sdk-checksum: "b64dfad9e1c9ccdf06f35cf9b1a00317e000df0c0de0b3eb9f49d6db0fcba4d9"
# test-args: "--traits WasmDebuggingSupport -Xswiftc -DWASMKIT_CI_TOOLCHAIN_NIGHTLY"
# - swift: "swiftlang/swift:nightly-main-noble"
# development-toolchain-download: "https://download.swift.org/development/ubuntu2404/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a-ubuntu24.04.tar.gz"
# wasi-swift-sdk-download: "https://download.swift.org/development/wasm-sdk/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm.artifactbundle.tar.gz"
# wasi-swift-sdk-id: swift-DEVELOPMENT-SNAPSHOT-2025-10-02-a_wasm
# wasi-swift-sdk-checksum: "b64dfad9e1c9ccdf06f35cf9b1a00317e000df0c0de0b3eb9f49d6db0fcba4d9"
# test-args: "--traits WasmDebuggingSupport -Xswiftc -DWASMKIT_CI_TOOLCHAIN_NIGHTLY --build-system swiftbuild"
# label: " --build-system swiftbuild"

runs-on: ubuntu-24.04
name: "build-linux (${{ matrix.swift }}${{ matrix.label }})"
Expand Down
5 changes: 3 additions & 2 deletions [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let package = Package(
],
traits: [
.default(enabledTraits: []),
"WasmDebuggingSupport"
"WasmDebuggingSupport",
],
targets: [
.executableTarget(
Expand Down Expand Up @@ -123,7 +123,8 @@ let package = Package(
.target(name: "WITExtractor"),
.testTarget(name: "WITExtractorTests", dependencies: ["WITExtractor", "WIT"]),

.target(name: "GDBRemoteProtocol",
.target(
name: "GDBRemoteProtocol",
dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "NIOCore", package: "swift-nio"),
Expand Down
10 changes: 10 additions & 0 deletions Sources/GDBRemoteProtocol/GDBHostCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ package struct GDBHostCommand: Equatable {
case readMemoryBinaryData
case readMemory
case wasmCallStack
case threadStopInfo

case generalRegisters

Expand Down Expand Up @@ -97,6 +98,7 @@ package struct GDBHostCommand: Equatable {
/// - arguments: raw arguments that immediately follow kind of the command.
package init(kindString: String, arguments: String) throws(GDBHostCommandDecoder.Error) {
let registerInfoPrefix = "qRegisterInfo"
let threadStopInfoPrefix = "qThreadStopInfo"

if kindString.starts(with: "x") {
self.kind = .readMemoryBinaryData
Expand All @@ -109,6 +111,14 @@ package struct GDBHostCommand: Equatable {
} else if kindString.starts(with: registerInfoPrefix) {
self.kind = .registerInfo

guard arguments.isEmpty else {
throw GDBHostCommandDecoder.Error.unexpectedArgumentsValue
}
self.arguments = String(kindString.dropFirst(registerInfoPrefix.count))
return
} else if kindString.starts(with: threadStopInfoPrefix) {
self.kind = .threadStopInfo

guard arguments.isEmpty else {
throw GDBHostCommandDecoder.Error.unexpectedArgumentsValue
}
Expand Down
13 changes: 10 additions & 3 deletions Sources/GDBRemoteProtocol/GDBTargetResponseEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

import Foundation
import Logging
import NIOCore

extension String {
Expand All @@ -27,7 +28,12 @@ extension String {
package class GDBTargetResponseEncoder: MessageToByteEncoder {
private var isNoAckModeActive = false

package init() {}
private let logger: Logger

package init(logger: Logger) {
self.logger = logger
}

package func encode(data: GDBTargetResponse, out: inout ByteBuffer) {
if !isNoAckModeActive {
out.writeInteger(UInt8(ascii: "+"))
Expand All @@ -51,8 +57,9 @@ package class GDBTargetResponseEncoder: MessageToByteEncoder {
out.writeString(str.appendedChecksum)

case .hexEncodedBinary(let binary):
let hexDump = ByteBuffer(bytes: binary).hexDump(format: .compact)
out.writeString(hexDump.appendedChecksum)
let hexDumpResponse = ByteBuffer(bytes: binary).hexDump(format: .compact).appendedChecksum
self.logger.trace("GDBTargetResponseEncoder encoded a response", metadata: ["RawResponse": .string(hexDumpResponse)])
out.writeString(hexDumpResponse)

case .empty:
out.writeString("".appendedChecksum)
Expand Down
2 changes: 2 additions & 0 deletions Sources/WAT/Encoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ extension TableType: WasmEncodable {
struct ElementExprCollector: AnyInstructionVisitor {
typealias Output = Void

var binaryOffset: Int = 0
var isAllRefFunc: Bool = true
var instructions: [Instruction] = []

Expand Down Expand Up @@ -443,6 +444,7 @@ extension WatParser.DataSegmentDecl {
}

struct ExpressionEncoder: BinaryInstructionEncoder {
var binaryOffset: Int = 0
var encoder = Encoder()
var hasDataSegmentInstruction: Bool = false

Expand Down
1 change: 1 addition & 0 deletions Sources/WAT/Parser/WastParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct WastParser {
}

struct ConstExpressionCollector: WastConstInstructionVisitor {
var binaryOffset: Int = 0
let addValue: (Value) -> Void

mutating func visitI32Const(value: Int32) throws { addValue(.i32(UInt32(bitPattern: value))) }
Expand Down
86 changes: 86 additions & 0 deletions Sources/WasmKit/DebuggerInstructionMapping.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

/// Two-way mapping between Wasm and internal iseq bytecode instructions. The implementation of the mapping
/// is private and is empty when `WasmDebuggingSupport` package trait is disabled.
struct DebuggerInstructionMapping {
Copy link
Member Author

@MaxDesiatov MaxDesiatov Oct 28, 2025

Choose a reason for hiding this comment

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

Nice side-effect of moving to a separate type is that it's easier to switch to an empty implementation of the mapping based on package traits.

@kateinoigakukun I hope this addresses your review feedback, let me know if anything else is needed to move this forward.

#if WasmDebuggingSupport

/// Mapping from iseq Pc to instruction addresses in the original binary.
/// Used for handling current call stack requests issued by a ``Debugger`` instance.
private var iseqToWasm = [Pc: Int]()

/// Mapping from Wasm instruction addresses in the original binary to iseq instruction addresses.
/// Used for handling breakpoint requests issued by a ``Debugger`` instance.
private var wasmToIseq = [Int: Pc]()

/// Wasm addresses sorted in ascending order for binary search when of the next closest mapped
/// instruction, when no key is found in `wasmToIseqMapping`.
private var wasmMappings = [Int]()

mutating func add(wasm: Int, iseq: Pc) {
// Don't override the existing mapping, only store a new pair if there's no mapping for a given key.
if self.iseqToWasm[iseq] == nil {
self.iseqToWasm[iseq] = wasm
}
if self.wasmToIseq[wasm] == nil {
self.wasmToIseq[wasm] = iseq
}
self.wasmMappings.append(wasm)
}

/// Computes an address of WasmKit's iseq bytecode instruction that matches a given Wasm instruction address.
/// - Parameter address: the Wasm instruction to find a mapping for.
/// - Returns: A tuple with an address of found iseq instruction and the original Wasm instruction or next
/// closest match if no direct match was found.
func findIseq(forWasmAddress address: Int) -> (iseq: Pc, wasm: Int)? {
// Look in the main mapping
if let iseq = self.wasmToIseq[address] {
return (iseq, address)
}

// If nothing found, find the closest Wasm address using binary search
guard let nextAddress = self.wasmMappings.binarySearch(nextClosestTo: address),
// Look in the main mapping again with the next closest address if binary search produced anything
let iseq = self.wasmToIseq[nextAddress]
else {
return nil
}

return (iseq, nextAddress)
}

func findWasm(forIseqAddress pc: Pc) -> Int? {
self.iseqToWasm[pc]
}
#endif
}


#if WasmDebuggingSupport
extension [Int] {
/// Uses binary search to find an element in `self` that's next closest to a given value.
/// - Parameter value: the array element to search for or to use as a baseline when searching.
/// - Returns: array element `result`, where `result - value` is the smallest possible, while
/// `result > value` also holds.
package func binarySearch(nextClosestTo value: Int) -> Int? {
switch self.count {
case 0:
return nil
default:
var slice = self[0..<self.count]
while slice.count > 1 {
let middle = (slice.endIndex - slice.startIndex) / 2
if slice[middle] < value {
// Not found anything in the lower half, assigning higher half to `slice`.
slice = slice[(middle + 1)..<slice.endIndex]
} else {
// Not found anything in the higher half, assigning lower half to `slice`.
slice = slice[slice.startIndex..<middle]
}
}

return self[slice.startIndex]
}
}
}

#endif
Loading
Loading