Skip to content

hostgen hardening: empty-prewarm codegen bug, validation gaps, panic consistency, async template coverage #44

Description

@zklapow

Why

Follow-ups from review of #29. Individually small, collectively they make the codegen path fragile for external extension authors:

  1. Empty prewarm generates non-compiling guest Rust. generate_rust_code emits let modules = {:?}; (boomslang-hostgen/src/lib.rs:529); with no prewarm entries that's let modules = [];, which fails type inference (E0282) against pyo3's generic Python::import. The DSL makes prewarm optional and demo_async has none, so this is one include! away from a user hitting it. Fix: emit let modules: [&str; N] or skip the loop when empty.
  2. Validation gaps in validate_manifest (lib.rs:306-344). No duplicate-function-name check, no duplicate-param check, no cross-convention collision check (foo_bar vs fooBar both map to Java fooBar / Rust foo_bar_handler), no collision check against generated identifiers (register, prewarm, MAX_RESULT, the py_ wrapper prefix). All pass validation and explode later as confusing compile errors.
  3. Inconsistent panic behavior in the library API. generate_rust_host_code validates; generate_rust_code/generate_java_code don't and hit panic!/.expect on bad input (lib.rs:692-696, lib.rs:1087) depending on entry point. Safe via Build::generate() and the CLI, but the library surface shouldn't panic on user data.
  4. Async Java template indentation + zero compiled coverage. {% if has_async -%} at templates/java_host_functions.java:47,58 strips indentation, so async-only members land at column 0 (valid Java, fails prettier). There is no compiled or golden coverage of async Java output — only contains assertions (src/tests.rs:223-235). The stock golden test can't catch it because the stock extension has no async functions.
  5. Java/Rust host semantic divergence. (a) Java cancel() still delivers a completion if the canceled future finishes (AsyncHostRegistry.java:124-127), Rust suppresses it (templates/rust_host.rs:286-297). (b) On async handler error, generated Java propagates the real message via startFailed(e) while generated Rust returns -1 and the guest sees only "async host call failed" (lib.rs:920-925). (c) Generated Java reads params outside the try (trap on bad ptr/len) where the Rust host maps the same failure to -1. Pick one behavior per case.
  6. Docs nit: examples/custom-python-build/README.md suggests emit_java_host("../../core/src/main/java", ...) from build.rs — writing into another module's source tree during cargo build, which breaks read-only checkouts (e.g. Nix) and build caching. Document the CLI-after-build flow as the supported path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions