Skip to content

Conversation

@gael-bigot
Copy link
Collaborator

@gael-bigot gael-bigot commented Oct 9, 2025

This PR refactors the entirety of the WASM crate to emit Cairo-M assembly directly instead of Mir

Changes in codegen API

generator.rs

  • add_function_from_builder helper which allows building functions manually without depending on a MirFunction object

layout.rs

  • make some fields and methods public

builder

  • make some fields public
  • make instruction builder helpers public when they depend on Values rather than offsets
  • add helpers for loading and storing Values

Changes in wasm crate

  • Biggest conceptual change is switching from a phi node system to a slot system in cfg
  • ops : had to refactor a bit as many opcodes do not have a direct equivalent in CASM

Other

  • main : add DAG printing in --verbose mode
  • improved caching system for tests which would crash all diff tests if a single one did not pass

Closes CORE-1292

@claude
Copy link

claude bot commented Oct 9, 2025

Claude finished @gael-bigot's task —— View job


Code Review for WASM → CASM Refactor

TLDR: This is a substantial architectural improvement that moves WASM compilation directly to CASM, bypassing MIR. The implementation looks solid with good test coverage updates. Main concerns are around error handling robustness and some API design choices.

Review Progress

  • Analyze core architectural changes in lowering module
  • Review codegen API modifications
  • Check test coverage and snapshot updates
  • Assess performance and security implications
  • Address reviewer comments
  • Provide comprehensive feedback

Key Architectural Improvements

Excellent Design Decisions:

  • Slot-based value management: The switch from phi nodes to pre-allocated slots is cleaner and more predictable for CASM generation
  • Two-pass label handling: Pre-registering labels and their slots prevents forward reference issues
  • Caching improvements: The new test caching system test_utils.rs:60-72 handles poisoned mutexes gracefully, making tests more robust

API Design:

  • add_function_from_builder() in generator.rs:351 provides good encapsulation for WASM lowering without exposing internals
  • Making builder fields public is reasonable for this use case, though consider selective exposure via accessor methods

Code Quality Issues

🔴 Critical Issues

1. Unimplemented BrTable (cfg.rs:211)

Operation::BrTable { targets: _ } => {
    todo!()
}

This will panic at runtime if WASM contains branch tables. Should return a proper error.

2. Type System Inconsistencies (ops.rs:129, 237)

  • Comparisons produce Bool but used as u32 in conditionals
  • Need consistent type handling between WASM and Cairo-M semantics

🟡 Design Concerns

1. Error Handling Robustness

  • Many unwraps in lowering/mod.rs:244-252 that could be more graceful
  • Consider using Result propagation instead of panicking on type mismatches

2. Code Duplication (mod.rs:220)
Parameter allocation logic duplicates FunctionLayout::allocate_parameters_with_sizes() - consider refactoring shared ABI logic.

3. Memory Safety

  • No bounds checking for array operations in ops.rs:200-234
  • Memory addresses should be validated against MAX_ADDRESS

Test Coverage Assessment

✅ Strengths:

  • Comprehensive snapshot tests covering all major WASM constructs
  • Good diff testing against WOMIR interpreter
  • Improved caching prevents cascading test failures

⚠️ Gaps:

  • No tests for error conditions (invalid WASM, unsupported ops)
  • Missing edge case tests for loop nesting depth limits
  • BrTable operations completely untested

Performance Considerations

Positive:

  • Direct CASM emission avoids MIR intermediate representation overhead
  • Two-pass approach minimizes label resolution complexity
  • Caching system improves test performance

Potential Issues:

  • Slot allocation may use more memory than phi nodes for simple cases
  • No optimization passes on generated CASM

Security Considerations

Low Risk:

  • No obvious security vulnerabilities
  • Proper bounds checking on loop depth cfg.rs:397-402
  • Good error messages that don't leak sensitive information

Responses to Review Comments

@enitrat on generator.rs:197: The removed code appears to be dead - good cleanup.

@enitrat on layout.rs: Documentation suggestion is good - the current comment doesn't fully explain the allocation behavior.

Recommendations

High Priority

  1. Replace todo!() with proper error: DagToCasmError::UnsupportedOperation for BrTable
  2. Fix type consistency: Standardize bool/u32 handling in comparisons
  3. Add bounds checking: Validate memory addresses in load/store operations

Medium Priority

  1. Refactor parameter allocation: Extract shared logic to avoid duplication
  2. Add error condition tests: Test invalid WASM inputs and unsupported operations
  3. Consider optimization passes: Add basic peephole optimizations for generated CASM

Low Priority

  1. API refinement: Consider accessor methods instead of public fields where appropriate
  2. Documentation: Add more detailed comments explaining the slot allocation strategy

This refactor represents a significant improvement in the WASM compilation pipeline. The core architecture is sound, but addressing the critical issues (especially the todo!()) should be prioritized before merge.

@gael-bigot gael-bigot marked this pull request as ready for review October 10, 2025 12:17
@enitrat
Copy link
Member

enitrat commented Oct 24, 2025

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +153 to +205
SolvedBreakTarget::Return(_return_values) => {
// These seem to never be generated by WOMIR
Err(DagToCasmError::InvalidControlFlow {
function_name: self.casm_builder.layout.name.clone(),
reason: "Conditional return not yet implemented".to_string(),
operation_context: "resolving BrIf return".to_string(),
})?;
}
}
}

Operation::BrIfZero(target) => {
// Inverted conditional branch - condition is the last input
// BrIfZero takes the branch when condition is ZERO
let cond_idx = node.inputs.len().checked_sub(1).ok_or_else(|| {
DagToMirError::InvalidControlFlow {
function_name: self.mir_function.name.clone(),
DagToCasmError::InvalidControlFlow {
function_name: self.casm_builder.layout.name.clone(),
reason: "BrIfZero without condition input".to_string(),
operation_context: "resolving BrIfZero condition".to_string(),
}
})?;
let condition_value = self.get_input_value(&node.inputs[cond_idx])?;
let else_target = self.resolve_break_target(node_idx, node, target)?;
let then_target = self.mir_function.add_basic_block();

// Edge copies on the taken edge
self.record_edge_values(node, target)?;
let branch_values = self.get_branch_values(node)?;

let terminator = Terminator::branch(condition_value, then_target, else_target);
self.get_current_block()?.set_terminator(terminator);
self.set_current_block(then_target);
let resolved_target = self.resolve_break_target(node_idx, node, target)?;

match resolved_target {
SolvedBreakTarget::Label(label) => {
let fallthrough_label =
self.casm_builder.emit_new_label_name(".fallthrough");

// If condition is non-zero, skip the branch (jump to fallthrough)
self.casm_builder
.jnz(condition_value, fallthrough_label.as_str())?;

// Taken path (when zero): store values and jump to target
self.store_to_label_slots(target, &branch_values)?;
self.casm_builder.jump(label.as_str());

// Fallthrough path continues here
self.casm_builder.emit_add_label(Label {
name: fallthrough_label,
address: None,
});
}
SolvedBreakTarget::Return(_return_values) => {
// These seem to never be generated by WOMIR
Err(DagToCasmError::InvalidControlFlow {
function_name: self.casm_builder.layout.name.clone(),
reason: "Conditional return not yet implemented".to_string(),
operation_context: "resolving BrIfZero return".to_string(),
})?;

Choose a reason for hiding this comment

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

P1 Badge Conditional branches to function exit now raise an error

The new BrIf and BrIfZero handlers bail out with InvalidControlFlow whenever the resolved break target represents a return. The previous MIR-based lowering handled this case by emitting a conditional branch whose taken edge performed the return. In WebAssembly it is valid (and common) to conditionally return from a function by branching to the outermost block, so this path can occur in real DAGs. With the current code such constructs will cause lowering to fail with "Conditional return not yet implemented", making the compiler reject valid input. Consider emitting the same store-and-return sequence used in the unconditional Br case instead of erroring out.

Useful? React with 👍 / 👎.

Copy link
Member

Choose a reason for hiding this comment

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

@gael-bigot okpm apres ça

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.

3 participants