mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
refactor: consolidate RVM instruction variants and clean up VM internals (#651)
Merge the three separate Assert* instructions (AssertNot, AssertCondition,
AssertNotUndefined) into a single `Guard { register, mode }` instruction
with a GuardMode enum. This cuts duplicated match arms across display,
listing, parser, dispatch, and all compiler emit sites.
Drop the unnecessary `#[repr(C)]` from the Instruction enum. It was never
exposed across FFI, so the C-compatible 4-byte discriminant was pure waste.
Without it Rust picks a 1-byte discriminant, shrinking every instruction
from 8 bytes to 6. A new `instruction_size` unit test locks this at 6.
While touching these files, also clean up several long-standing issues:
- Deduplicate the iteration-state setup in loops.rs by extracting a shared
resolve_iteration_state() helper -- the stack-based and stackless paths
had near-identical 40-line blocks.
- Collapse the ExitWithSuccess / ExitWithFailure match arms into one.
- In rules.rs, stop cloning Arc<Program> just to borrow a RuleInfo -- clone
the small RuleInfo struct directly and extract a get_rule_info() helper.
- Move the memory check into dispatch (runs per instruction) and remove the
now-dead enforce_memory_check() entry-point calls.
- Apply map_or_else style throughout listing.rs for consistency.
This commit is contained in:
committed by
GitHub
parent
1a8fc08773
commit
126cc12eb5
+17
-29
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
use crate::rvm::instructions::{Instruction, LiteralOrRegister};
|
||||
use crate::rvm::instructions::{GuardMode, Instruction, LiteralOrRegister};
|
||||
use crate::rvm::program::Program;
|
||||
use crate::value::Value;
|
||||
use alloc::collections::BTreeSet;
|
||||
@@ -26,6 +26,7 @@ impl RegoVM {
|
||||
program: &Program,
|
||||
instruction: Instruction,
|
||||
) -> Result<InstructionOutcome> {
|
||||
self.memory_check()?;
|
||||
self.execute_load_and_move(program, instruction)
|
||||
}
|
||||
|
||||
@@ -317,9 +318,6 @@ impl RegoVM {
|
||||
}
|
||||
Not { dest, operand } => {
|
||||
let operand_value = self.get_register(operand)?;
|
||||
|
||||
// In Rego, `not expr` succeeds when `expr` is undefined or false,
|
||||
// and fails for any other defined value (including non-booleans like 42).
|
||||
let negated = match *operand_value {
|
||||
Value::Undefined => true,
|
||||
Value::Bool(b) => !b,
|
||||
@@ -335,35 +333,24 @@ impl RegoVM {
|
||||
self.handle_condition(passed)?;
|
||||
Ok(InstructionOutcome::Continue)
|
||||
}
|
||||
AssertNot { operand } => {
|
||||
let value = self.get_register(operand)?;
|
||||
let passed = match *value {
|
||||
Value::Undefined => true,
|
||||
Value::Bool(b) => !b,
|
||||
_ => false,
|
||||
Guard { register, mode } => {
|
||||
let value = self.get_register(register)?;
|
||||
let passed = match mode {
|
||||
GuardMode::Not => match *value {
|
||||
Value::Undefined => true,
|
||||
Value::Bool(b) => !b,
|
||||
_ => false,
|
||||
},
|
||||
GuardMode::Condition => match *value {
|
||||
Value::Bool(b) => b,
|
||||
Value::Undefined => false,
|
||||
_ => true,
|
||||
},
|
||||
GuardMode::NotUndefined => !matches!(value, Value::Undefined),
|
||||
};
|
||||
self.handle_condition(passed)?;
|
||||
Ok(InstructionOutcome::Continue)
|
||||
}
|
||||
AssertCondition { condition } => {
|
||||
let value = self.get_register(condition)?;
|
||||
|
||||
let condition_result = match *value {
|
||||
Value::Bool(b) => b,
|
||||
Value::Undefined => false,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
self.handle_condition(condition_result)?;
|
||||
Ok(InstructionOutcome::Continue)
|
||||
}
|
||||
AssertNotUndefined { register } => {
|
||||
let value = self.get_register(register)?;
|
||||
|
||||
let is_undefined = matches!(value, Value::Undefined);
|
||||
self.handle_condition(!is_undefined)?;
|
||||
Ok(InstructionOutcome::Continue)
|
||||
}
|
||||
other => self.execute_call_instruction(program, other),
|
||||
}
|
||||
}
|
||||
@@ -747,6 +734,7 @@ impl RegoVM {
|
||||
available: loop_params_len,
|
||||
})?;
|
||||
let mode = loop_params.mode;
|
||||
|
||||
let params = LoopParams {
|
||||
collection: loop_params.collection,
|
||||
key_reg: loop_params.key_reg,
|
||||
|
||||
Reference in New Issue
Block a user