feat(hoist): pre-compute loop hoisting metadata at compilation time (#483)

Introduce a compiler pass that analyzes and pre-computes loop hoisting information
during policy compilation. This hoisted metadata is stored in lookup tables and made
available to downstream consumers:

- interpreter: use HoistedLoop entries during evaluation (replaces runtime scanning)
- type inference: can leverage pre-computed loop structure for type propagation
- RVM compiler: will consume hoisting metadata for optimized bytecode generation

Changes:
- populate loop hoisting tables during engine preparation and query snippet execution
- refactor eval_stmts_in_loop and eval_output_expr_in_loop to consume HoistedLoop directly
- add helper methods for accessing loop expressions, collections, and indices from HoistedLoop
- extend Lookup with get_checked and into_slots for safe query context access and merging

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2025-10-08 11:11:30 -05:00
committed by GitHub
parent 9604fe86f1
commit 5d8387f4d9
14 changed files with 1365 additions and 267 deletions

View File

@@ -82,7 +82,7 @@ mod load_target_definitions {
use crate::registry::targets;
// Load target definitions
let _ = load()?;
load()?;
// Check that the sample targets were loaded
assert!(
@@ -184,12 +184,13 @@ pub fn process_value(v: &Value) -> Result<Value> {
fn match_values(computed: &Value, expected: &Value) -> Result<()> {
if computed != expected {
let expected_yaml = serde_yaml::to_string(&expected)?;
let computed_yaml = serde_yaml::to_string(&computed)?;
panic!(
"{}",
prettydiff::diff_chars(
&serde_yaml::to_string(&expected)?,
&serde_yaml::to_string(&computed)?
)
"expected:\n{}computed:\n{}diff:\n{}",
expected_yaml,
computed_yaml,
prettydiff::diff_chars(&expected_yaml, &computed_yaml)
);
}
Ok(())