From 1f5f59b3f2230f94a32b9126d9d7a04b4daf7d21 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 15 Aug 2024 01:28:27 -0700 Subject: [PATCH 1/4] feat: enable executing external Dyn nodes --- CHANGELOG.md | 6 ++++ processor/src/lib.rs | 70 ++++++++++++++++++++++++-------------------- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d98a8c2b5..7ae2abf8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.10.4 (2024-08-15) + +#### Enhancements + +- Added support for executing `Dyn` nodes from external MAST forests (#1455). + ## 0.10.3 (2024-08-12) #### Enhancements diff --git a/processor/src/lib.rs b/processor/src/lib.rs index de1a1f3dd..3aef82c9f 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -24,9 +24,7 @@ pub use vm_core::{ StackInputs, StackOutputs, Word, EMPTY_WORD, ONE, ZERO, }; use vm_core::{ - mast::{ - BasicBlockNode, CallNode, DynNode, JoinNode, LoopNode, OpBatch, SplitNode, OP_GROUP_SIZE, - }, + mast::{BasicBlockNode, CallNode, JoinNode, LoopNode, OpBatch, SplitNode, OP_GROUP_SIZE}, Decorator, DecoratorIterator, FieldElement, StackTopState, }; pub use winter_prover::matrix::ColMatrix; @@ -267,11 +265,11 @@ where node_id: MastNodeId, program: &MastForest, ) -> Result<(), ExecutionError> { - let wrapper_node = &program + let node = program .get_node_by_id(node_id) .ok_or(ExecutionError::MastNodeNotFoundInForest { node_id })?; - match wrapper_node { + match node { MastNode::Block(node) => self.execute_basic_block_node(node), MastNode::Join(node) => self.execute_join_node(node, program), MastNode::Split(node) => self.execute_split_node(node, program), @@ -286,8 +284,8 @@ where }, )?; - // We temporarily limit the parts of the program that can be called externally to - // procedure roots, even though MAST doesn't have that restriction. + // We limit the parts of the program that can be called externally to procedure + // roots, even though MAST doesn't have that restriction. let root_id = mast_forest.find_procedure_root(external_node.digest()).ok_or( ExecutionError::MalformedMastForestInHost { root_digest: external_node.digest(), @@ -299,6 +297,7 @@ where } } + /// Executes the specified [JoinNode]. #[inline(always)] fn execute_join_node( &mut self, @@ -314,6 +313,7 @@ where self.end_join_node(node) } + /// Executes the specified [SplitNode]. #[inline(always)] fn execute_split_node( &mut self, @@ -335,7 +335,7 @@ where self.end_split_node(node) } - /// Executes the specified [Loop] block. + /// Executes the specified [LoopNode]. #[inline(always)] fn execute_loop_node( &mut self, @@ -370,55 +370,61 @@ where } } - /// Executes the specified [Call] block. + /// Executes the specified [CallNode]. #[inline(always)] fn execute_call_node( &mut self, call_node: &CallNode, program: &MastForest, ) -> Result<(), ExecutionError> { - let callee_digest = { + // if this is a syscall, make sure the call target exists in the kernel + if call_node.is_syscall() { let callee = program.get_node_by_id(call_node.callee()).ok_or_else(|| { ExecutionError::MastNodeNotFoundInForest { node_id: call_node.callee() } })?; - - callee.digest() - }; - - // if this is a syscall, make sure the call target exists in the kernel - if call_node.is_syscall() { - self.chiplets.access_kernel_proc(callee_digest)?; + self.chiplets.access_kernel_proc(callee.digest())?; } self.start_call_node(call_node, program)?; - - // if this is a dyncall, execute the dynamic code block - if callee_digest == DynNode.digest() { - self.execute_dyn_node(program)?; - } else { - self.execute_mast_node(call_node.callee(), program)?; - } - + self.execute_mast_node(call_node.callee(), program)?; self.end_call_node(call_node) } - /// Executes the specified [DynNode] node. + /// Executes the specified [vm_core::mast::DynNode]. + /// + /// The MAST root of the callee is assumed to be at the top of the stack, and the callee is + /// expected to be either in the current `program` or in the host. #[inline(always)] fn execute_dyn_node(&mut self, program: &MastForest) -> Result<(), ExecutionError> { // get target hash from the stack let callee_hash = self.stack.get_word(0); self.start_dyn_node(callee_hash)?; - // get dynamic code from the code block table and execute it - let callee_id = program - .find_procedure_root(callee_hash.into()) - .ok_or_else(|| ExecutionError::DynamicNodeNotFound(callee_hash.into()))?; - self.execute_mast_node(callee_id, program)?; + // if the callee is not in the current MAST forest, try to find a MAST forest for it in the + // host; if not found in the host, return an error + match program.find_procedure_root(callee_hash.into()) { + Some(callee_id) => self.execute_mast_node(callee_id, program)?, + None => { + let mast_forest = self + .host + .borrow() + .get_mast_forest(&callee_hash.into()) + .ok_or_else(|| ExecutionError::DynamicNodeNotFound(callee_hash.into()))?; + + // We limit the parts of the program that can be called externally to procedure + // roots, even though MAST doesn't have that restriction. + let root_id = mast_forest.find_procedure_root(callee_hash.into()).ok_or( + ExecutionError::MalformedMastForestInHost { root_digest: callee_hash.into() }, + )?; + + self.execute_mast_node(root_id, &mast_forest)? + }, + } self.end_dyn_node() } - /// Executes the specified [`BasicBlockNode`] block. + /// Executes the specified [BasicBlockNode]. #[inline(always)] fn execute_basic_block_node( &mut self, From 85253d9407a3a107460b142b184046f05ad8c951 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Date: Thu, 15 Aug 2024 09:02:09 -0700 Subject: [PATCH 2/4] doc: improve comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Philippe Laferrière --- processor/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/processor/src/lib.rs b/processor/src/lib.rs index 3aef82c9f..04002c1b4 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -400,8 +400,8 @@ where let callee_hash = self.stack.get_word(0); self.start_dyn_node(callee_hash)?; - // if the callee is not in the current MAST forest, try to find a MAST forest for it in the - // host; if not found in the host, return an error + // if the callee is not in the program's MAST forest, try to find a MAST forest for it in the + // host (corresponding to an external library loaded in the host); if none are found, return an error. match program.find_procedure_root(callee_hash.into()) { Some(callee_id) => self.execute_mast_node(callee_id, program)?, None => { From 43340920fc89810465d0a0fd5acaebe0309f75cf Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 15 Aug 2024 09:50:19 -0700 Subject: [PATCH 3/4] fix: lint --- processor/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/processor/src/lib.rs b/processor/src/lib.rs index 04002c1b4..132a7a2cd 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -400,8 +400,9 @@ where let callee_hash = self.stack.get_word(0); self.start_dyn_node(callee_hash)?; - // if the callee is not in the program's MAST forest, try to find a MAST forest for it in the - // host (corresponding to an external library loaded in the host); if none are found, return an error. + // if the callee is not in the program's MAST forest, try to find a MAST forest for it in + // the host (corresponding to an external library loaded in the host); if none are + // found, return an error. match program.find_procedure_root(callee_hash.into()) { Some(callee_id) => self.execute_mast_node(callee_id, program)?, None => { From 35b3a4884e5d049634274d70af6432095cd63772 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 15 Aug 2024 09:52:29 -0700 Subject: [PATCH 4/4] chore: update miden-processor version to v0.10.4 --- Cargo.lock | 37 ++++++++++++++++++++++--------------- processor/Cargo.toml | 4 ++-- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c39e0d0b..d9d8f44e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,12 +243,13 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.10" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" +checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -756,9 +757,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -774,9 +775,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown", @@ -784,9 +785,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ "hermit-abi", "libc", @@ -1132,7 +1133,7 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.10.3" +version = "0.10.4" dependencies = [ "logtest", "miden-air", @@ -1874,18 +1875,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.207" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.207" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", @@ -1894,9 +1895,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" dependencies = [ "itoa", "memchr", @@ -1943,6 +1944,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "siphasher" version = "0.3.11" diff --git a/processor/Cargo.toml b/processor/Cargo.toml index 623e8f89d..1efc88a4d 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "miden-processor" -version = "0.10.3" +version = "0.10.4" description = "Miden VM processor" -documentation = "https://docs.rs/miden-processor/0.10.3" +documentation = "https://docs.rs/miden-processor/0.10.4" readme = "README.md" categories = ["emulators", "no-std"] keywords = ["miden", "virtual-machine"]