- ,
+ {
+ self.callset.extend(callees);
+ }
+
+ /// Registers a call to an externally-defined procedure which we have previously compiled.
+ ///
+ /// The call set of the callee is added to the call set of the procedure we are currently
+ /// compiling, to reflect that all of the code reachable from the callee is by extension
+ /// reachable by the caller.
+ pub fn register_external_call(
+ &mut self,
+ callee: &Procedure,
+ inlined: bool,
+ ) -> Result<(), AssemblyError> {
+ // If we call the callee, it's callset is by extension part of our callset
+ self.extend_callset(callee.callset().iter().cloned());
+
+ // If the callee is not being inlined, add it to our callset
+ if !inlined {
+ self.insert_callee(callee.mast_root());
+ }
+
+ Ok(())
+ }
+
+ /// Transforms this procedure context into a [Procedure].
+ ///
+ /// The passed-in `mast_root` defines the MAST root of the procedure's body while
+ /// `mast_node_id` specifies the ID of the procedure's body node in the MAST forest in
+ /// which the procedure is defined.
+ ///
+ ///
+ /// `mast_root` and `mast_node_id` must be consistent. That is, the node located in the MAST
+ /// forest under `mast_node_id` must have the digest equal to the `mast_root`.
+ ///
+ pub fn into_procedure(self, mast_root: RpoDigest, mast_node_id: MastNodeId) -> Procedure {
+ Procedure::new(self.name, self.visibility, self.num_locals as u32, mast_root, mast_node_id)
+ .with_span(self.span)
+ .with_source_file(self.source_file)
+ .with_callset(self.callset)
+ }
+}
+
+impl Spanned for ProcedureContext {
+ fn span(&self) -> SourceSpan {
+ self.span
+ }
+}
+
// PROCEDURE
// ================================================================================================
-/// A compiled Miden Assembly procedure, consisting of MAST and basic metadata.
+/// A compiled Miden Assembly procedure, consisting of MAST info and basic metadata.
///
/// Procedure metadata includes:
///
-/// * Fully-qualified path of the procedure in Miden Assembly (if known).
-/// * Number of procedure locals to allocate.
-/// * The visibility of the procedure (e.g. public/private/syscall)
-/// * The set of MAST roots invoked by this procedure.
-/// * The original source span and file of the procedure (if available).
+/// - Fully-qualified path of the procedure in Miden Assembly (if known).
+/// - Number of procedure locals to allocate.
+/// - The visibility of the procedure (e.g. public/private/syscall)
+/// - The set of MAST roots invoked by this procedure.
+/// - The original source span and file of the procedure (if available).
#[derive(Clone, Debug)]
pub struct Procedure {
span: SourceSpan,
@@ -28,18 +166,22 @@ pub struct Procedure {
path: FullyQualifiedProcedureName,
visibility: Visibility,
num_locals: u32,
- /// The MAST node id for the root of this procedure
+ /// The MAST root of the procedure.
+ mast_root: RpoDigest,
+ /// The MAST node id which resolves to the above MAST root.
body_node_id: MastNodeId,
/// The set of MAST roots called by this procedure
callset: CallSet,
}
-/// Builder
+// ------------------------------------------------------------------------------------------------
+/// Constructors
impl Procedure {
- pub(crate) fn new(
+ fn new(
path: FullyQualifiedProcedureName,
visibility: Visibility,
num_locals: u32,
+ mast_root: RpoDigest,
body_node_id: MastNodeId,
) -> Self {
Self {
@@ -48,6 +190,7 @@ impl Procedure {
path,
visibility,
num_locals,
+ mast_root,
body_node_id,
callset: Default::default(),
}
@@ -69,7 +212,8 @@ impl Procedure {
}
}
-/// Metadata
+// ------------------------------------------------------------------------------------------------
+/// Public accessors
impl Procedure {
/// Returns a reference to the name of this procedure
#[allow(unused)]
@@ -105,9 +249,8 @@ impl Procedure {
}
/// Returns the root of this procedure's MAST.
- pub fn mast_root(&self, mast_forest: &MastForest) -> RpoDigest {
- let body_node = &mast_forest[self.body_node_id];
- body_node.digest()
+ pub fn mast_root(&self) -> RpoDigest {
+ self.mast_root
}
/// Returns a reference to the MAST node ID of this procedure.
From 4f0dbf2ddf94be2ce24239940efc306e2d86e2d5 Mon Sep 17 00:00:00 2001
From: Bobbin Threadbare
Date: Tue, 23 Jul 2024 14:50:18 -0700
Subject: [PATCH 6/7] chore: fix typos and add section separators
---
.../module_graph/analysis/rewrite_check.rs | 18 ++-
.../assembler/module_graph/name_resolver.rs | 134 +++++++++---------
.../assembler/module_graph/rewrites/module.rs | 3 +
3 files changed, 82 insertions(+), 73 deletions(-)
diff --git a/assembly/src/assembler/module_graph/analysis/rewrite_check.rs b/assembly/src/assembler/module_graph/analysis/rewrite_check.rs
index 4c097133e5..c2941a181e 100644
--- a/assembly/src/assembler/module_graph/analysis/rewrite_check.rs
+++ b/assembly/src/assembler/module_graph/analysis/rewrite_check.rs
@@ -11,15 +11,18 @@ use crate::{
AssemblyError, Spanned,
};
+// MAYBE REWRITE CHECK
+// ================================================================================================
+
/// [MaybeRewriteCheck] is a simple analysis pass over a [Module], that looks for evidence that new
/// information has been found that would result in at least one rewrite to the module body.
///
-/// This pass is intended for modules that were already added to a [ModuleGraph], and so have been
-/// rewritten at least once before. When new modules are added to the graph, the introduction of
-/// those modules may allow us to resolve invocation targets that were previously unresolvable, or
-/// that resolved as phantoms due to missing definitions. When that occurs, we want to go back and
-/// rewrite all of the modules that can be further refined as a result of that additional
-/// information.
+/// This pass is intended for modules that were already added to a [super::super::ModuleGraph], and
+/// so have been rewritten at least once before. When new modules are added to the graph, the
+/// introduction of those modules may allow us to resolve invocation targets that were previously
+/// unresolvable, or that resolved as phantoms due to missing definitions. When that occurs, we
+/// want to go back and rewrite all of the modules that can be further refined as a result of that
+/// additional information.
pub struct MaybeRewriteCheck<'a, 'b: 'a> {
resolver: &'a NameResolver<'b>,
}
@@ -44,6 +47,9 @@ impl<'a, 'b: 'a> MaybeRewriteCheck<'a, 'b> {
}
}
+// REWRITE CHECK VISITOR
+// ================================================================================================
+
struct RewriteCheckVisitor<'a, 'b: 'a> {
resolver: &'a NameResolver<'b>,
module_id: ModuleIndex,
diff --git a/assembly/src/assembler/module_graph/name_resolver.rs b/assembly/src/assembler/module_graph/name_resolver.rs
index 07fb614dc6..4703ebf94b 100644
--- a/assembly/src/assembler/module_graph/name_resolver.rs
+++ b/assembly/src/assembler/module_graph/name_resolver.rs
@@ -120,9 +120,71 @@ impl<'a> NameResolver<'a> {
});
}
+ /// Resolve `target`, a possibly-resolved callee identifier, to a [ResolvedTarget], using
+ /// `caller` as the context.
+ pub fn resolve_target(
+ &self,
+ caller: &CallerInfo,
+ target: &InvocationTarget,
+ ) -> Result {
+ match target {
+ InvocationTarget::MastRoot(mast_root) => {
+ match self.graph.get_procedure_index_by_digest(mast_root) {
+ None => Ok(ResolvedTarget::Phantom(mast_root.into_inner())),
+ Some(gid) => Ok(ResolvedTarget::Exact { gid }),
+ }
+ }
+ InvocationTarget::ProcedureName(ref callee) => self.resolve(caller, callee),
+ InvocationTarget::ProcedurePath {
+ ref name,
+ module: ref imported_module,
+ } => match self.resolve_import(caller, imported_module) {
+ Some(imported_module) => {
+ let fqn = FullyQualifiedProcedureName {
+ span: target.span(),
+ module: imported_module.into_inner().clone(),
+ name: name.clone(),
+ };
+ let gid = self.find(caller, &fqn)?;
+ let path = self.module_path(gid.module);
+ let pending_offset = self.graph.modules.len();
+ let name = if gid.module.as_usize() >= pending_offset {
+ self.pending[gid.module.as_usize() - pending_offset]
+ .resolver
+ .get_name(gid.index)
+ .clone()
+ } else {
+ self.graph[gid].name().clone()
+ };
+ Ok(ResolvedTarget::Resolved {
+ gid,
+ target: InvocationTarget::AbsoluteProcedurePath { name, path },
+ })
+ }
+ None => Err(AssemblyError::UndefinedModule {
+ span: target.span(),
+ source_file: caller.source_file.clone(),
+ path: LibraryPath::new_from_components(
+ LibraryNamespace::User(imported_module.clone().into_inner()),
+ [],
+ ),
+ }),
+ },
+ InvocationTarget::AbsoluteProcedurePath { ref name, ref path } => {
+ let fqn = FullyQualifiedProcedureName {
+ span: target.span(),
+ module: path.clone(),
+ name: name.clone(),
+ };
+ let gid = self.find(caller, &fqn)?;
+ Ok(ResolvedTarget::Exact { gid })
+ }
+ }
+ }
+
/// Resolver `callee` to a [ResolvedTarget], using `caller` as the context in which `callee`
/// should be resolved.
- pub fn resolve(
+ fn resolve(
&self,
caller: &CallerInfo,
callee: &ProcedureName,
@@ -175,7 +237,7 @@ impl<'a> NameResolver<'a> {
/// Resolve `name`, the name of an imported module, to a [LibraryPath], using `caller` as the
/// context.
- pub fn resolve_import(&self, caller: &CallerInfo, name: &Ident) -> Option> {
+ fn resolve_import(&self, caller: &CallerInfo, name: &Ident) -> Option> {
let pending_offset = self.graph.modules.len();
if caller.module.as_usize() >= pending_offset {
self.pending[caller.module.as_usize() - pending_offset]
@@ -188,68 +250,6 @@ impl<'a> NameResolver<'a> {
}
}
- /// Resolve `target`, a possibly-resolved callee identifier, to a [ResolvedTarget], using
- /// `caller` as the context.
- pub fn resolve_target(
- &self,
- caller: &CallerInfo,
- target: &InvocationTarget,
- ) -> Result {
- match target {
- InvocationTarget::MastRoot(mast_root) => {
- match self.graph.get_procedure_index_by_digest(mast_root) {
- None => Ok(ResolvedTarget::Phantom(mast_root.into_inner())),
- Some(gid) => Ok(ResolvedTarget::Exact { gid }),
- }
- }
- InvocationTarget::ProcedureName(ref callee) => self.resolve(caller, callee),
- InvocationTarget::ProcedurePath {
- ref name,
- module: ref imported_module,
- } => match self.resolve_import(caller, imported_module) {
- Some(imported_module) => {
- let fqn = FullyQualifiedProcedureName {
- span: target.span(),
- module: imported_module.into_inner().clone(),
- name: name.clone(),
- };
- let gid = self.find(caller, &fqn)?;
- let path = self.module_path(gid.module);
- let pending_offset = self.graph.modules.len();
- let name = if gid.module.as_usize() >= pending_offset {
- self.pending[gid.module.as_usize() - pending_offset]
- .resolver
- .get_name(gid.index)
- .clone()
- } else {
- self.graph[gid].name().clone()
- };
- Ok(ResolvedTarget::Resolved {
- gid,
- target: InvocationTarget::AbsoluteProcedurePath { name, path },
- })
- }
- None => Err(AssemblyError::UndefinedModule {
- span: target.span(),
- source_file: caller.source_file.clone(),
- path: LibraryPath::new_from_components(
- LibraryNamespace::User(imported_module.clone().into_inner()),
- [],
- ),
- }),
- },
- InvocationTarget::AbsoluteProcedurePath { ref name, ref path } => {
- let fqn = FullyQualifiedProcedureName {
- span: target.span(),
- module: path.clone(),
- name: name.clone(),
- };
- let gid = self.find(caller, &fqn)?;
- Ok(ResolvedTarget::Exact { gid })
- }
- }
- }
-
fn resolve_local(
&self,
caller: &CallerInfo,
@@ -278,11 +278,11 @@ impl<'a> NameResolver<'a> {
}
}
- /// Resolve `name` to its concrete definition, returning the corresponding
+ /// Resolve `callee` to its concrete definition, returning the corresponding
/// [GlobalProcedureIndex].
///
/// If an error occurs during resolution, or the name cannot be resolved, `Err` is returned.
- pub fn find(
+ fn find(
&self,
caller: &CallerInfo,
callee: &FullyQualifiedProcedureName,
@@ -430,7 +430,7 @@ impl<'a> NameResolver<'a> {
}
/// Resolve a [LibraryPath] to a [ModuleIndex] in this graph
- pub fn find_module_index(&self, name: &LibraryPath) -> Option {
+ fn find_module_index(&self, name: &LibraryPath) -> Option {
self.graph
.modules
.iter()
diff --git a/assembly/src/assembler/module_graph/rewrites/module.rs b/assembly/src/assembler/module_graph/rewrites/module.rs
index 9d39307b89..4637ff2f4e 100644
--- a/assembly/src/assembler/module_graph/rewrites/module.rs
+++ b/assembly/src/assembler/module_graph/rewrites/module.rs
@@ -14,6 +14,9 @@ use crate::{
AssemblyError, Spanned,
};
+// MODULE REWRITE CHECK
+// ================================================================================================
+
/// A [ModuleRewriter] handles applying all of the module-wide rewrites to a [Module] that is being
/// added to a [ModuleGraph]. These rewrites include:
///
From 454d34415223ad868d29a4e6e2720cd36a48875b Mon Sep 17 00:00:00 2001
From: Andrey Khmuro
Date: Wed, 24 Jul 2024 12:37:17 +0300
Subject: [PATCH 7/7] Rename `internals` feature to `testing` (#1399)
* refactor: rename internals feature to testing
* chore: update CHANGELOG
---
CHANGELOG.md | 1 +
Makefile | 2 +-
air/Cargo.toml | 2 +-
air/src/trace/main_trace.rs | 4 ++--
processor/Cargo.toml | 2 +-
processor/src/host/advice/inputs.rs | 6 +++---
processor/src/host/advice/providers.rs | 4 ++--
processor/src/host/mod.rs | 4 ++--
processor/src/lib.rs | 4 ++--
processor/src/stack/mod.rs | 2 +-
processor/src/stack/trace.rs | 2 +-
stdlib/Cargo.toml | 2 +-
test-utils/Cargo.toml | 2 +-
13 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 53d198691c..f71356af6d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@
#### Changed
- When using `if.(true|false) .. end`, the parser used to emit an empty block for the branch that was elided. The parser now emits a block containing a single `nop` instruction instead, which is equivalent to the code emitted by the assembler when lowering to MAST.
+- `internals` configuration feature was renamed to `testing` (#1399).
## 0.9.2 (2024-05-22) - `stdlib` crate only
diff --git a/Makefile b/Makefile
index c5df854680..8ad16f81e1 100644
--- a/Makefile
+++ b/Makefile
@@ -51,7 +51,7 @@ mdbook: ## Generates mdbook documentation
.PHONY: test
test: ## Runs all tests
- $(DEBUG_ASSERTIONS) cargo nextest run --cargo-profile test-release --features internals
+ $(DEBUG_ASSERTIONS) cargo nextest run --cargo-profile test-release --features testing
# --- checking ------------------------------------------------------------------------------------
diff --git a/air/Cargo.toml b/air/Cargo.toml
index 267be62ba6..47249e8f70 100644
--- a/air/Cargo.toml
+++ b/air/Cargo.toml
@@ -28,7 +28,7 @@ harness = false
[features]
default = ["std"]
std = ["vm-core/std", "winter-air/std"]
-internals = []
+testing = []
[dependencies]
vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false }
diff --git a/air/src/trace/main_trace.rs b/air/src/trace/main_trace.rs
index c25d8716c8..d51c3fcec9 100644
--- a/air/src/trace/main_trace.rs
+++ b/air/src/trace/main_trace.rs
@@ -19,7 +19,7 @@ use super::{
use core::ops::{Deref, Range};
use vm_core::{utils::range, Felt, Word, ONE, ZERO};
-#[cfg(any(test, feature = "internals"))]
+#[cfg(any(test, feature = "testing"))]
use alloc::vec::Vec;
// CONSTANTS
@@ -54,7 +54,7 @@ impl MainTrace {
self.columns.num_rows()
}
- #[cfg(any(test, feature = "internals"))]
+ #[cfg(any(test, feature = "testing"))]
pub fn get_column_range(&self, range: Range) -> Vec> {
range.fold(vec![], |mut acc, col_idx| {
acc.push(self.get_column(col_idx).to_vec());
diff --git a/processor/Cargo.toml b/processor/Cargo.toml
index f7e31acebd..4bd83943c2 100644
--- a/processor/Cargo.toml
+++ b/processor/Cargo.toml
@@ -20,7 +20,7 @@ doctest = false
[features]
concurrent = ["std", "winter-prover/concurrent"]
default = ["std"]
-internals = ["miden-air/internals"]
+testing = ["miden-air/testing"]
std = ["vm-core/std", "winter-prover/std"]
[dependencies]
diff --git a/processor/src/host/advice/inputs.rs b/processor/src/host/advice/inputs.rs
index 7e217ecea5..ffce6345f3 100644
--- a/processor/src/host/advice/inputs.rs
+++ b/processor/src/host/advice/inputs.rs
@@ -18,7 +18,7 @@ use vm_core::crypto::hash::RpoDigest;
/// 2. Key-mapped element lists which can be pushed onto the advice stack.
/// 3. Merkle store, which is used to provide nondeterministic inputs for instructions that operates
/// with Merkle trees.
-#[cfg(not(feature = "internals"))]
+#[cfg(not(feature = "testing"))]
#[derive(Clone, Debug, Default)]
pub struct AdviceInputs {
stack: Vec,
@@ -132,10 +132,10 @@ impl AdviceInputs {
}
}
-// INTERNALS
+// TESTING
// ================================================================================================
-#[cfg(feature = "internals")]
+#[cfg(feature = "testing")]
#[derive(Clone, Debug, Default)]
pub struct AdviceInputs {
pub stack: Vec,
diff --git a/processor/src/host/advice/providers.rs b/processor/src/host/advice/providers.rs
index e6846ef4f5..3e7cd11c52 100644
--- a/processor/src/host/advice/providers.rs
+++ b/processor/src/host/advice/providers.rs
@@ -243,7 +243,7 @@ impl From for MemAdviceProvider {
}
/// Accessors to internal data structures of the provider used for testing purposes.
-#[cfg(any(test, feature = "internals"))]
+#[cfg(any(test, feature = "testing"))]
impl MemAdviceProvider {
/// Returns the current state of the advice stack.
pub fn stack(&self) -> &[Felt] {
@@ -364,7 +364,7 @@ impl From for RecAdviceProvider {
}
/// Accessors to internal data structures of the provider used for testing purposes.
-#[cfg(any(test, feature = "internals"))]
+#[cfg(any(test, feature = "testing"))]
impl RecAdviceProvider {
/// Returns the current state of the advice stack.
pub fn stack(&self) -> &[Felt] {
diff --git a/processor/src/host/mod.rs b/processor/src/host/mod.rs
index d6bfe9a79d..86a2128092 100644
--- a/processor/src/host/mod.rs
+++ b/processor/src/host/mod.rs
@@ -309,12 +309,12 @@ where
self.store.insert(mast_forest)
}
- #[cfg(any(test, feature = "internals"))]
+ #[cfg(any(test, feature = "testing"))]
pub fn advice_provider(&self) -> &A {
&self.adv_provider
}
- #[cfg(any(test, feature = "internals"))]
+ #[cfg(any(test, feature = "testing"))]
pub fn advice_provider_mut(&mut self) -> &mut A {
&mut self.adv_provider
}
diff --git a/processor/src/lib.rs b/processor/src/lib.rs
index 95ab09e7ed..3f5648c4ea 100644
--- a/processor/src/lib.rs
+++ b/processor/src/lib.rs
@@ -171,7 +171,7 @@ where
/// However, for situations in which you want finer-grained control over those steps, you will need
/// to construct an instance of [Process] using [Process::new], invoke [Process::execute], and then
/// get the execution trace using [ExecutionTrace::new] using the outputs produced by execution.
-#[cfg(not(any(test, feature = "internals")))]
+#[cfg(not(any(test, feature = "testing")))]
pub struct Process
where
H: Host,
@@ -186,7 +186,7 @@ where
enable_tracing: bool,
}
-#[cfg(any(test, feature = "internals"))]
+#[cfg(any(test, feature = "testing"))]
pub struct Process
where
H: Host,
diff --git a/processor/src/stack/mod.rs b/processor/src/stack/mod.rs
index 86419d23fe..cd65cc74a0 100644
--- a/processor/src/stack/mod.rs
+++ b/processor/src/stack/mod.rs
@@ -330,7 +330,7 @@ impl Stack {
/// Returns state of stack item columns at the current clock cycle. This does not include stack
/// values in the overflow table.
- #[cfg(any(test, feature = "internals"))]
+ #[cfg(any(test, feature = "testing"))]
pub fn trace_state(&self) -> [Felt; STACK_TOP_SIZE] {
self.trace.get_stack_state_at(self.clk)
}
diff --git a/processor/src/stack/trace.rs b/processor/src/stack/trace.rs
index 960fd79827..c8534df24f 100644
--- a/processor/src/stack/trace.rs
+++ b/processor/src/stack/trace.rs
@@ -200,7 +200,7 @@ impl StackTrace {
// --------------------------------------------------------------------------------------------
/// Returns the stack trace state at the specified clock cycle.
- #[cfg(any(test, feature = "internals"))]
+ #[cfg(any(test, feature = "testing"))]
pub fn get_stack_state_at(&self, clk: u32) -> [Felt; STACK_TOP_SIZE] {
let mut result = [ZERO; STACK_TOP_SIZE];
for (result, column) in result.iter_mut().zip(self.stack.iter()) {
diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml
index 55a3849b80..b7fe8bcbdf 100644
--- a/stdlib/Cargo.toml
+++ b/stdlib/Cargo.toml
@@ -35,7 +35,7 @@ num = "0.4.1"
num-bigint = "0.4"
pretty_assertions = "1.4"
processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false, features = [
- "internals",
+ "testing",
] }
rand = { version = "0.8.5", default-features = false }
serde_json = "1.0"
diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml
index 0873c88315..680a79986a 100644
--- a/test-utils/Cargo.toml
+++ b/test-utils/Cargo.toml
@@ -28,7 +28,7 @@ assembly = { package = "miden-assembly", path = "../assembly", version = "0.9",
"testing",
] }
processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false, features = [
- "internals",
+ "testing",
] }
prover = { package = "miden-prover", path = "../prover", version = "0.9", default-features = false }
test-case = "3.2"