Skip to content

baml_language: route vm function execution to BexEngine#3173

Open
miguelcsx wants to merge 3 commits intoBoundaryML:canaryfrom
miguelcsx:refac/vm-engine
Open

baml_language: route vm function execution to BexEngine#3173
miguelcsx wants to merge 3 commits intoBoundaryML:canaryfrom
miguelcsx:refac/vm-engine

Conversation

@miguelcsx
Copy link
Contributor

@miguelcsx miguelcsx commented Feb 24, 2026

Why this change

BexVm::from_program let callers run the VM without the engine, but the engine is where execution correctness lives (event loop, notify/span-notify handling, GC, and consistent result/error propagation). In practice, bypassing it meant re-implementing that logic, and getting edge cases wrong.

tools_onionskin was the only real non-test user, and its custom loop had a user-visible bug: SpanNotify could be dropped, leaving the final result unset (blank Runner panel). It also treated Notify as an error instead of a normal mid-execution event.

What this PR does

  • Removes from_program to prevent bypassing the engine.
  • Switches tools_onionskin to run via BexEngine using SysOps::all_unsupported() (safe no-op SysOps), so all intermediate events are handled correctly and results are always set.
  • Adds make_vm() in baml_tests for VM-level tests/benchmarks that need direct VM control; everywhere else should use BexEngine.

Summary by CodeRabbit

  • Refactor

    • Switched the tool’s execution backend from a VM-based runner to an engine-driven runner for more reliable execution and UI sync.
    • Updated value formatting to reflect engine results, improving display for arrays, variants and union cases.
    • Improved runtime error and arity reporting when running functions.
  • Chores

    • Updated crate dependencies to support the new execution path (including async runtime).
  • Tests

    • Added formatter tests for scalar, string, array and variant representations.

@vercel
Copy link

vercel bot commented Feb 24, 2026

@miguelcsx is attempting to deploy a commit to the Boundary Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Moves test-only VM construction into a new make_vm helper, removes BexVm::from_program from the VM crate, updates benchmarks to use the helper, and migrates tools_onionskin execution from direct VM runs to an async bex_engine-based invocation (adds engine, sys_types, tokio deps and new formatting logic).

Changes

Cohort / File(s) Summary
Test VM helper & deps
baml_language/crates/baml_tests/src/bytecode.rs, baml_language/crates/baml_tests/Cargo.toml
Adds pub fn make_vm(program: VmProgram) -> Result<BexVm, bex_vm::errors::VmError> and a workspace dependency bex_heap; replaces test/bench callsites to use make_vm.
VM API removal
baml_language/crates/bex_vm/src/vm.rs
Removes pub fn from_program(program: bex_vm_types::Program) -> Result<Self, VmError> from impl BexVm, deleting the program->VM public constructor.
Bench updates
baml_language/crates/bex_vm/benches/fib.rs
Replaces BexVm::from_program usage with make_vm; tightens error handling around VM construction and vm.exec() failures.
tools_onionskin engine migration
baml_language/crates/tools_onionskin/Cargo.toml, baml_language/crates/tools_onionskin/src/compiler.rs
Adds bex_engine, sys_types, tokio deps; introduces compile_program_with_builtins, try_execute_selected_function, and format_external_value; replaces direct VM execution with async bex_engine calls on a current-thread Tokio runtime and adds formatting tests.

Sequence Diagram(s)

sequenceDiagram
    participant UI as "UI / Runner"
    participant CR as "CompilerRunner"
    participant RT as "Tokio Runtime"
    participant Engine as "bex_engine"
    participant Fmt as "Formatter"

    UI->>CR: run selected function
    CR->>CR: compile_program_with_builtins()
    CR->>RT: spawn current-thread runtime
    RT->>Engine: init(engine with sysops)
    RT->>Engine: function_params(func_idx)
    alt requires args
        Engine-->>RT: params (non-empty)
        RT-->>CR: RequiresArgs(n)
        CR-->>UI: update UI (requires args)
    else no args
        RT->>Engine: call_function(func_idx, [])
        Engine-->>RT: BexExternalValue
        RT->>Fmt: format_external_value(value)
        Fmt-->>RT: String
        RT-->>CR: VmExecutionResult::Ok(formatted)
        CR-->>UI: update UI (result)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'baml_language: route vm function execution to BexEngine' accurately describes the main change: moving VM function execution from direct BexVm usage to BexEngine, with removal of BexVm::from_program and updates to tools_onionskin to use BexEngine instead.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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: 1


ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec9ea08 and 03d7b5a.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • baml_language/crates/baml_tests/Cargo.toml
  • baml_language/crates/baml_tests/src/bytecode.rs
  • baml_language/crates/bex_vm/benches/fib.rs
  • baml_language/crates/bex_vm/src/vm.rs
  • baml_language/crates/tools_onionskin/Cargo.toml
  • baml_language/crates/tools_onionskin/src/compiler.rs
💤 Files with no reviewable changes (1)
  • baml_language/crates/bex_vm/src/vm.rs

- use all unsupported instead of driving the VM directly

- replaces from_program for the VM-level tests that legitimately need raw bytecode access
- compile vm runner programs with builtins via shared helper

- reduce clones/unwraps in bytecode tests and benches

- add unit coverage for external value formatting
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 info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03d7b5a and 71e6740.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • baml_language/crates/baml_tests/Cargo.toml
  • baml_language/crates/baml_tests/src/bytecode.rs
  • baml_language/crates/bex_vm/benches/fib.rs
  • baml_language/crates/bex_vm/src/vm.rs
  • baml_language/crates/tools_onionskin/Cargo.toml
  • baml_language/crates/tools_onionskin/src/compiler.rs
💤 Files with no reviewable changes (1)
  • baml_language/crates/bex_vm/src/vm.rs

- reflect correct vm failure
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 info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71e6740 and 6bee89f.

📒 Files selected for processing (1)
  • baml_language/crates/bex_vm/benches/fib.rs

Comment on lines +18 to +20
let Some(function_index) = program.function_index(input.function) else {
panic!("function not found");
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Include function name in panic message for easier debugging.

The panic message would be more helpful if it included the function name that wasn't found.

Proposed fix
     let Some(function_index) = program.function_index(input.function) else {
-        panic!("function not found");
+        panic!("function '{}' not found", input.function);
     };

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.

1 participant