Skip to content

Conversation

@tomusdrw
Copy link
Owner

@tomusdrw tomusdrw commented Nov 3, 2025

Current implementation was always attempting to allocate the destination vector (which could simply be impossible).

This PR patches the behavior by first checking if all pages are accessbile, yet the ultimate solution should be to get rid of this API in favour of a more performant one.

Summary by CodeRabbit

  • New Features

    • Memory reads now detect faults before allocating buffers, making read operations safer and more efficient.
  • Tests

    • Added tests for memory boundary faults, oversized-read handling, and successful in-range reads to prevent regressions.
  • Documentation

    • Expanded usage notes recommending more efficient access patterns and documenting deprecation of the old read approach.
  • Chores

    • Updated project file inclusion rules to exclude build directories from assemblies.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Walkthrough

Replaces the debugger's internal memory-read path to call a new Memory.getMemory(fault, address, length) that scans pages for faults before allocating a buffer. Implements Memory.getMemory, adds tests for fault and successful reads, and updates tooling includes to exclude build directories.

Changes

Cohort / File(s) Summary
Memory API Implementation
assembly/memory.ts
Added `getMemory(fault: MaybePageFault, address: u32, length: u32): Uint8Array
Memory API Consumer (Debugger)
assembly/api-debugger.ts
Switched debugger internal read to call int.memory.getMemory(faultRes, address, length) instead of allocating a buffer and using int.memory.bytesRead. Updated deprecation docblock and example to show preferred access pattern.
Memory Fault & Read Tests
assembly/memory.test.ts
Added three tests to TESTS: "should page fault when going beyond memory", "should page fault when trying to allocate too much", and "should read memory succesfully" — asserting fault behavior and successful read semantics.
Tooling config
biome.jsonc
Extended files.includes to exclude build directories by adding "!build" and "!web/build" to the **/assembly/**/* include list.

Sequence Diagram(s)

sequenceDiagram
  participant Debugger as api-debugger
  participant Interpreter as Interpreter
  participant Memory as Memory (pages)

  rect rgb(245,250,255)
  Debugger->>Interpreter: getMemory(faultRes, address, length)
  note right of Interpreter: Delegates to Memory.getMemory
  Interpreter->>Memory: scan pages for faults (no allocations)
  alt fault detected
    Memory-->>Interpreter: set faultRes.isFault = true\nreturn null
    Interpreter-->>Debugger: return null (fault)
  else no fault
    Memory->>Memory: allocate destination buffer
    Memory-->>Interpreter: Uint8Array (data)
    Interpreter-->>Debugger: return Uint8Array
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect assembly/memory.ts::getMemory for correct page traversal, bounds and overflow checks, and allocation conditions.
  • Verify assembly/api-debugger.ts correctly constructs/interprets MaybePageFault and handles null vs data.
  • Check new tests in assembly/memory.test.ts for edge-case coverage and accurate assertions.

Possibly related PRs

Suggested reviewers

  • DrEverr
  • mateuszsikora

Poem

🐰
I hop the pages, nose so light,
I sniff for faults before I bite,
No spare buffers left to keep,
I fetch your bytes then wake from sleep. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Fix getting memory from ananas' directly relates to the main changes in the changeset. The PR addresses an issue with memory allocation in the api-debugger by introducing a new getMemory method that checks page accessibility before attempting allocation. The title is concise and captures the core fix being implemented.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch td-read

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 43ea896 and 7f32d71.

📒 Files selected for processing (1)
  • assembly/memory.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • assembly/memory.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cee77f9 and 887a171.

📒 Files selected for processing (3)
  • assembly/api-debugger.ts (1 hunks)
  • assembly/memory.test.ts (1 hunks)
  • assembly/memory.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 92
File: assembly/api-debugger.ts:170-182
Timestamp: 2025-10-16T15:17:10.864Z
Learning: In assembly/memory.ts, the `bytesRead` method signature is: `bytesRead(faultRes: MaybePageFault, address: u32, destination: Uint8Array, destinationOffset: u32): void`. The last parameter is the offset within the destination buffer to start writing at, not the number of bytes to read. The method reads until the destination buffer is filled from destinationOffset to destination.length.
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).
📚 Learning: 2025-10-16T15:17:10.864Z
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 92
File: assembly/api-debugger.ts:170-182
Timestamp: 2025-10-16T15:17:10.864Z
Learning: In assembly/memory.ts, the `bytesRead` method signature is: `bytesRead(faultRes: MaybePageFault, address: u32, destination: Uint8Array, destinationOffset: u32): void`. The last parameter is the offset within the destination buffer to start writing at, not the number of bytes to read. The method reads until the destination buffer is filled from destinationOffset to destination.length.

Applied to files:

  • assembly/api-debugger.ts
  • assembly/memory.test.ts
  • assembly/memory.ts
📚 Learning: 2025-04-22T15:58:24.284Z
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).

Applied to files:

  • assembly/memory.test.ts
  • assembly/memory.ts
🧬 Code graph analysis (3)
assembly/api-debugger.ts (2)
assembly/memory.ts (2)
  • getMemory (199-223)
  • MaybePageFault (15-19)
assembly/interpreter.ts (1)
  • Interpreter (21-198)
assembly/memory.test.ts (1)
assembly/memory.ts (2)
  • MemoryBuilder (38-88)
  • MaybePageFault (15-19)
assembly/memory.ts (1)
assembly/memory-page.ts (1)
  • PAGE_SIZE (5-5)
🪛 GitHub Actions: Node.js CI
assembly/api-debugger.ts

[error] 179-179: File content differs from formatting output.

assembly/memory.test.ts

[error] 113-114: File content differs from formatting output.

assembly/memory.ts

[error] 198-199: File content differs from formatting output.


[error] 201-205: File content differs from formatting output.


[warning] 206-206: iLength is never reassigned.


[error] 211-216: File content differs from formatting output.

🔇 Additional comments (6)
assembly/memory.test.ts (2)

113-125: LGTM!

The test correctly verifies that getMemory detects page faults when attempting to read beyond allocated memory.


126-138: LGTM!

The test correctly verifies that getMemory handles allocation failures for oversized memory requests.

assembly/api-debugger.ts (2)

174-201: Good documentation of the deprecation rationale.

The detailed explanation of why this API is inefficient and what the better approach should be is helpful for future refactoring.


202-213: LGTM!

The change correctly uses the new getMemory API which handles fault detection before allocation.

assembly/memory.ts (2)

252-252: LGTM!

Clear documentation for the bytesWrite method.


361-361: LGTM!

Clear documentation for the setBytes method.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
assembly/memory.test.ts (1)

113-125: Test validates overflow protection correctly.

This test properly checks that getMemory fails when the address range would overflow u32 (2343629385 + 2145386496 = 4489015881 > 4294967295). The assertions correctly expect a page fault and null result.

Consider adding a brief comment explaining the overflow scenario being tested for future maintainability:

 test("should page fault when going beyond memory", (assert) => {
+  // Test u32 overflow: address + length > u32::MAX
   const address = 2343629385;
   const length = 2145386496;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 887a171 and 643159a.

📒 Files selected for processing (4)
  • assembly/api-debugger.ts (1 hunks)
  • assembly/memory.test.ts (1 hunks)
  • assembly/memory.ts (3 hunks)
  • biome.jsonc (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • assembly/api-debugger.ts
  • assembly/memory.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 92
File: assembly/api-debugger.ts:170-182
Timestamp: 2025-10-16T15:17:10.864Z
Learning: In assembly/memory.ts, the `bytesRead` method signature is: `bytesRead(faultRes: MaybePageFault, address: u32, destination: Uint8Array, destinationOffset: u32): void`. The last parameter is the offset within the destination buffer to start writing at, not the number of bytes to read. The method reads until the destination buffer is filled from destinationOffset to destination.length.
📚 Learning: 2025-10-16T15:17:10.864Z
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 92
File: assembly/api-debugger.ts:170-182
Timestamp: 2025-10-16T15:17:10.864Z
Learning: In assembly/memory.ts, the `bytesRead` method signature is: `bytesRead(faultRes: MaybePageFault, address: u32, destination: Uint8Array, destinationOffset: u32): void`. The last parameter is the offset within the destination buffer to start writing at, not the number of bytes to read. The method reads until the destination buffer is filled from destinationOffset to destination.length.

Applied to files:

  • assembly/memory.test.ts
📚 Learning: 2025-04-22T15:58:24.284Z
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).

Applied to files:

  • assembly/memory.test.ts
🧬 Code graph analysis (1)
assembly/memory.test.ts (1)
assembly/memory.ts (2)
  • MemoryBuilder (38-88)
  • MaybePageFault (15-19)
🔇 Additional comments (2)
biome.jsonc (1)

46-46: LGTM! Good practice to exclude build artifacts.

Excluding the build directory from linting and formatting is appropriate and prevents unnecessary processing of generated files.

assembly/memory.test.ts (1)

126-138: Test correctly validates large allocation handling.

This test properly verifies that getMemory fails safely when attempting to read a very large length (~2GB) from an unallocated address, preventing potentially problematic buffer allocation attempts.

Note: The formatting issue mentioned in the previous review (missing semicolon on line 115) has been resolved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 643159a and 43ea896.

📒 Files selected for processing (3)
  • assembly/memory.test.ts (1 hunks)
  • assembly/memory.ts (3 hunks)
  • biome.jsonc (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • assembly/memory.test.ts
  • biome.jsonc
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 92
File: assembly/api-debugger.ts:170-182
Timestamp: 2025-10-16T15:17:10.864Z
Learning: In assembly/memory.ts, the `bytesRead` method signature is: `bytesRead(faultRes: MaybePageFault, address: u32, destination: Uint8Array, destinationOffset: u32): void`. The last parameter is the offset within the destination buffer to start writing at, not the number of bytes to read. The method reads until the destination buffer is filled from destinationOffset to destination.length.
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).
📚 Learning: 2025-10-16T15:17:10.864Z
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 92
File: assembly/api-debugger.ts:170-182
Timestamp: 2025-10-16T15:17:10.864Z
Learning: In assembly/memory.ts, the `bytesRead` method signature is: `bytesRead(faultRes: MaybePageFault, address: u32, destination: Uint8Array, destinationOffset: u32): void`. The last parameter is the offset within the destination buffer to start writing at, not the number of bytes to read. The method reads until the destination buffer is filled from destinationOffset to destination.length.

Applied to files:

  • assembly/memory.ts
📚 Learning: 2025-04-22T15:58:24.284Z
Learnt from: tomusdrw
Repo: tomusdrw/anan-as PR: 49
File: assembly/memory.ts:335-335
Timestamp: 2025-04-22T15:58:24.284Z
Learning: In the bytesWrite method, memory writes should be atomic. If a page fault occurs during a multi-page write, no memory should be altered (current implementation allows partial writes).

Applied to files:

  • assembly/memory.ts
🧬 Code graph analysis (1)
assembly/memory.ts (1)
assembly/memory-page.ts (1)
  • PAGE_SIZE (5-5)
🔇 Additional comments (2)
assembly/memory.ts (2)

251-251: LGTM!

The JSDoc comment accurately describes the bytesWrite method's purpose and parameters.


360-360: LGTM!

The JSDoc comment accurately describes the setBytes method's behavior.

@tomusdrw tomusdrw merged commit 5acc613 into main Nov 3, 2025
3 checks passed
@tomusdrw tomusdrw deleted the td-read branch November 3, 2025 09:51
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