Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce MastForestStore #1359

Merged
merged 43 commits into from
Jul 3, 2024
Merged

Introduce MastForestStore #1359

merged 43 commits into from
Jul 3, 2024

Conversation

plafer
Copy link
Contributor

@plafer plafer commented Jun 21, 2024

Follow-up to #1349.
Partially closes #1226

Introduces the MastForestStore (referred to elsewhere as ObjectStore).

Note that since packages aren't implemented yet, we still require programs to be assembled directly with the libraries they depend on. Hence, the current use of MastForestStore is limited to supported call.0x... and dyn calls to procedures assembled as part of a separate compilation unit.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Looks good. I left some comments inline. The biggest missing pieces are:

  • As far as I can tell, the assembler does not currently output any External nodes. We should output external nodes at least for call.0x... instructions and potentially for syscall instructions as well.
  • I think the way the MastForest is currently being built by the assembler would result in incorrect set of roots and also would contain duplicate nodes. So, we may want to introduce a concept of MastForestBuilder to address this.
    • We should also improve tests to make sure MastForests are being built by the assembler correctly.
  • We don't have a mechanism for loading Kernel forests into the VM processor - but maybe that's something we leave for the next PR.

core/src/mast/node/external.rs Outdated Show resolved Hide resolved
core/src/mast/node/external.rs Outdated Show resolved Hide resolved
core/src/mast/mod.rs Outdated Show resolved Hide resolved
core/src/program.rs Outdated Show resolved Hide resolved
core/src/program.rs Outdated Show resolved Hide resolved
assembly/src/assembler/mod.rs Outdated Show resolved Hide resolved
assembly/src/assembler/mod.rs Outdated Show resolved Hide resolved
assembly/src/assembler/mod.rs Outdated Show resolved Hide resolved
assembly/src/assembler/tests.rs Show resolved Hide resolved
assembly/src/assembler/instruction/procedures.rs Outdated Show resolved Hide resolved
@plafer plafer requested a review from bobbinth June 23, 2024 14:10
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! I left a few more comment inline - but all of them should be pretty straight forward.

Would be great to get a review from @bitwalker though - especially for the assembler-specific changes.

For the next PR, we should start working on the package format and MAST forest serialization. I'll write a more detailed comment in the issue discussion.

core/src/mast/mod.rs Show resolved Hide resolved
processor/src/operations/mod.rs Outdated Show resolved Hide resolved
assembly/src/assembler/tests.rs Show resolved Hide resolved
@bobbinth
Copy link
Contributor

Oh - and let's update the changelog.

@bitwalker
Copy link
Contributor

Sorry I haven't had a chance to review this yet, it's on the docket for tomorrow though, so bear with me!

@plafer plafer mentioned this pull request Jun 27, 2024
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good! Thank you!

@bitwalker - could you take a quick look? Would be great to merge this in the next day or so.

Copy link
Contributor

@bitwalker bitwalker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mostly done with my review, and am requesting changes, or at least discussion/clarification on a few points, but I'm still skimming a few remaining files outside of the assembler, but I'll add any comments to those as one-offs.

My primary concerns are two-fold:

  1. The ability to assemble libraries, not just executables
  2. The ability to exec procedures in libraries which are not part of the current translation unit (i.e. they were compiled as part of another library, not the current library/program).

As far as the compiler is concerned, those are blocking issues that cannot be left unresolved. They are also practical issues for packaging (and consequently, how to reference code across packages).

/// # Errors
///
/// Returns an error if parsing or compilation of the specified program fails.
pub fn assemble(self, source: impl Compile) -> Result<MastForest, Report> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the Assembler was changed so that it is no longer possible to assemble a library, only programs. The compiler, for example, is going to primarily be assembling libraries, not programs - particularly for the rollup, where accounts are libraries, and note scripts are not executables but libraries dynamically invoked from the "real" executable, the transaction kernel.

How does one obtain a MastForest for a library from the Assembler? I took a look around, but it looks to me like it isn't possible.

self.compile_body(then_blk.iter(), context, None, mast_forest)?;
let else_blk =
self.compile_body(else_blk.iter(), context, None, mast_forest)?;
self.compile_body(then_blk.iter(), context, None, mast_forest_builder)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there was a merge conflict here - the old version in the diff is actually newer than the "new" version in the diff: we no longer treat the else block specially here (either block could be empty now, and we rely on compile_body to fill empty bodies with a single nop, if any have made it to the assembler).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 3c26bd6

@@ -104,6 +104,15 @@ pub enum AssemblyError {
source_file: Option<Arc<SourceFile>>,
callee: RpoDigest,
},
#[error("invalid exec: exec'd procedures must be available during compilation, but '{callee}' is not")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not supposed to be an error - exec does not require the procedure to be available, and cannot require that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, removed

// effect of inlining it
InvokeKind::Exec => callee_id,
// For `call`, we just use the corresponding CALL block
InvokeKind::Exec => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused how we have ended up back here again - exec and call are identical in every respect, with the sole exception of their execution context semantics. Why are we treating exec differently than call here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, this was updated to act similarly to call: 25fe82f

root_digest: external_node.digest(),
},
)?;
let root_id = mast_forest.find_procedure_root(external_node.digest()).ok_or(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think that an External node could be any MAST node, not necessarily a procedure root. In particular, this would make it impossible to hide portions of a program - you would have to factor out all of the parts you want to hide into procedures, which sort of defeats the point. That was in fact what Proxy was used for previously, and I've somewhat lost the thread on what our plans are for the use cases it supported.

Maybe this is a fine restriction to have for now, but we should probably make a note here that the implicit assumption here that External nodes are always procedures is an artifact of other implementation choices, and not of the representation itself. In particular, the notion that exec is restricted to invoking procedures is a fiction - if you specify the MAST root of a non-procedure node as the callee of exec, that is totally valid, because the semantics are that the referenced MAST is treated as inlined at the callsite. This is in fact the only current means by which someone can hide portions of their program in Miden Assembly today.

Anyway, I'm bringing this up, because I know we made various claims about what the assembler does and does not produce when we were discussing Proxy, but I think what got lost in that discussion was what the prior representation made possible, that I'm not sure is being preserved by the changes made as part of the MAST refactoring. That may very well be deliberate, but it is not documented AFAICT.

Copy link
Contributor

@bitwalker bitwalker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@plafer plafer requested a review from bitwalker July 2, 2024 22:44
@plafer plafer merged commit 629ea82 into next Jul 3, 2024
15 checks passed
@plafer plafer deleted the plafer-object-store branch July 3, 2024 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants