Skip to content

feat(eval): make regex support explicit - #656

Open
nahime0 wants to merge 4 commits into
mainfrom
feat/eval-regex-capability
Open

feat(eval): make regex support explicit#656
nahime0 wants to merge 4 commits into
mainfrom
feat/eval-regex-capability

Conversation

@nahime0

@nahime0 nahime0 commented Jul 30, 2026

Copy link
Copy Markdown
Member

Summary

  • Decouple dynamic eval() support from PCRE2 so Magician-only binaries no longer require a managed native project or link regex code.
  • Add --with-regex for regex calls that exist only inside opaque evaluated source, while keeping normal automatic detection for statically visible regex usage.
  • Register managed PCRE2 with Magician through a versioned provider ABI only when regex support is enabled. Without a provider, evaluated code does not expose preg_* or mb_ereg_match() and fails only if one of those unavailable functions is executed.
  • Print a post-build reminder when dynamic eval is compiled without regex support, including the commands needed to declare PCRE2 and enable the capability.
  • Move regex usage out of the general examples/eval/ program into a dedicated examples/eval_regex/ project with a managed PCRE2 manifest and lockfile.
  • Restore the Magician benchmark runner to dependency-free isolated fixtures, removing the PCRE2 project staging that eval-only benchmarks no longer need.

Behavior

Program shape Result
Dynamic eval without regex Compiles without a native project or PCRE2, links Magician only, and emits a reminder after a successful build.
Statically visible regex usage Keeps existing auto-detection, links managed PCRE2, and makes the provider available to dynamic eval too.
Regex used only inside opaque eval source Requires a declared pcre2 native dependency and an explicit --with-regex build.

Testing

  • cargo test --bin elephc with_regex_records_runtime_capability
  • cargo test --lib runtime_features::tests::test_eval
  • cargo test --test codegen_tests test_dynamic_eval_without_regex_needs_no_native_project
  • cargo test --test codegen_tests test_dynamic_eval_regex_without_capability_fails_at_runtime
  • cargo test --test codegen_tests test_dynamic_eval_with_regex_uses_managed_provider
  • cargo test --test codegen_tests test_static_regex_detection_enables_dynamic_eval_regex

@github-actions github-actions Bot added area:codegen Touches target-aware assembly or backend lowering. area:magician Touches eval, include execution, or elephc-magician. area:tooling-ci Touches CI, development tooling, Docker, or repository scripts. scope:multi-area Touches more compiler areas than the automatic area-label cap. size:l Large pull request. type:feature Introduces new user-visible behavior or capabilities. labels Jul 30, 2026
@greptile-apps

greptile-apps Bot commented Jul 30, 2026

Copy link
Copy Markdown

Greptile Summary

This PR decouples dynamic eval() regex support from the Magician binary's static link graph by introducing a versioned callback-based provider ABI. A new --with-regex flag and OnceLock-backed registration mechanism allow Magician-only binaries to build without PCRE2, while programs that declare pcre2 and pass --with-regex get the managed shim registered before the first eval dispatch.

  • Regex provider ABI (crates/elephc-magician/src/regex_provider.rs): a new RegexProvider struct holds compile/exec/free function pointers; __elephc_eval_register_regex_provider registers them idempotently via OnceLock; test builds install a host-PCRE2 adapter transparently.
  • Provider registration in codegen (src/codegen/lower_inst/builtins/eval.rs): register_eval_regex_provider is inserted into the "not yet initialized" branch of ensure_eval_context, emitting the three shim symbol addresses as arguments only when runtime_features.regex is set.
  • REG_STARTEND shim fix (src/native_deps/recipes/pcre2_shim.c): saves caller-supplied start/end offsets before zeroing the output array and restores them into the POSIX match struct, correcting the byte-range search behavior; recipe revision bumped from 1 to 2.
  • --with-regex CLI and pipeline wiring: the flag is accepted as a non-bridge runtime capability, forces runtime_features.regex, and triggers a post-build reminder on stderr when eval is compiled without the capability.

Confidence Score: 5/5

Safe to merge — the change is additive, all new code paths are tested end-to-end, and the decoupling from direct PCRE2 linkage is mechanically correct.

The provider ABI is registered exactly once via OnceLock, the codegen correctly gates symbol emission on runtime_features.regex, the pcre2_shim REG_STARTEND fix is validated by a new C-level test, and all four behavior combinations have dedicated test coverage. No regressions in existing eval behavior are expected.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
crates/elephc-magician/src/regex_provider.rs New file: introduces the versioned provider ABI and OnceLock-backed registration; test builds return an always-available host-PCRE2 provider; production path returns None until the generated init code calls __elephc_eval_register_regex_provider.
src/codegen/lower_inst/builtins/eval.rs Adds register_eval_regex_provider to the not-yet-initialized branch of ensure_eval_context; emits symbol addresses for the three shim callbacks only when runtime_features.regex is set.
src/codegen_support/runtime_features.rs Decouples eval_bridge from the pcre2 link requirement; eval alone now requires only the magician bridge, while regex is an independent feature that adds the pcre2 native package.
src/pipeline.rs Forces runtime_features.regex when --with-regex is present and emits a post-build reminder when eval is compiled without regex support via direct eprintln!.
src/cli.rs Extends --with- to accept non-bridge runtime capabilities alongside bridge crate names; error message and help text updated.
src/native_deps/recipes/pcre2_shim.c Fixes REG_STARTEND handling by saving caller-supplied start/end offsets before zeroing the output array; recipe revision bumped from 1 to 2.
crates/elephc-magician/build.rs Switches from cargo:rustc-link-lib to cargo:rustc-link-arg so PCRE2 is not propagated to downstream users of the staticlib.
crates/elephc-magician/src/interpreter/builtins/registry/mod.rs Adds builtin_is_available helper that gates regex-area builtins on provider registration.
tests/codegen/eval.rs Adds four new tests covering all behavior combinations; existing preg_* tests migrated to compile_and_run_with_regex.
tests/codegen/support/compiler.rs Extends fixture helpers with optional regex capability propagation; adds compile_and_run_with_regex and compile_and_run_capture_with_regex entry points.

Sequence Diagram

sequenceDiagram
    participant CLI as elephc CLI
    participant Pipeline as pipeline.rs
    participant Codegen as eval.rs codegen
    participant Binary as Generated Binary
    participant Magician as libelephc_magician
    participant Shim as pcre2_shim

    CLI->>Pipeline: --with-regex flag
    Pipeline->>Pipeline: "runtime_features.regex = true"
    Pipeline->>Pipeline: link pcre2 native package
    Pipeline->>Codegen: generate eval call site
    Codegen->>Codegen: ensure_eval_context (not yet initialized)
    Codegen->>Codegen: register_eval_regex_provider emits compile/exec/free addrs
    Codegen->>Codegen: call __elephc_eval_register_regex_provider
    Codegen->>Codegen: call __elephc_eval_init

    Note over Binary,Shim: At runtime

    Binary->>Magician: __elephc_eval_register_regex_provider(compile, exec, free)
    Magician->>Magician: REGEX_PROVIDER.set(RegexProvider)
    Binary->>Magician: eval preg_match call
    Magician->>Magician: "builtin_is_available -> regex_provider_available() = true"
    Magician->>Shim: provider.compile(pattern, flags, slots)
    Shim-->>Magician: opaque handle
    Magician->>Shim: provider.exec(handle, subject, slots, pairs, REG_STARTEND)
    Shim-->>Magician: match offsets
    Magician->>Shim: provider.free(handle)
Loading

Reviews (3): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

@nahime0
nahime0 requested a review from Guikingone July 31, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:codegen Touches target-aware assembly or backend lowering. area:magician Touches eval, include execution, or elephc-magician. area:tooling-ci Touches CI, development tooling, Docker, or repository scripts. scope:multi-area Touches more compiler areas than the automatic area-label cap. size:l Large pull request. type:feature Introduces new user-visible behavior or capabilities.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant