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

Implement kernel compilation in the assembler #1418

Merged
merged 198 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
198 commits
Select commit Hold shift + click to select a range
a94d52d
Introduce `ExternalNode`
plafer Jun 20, 2024
f8ad339
Replace `Assembler.node_id_by_digest` map
plafer Jun 20, 2024
06f421b
add TODOP
plafer Jun 20, 2024
bcf2a9b
Add `Host::get_mast_forest`
plafer Jun 20, 2024
980713d
Move kernel and entrypoint out of `MastForest`
plafer Jun 21, 2024
d2bbcd2
Add Host::get_mast_forest
plafer Jun 21, 2024
32e757e
Remove ProgramError
plafer Jun 21, 2024
f87217a
docs
plafer Jun 21, 2024
71f35f1
cleanup Program constructors
plafer Jun 21, 2024
a39f74f
fix docs
plafer Jun 21, 2024
f7e98af
Make `Program.kernel` an `Arc`
plafer Jun 21, 2024
b5538c5
fix executable
plafer Jun 21, 2024
2eab574
Merge remote-tracking branch 'origin/next' into plafer-object-store
plafer Jun 21, 2024
188651b
invoke_mast_root: fix external node creation logic
plafer Jun 23, 2024
b15263c
add failing test
plafer Jun 23, 2024
a94a095
don't make root in `combine_mast_node_ids` and `compile_body`
plafer Jun 23, 2024
7af0bfa
fix External docs
plafer Jun 23, 2024
a6fcf47
fmt
plafer Jun 23, 2024
c66db6f
fix `entrypoint` doc
plafer Jun 23, 2024
572fc7e
Rename `Program::new_with_kernel()`
plafer Jun 23, 2024
08ce2c7
Document `MastForestStore` and `MemMastForestStore`
plafer Jun 23, 2024
50e01e9
fix syscall
plafer Jun 23, 2024
071ab54
execute_* functions: use `MastForest`
plafer Jun 23, 2024
49de40d
`Program`: Remove `Arc` around kernel
plafer Jun 23, 2024
c28c876
remove `Arc` around `MastForest` in `Program`
plafer Jun 23, 2024
78b2b16
Return error on malformed host
plafer Jun 23, 2024
4883b44
Simplify `DefaultHost`
plafer Jun 23, 2024
155a798
`MastForest::add_node()`: add docs
plafer Jun 23, 2024
bc6d13e
fmt
plafer Jun 23, 2024
be24320
add failing `duplicate_procedure()` test
plafer Jun 23, 2024
32aedd6
Introduce `MastForestBuilder`
plafer Jun 23, 2024
088de82
Rename `mod tests` -> `testing`
plafer Jun 25, 2024
9d48fda
add `duplicate_node()` test
plafer Jun 25, 2024
6c62d9b
changelog
plafer Jun 25, 2024
039bba0
Program: use `assert!()` instead of `debug_assert!()`
plafer Jun 26, 2024
9c9e171
`MastForest::make_root()`: add assert
plafer Jun 26, 2024
8e4dc5e
Merge remote-tracking branch 'origin/next' into plafer-object-store
plafer Jun 26, 2024
c34e985
fmt
plafer Jun 26, 2024
c1b2693
Serialization for `MastNodeId`
plafer Jun 26, 2024
efc24fd
serialization for MastNode variants except basic block
plafer Jun 26, 2024
861d0d5
MastForest serialization scaffolding
plafer Jun 27, 2024
6173790
define `MastNodeType` constructor from `MastNode`
plafer Jun 27, 2024
e018cc8
test join serialization of MastNodeType
plafer Jun 27, 2024
6671afe
`MastNodeType` serialization of split
plafer Jun 27, 2024
babdd0c
Revert "serialization for MastNode variants except basic block"
plafer Jun 27, 2024
cd06527
add TODOP
plafer Jun 27, 2024
2dd4829
impl Deserializable for `MastForest` (scaffold)
plafer Jul 1, 2024
4be1401
mast_node_to_info() scaffold
plafer Jul 1, 2024
2695062
try_info_to_mast_node scaffold
plafer Jul 1, 2024
ef0a881
Rename `EncodedMastNodeType`
plafer Jul 1, 2024
dd89461
add info module
plafer Jul 1, 2024
91009b0
encode operations into `data` field
plafer Jul 1, 2024
d5ed108
decode operations
plafer Jul 1, 2024
0cf49ff
implement `BasicBlockNode::num_operations_and_decorators()`
plafer Jul 2, 2024
64c36ec
OperationOrDecoratorIterator
plafer Jul 2, 2024
794ebbb
basic block node: move tests in new file
plafer Jul 2, 2024
49673ae
operation_or_decorator_iterator test
plafer Jul 2, 2024
a5c324b
Implement `Operation::with_opcode_and_data()`
plafer Jul 2, 2024
c04bc90
encode decorators
plafer Jul 2, 2024
27e2783
implement `decode_decorator()`
plafer Jul 2, 2024
25fe82f
fix exec invocation
plafer Jul 2, 2024
36ecdd7
Merge remote-tracking branch 'origin/next' into plafer-object-store
plafer Jul 2, 2024
3c26bd6
no else blk special case
plafer Jul 2, 2024
34c2f7f
add procedure roots comment
plafer Jul 2, 2024
97d3de8
Merge remote-tracking branch 'origin/next' into plafer-object-store
plafer Jul 3, 2024
3166dc2
Merge branch 'plafer-object-store' into plafer-mast-forest-serialization
plafer Jul 3, 2024
ffc7c78
implement forgotten `todo!()`
plafer Jul 3, 2024
5504157
`serialize_deserialize_all_nodes` test
plafer Jul 3, 2024
93c4fca
`decode_operations_and_decorators`: fix bit check
plafer Jul 3, 2024
da14984
confirm_assumptions test scaffold
plafer Jul 3, 2024
4870b32
minor adjustments
plafer Jul 3, 2024
072b0b9
Introduce `StringTableBuilder`
plafer Jul 3, 2024
a04836c
Merge remote-tracking branch 'origin/next' into plafer-mast-forest-se…
plafer Jul 3, 2024
48aec6a
naming
plafer Jul 3, 2024
a4ef4b1
test confirm_operation_and_decorator_structure
plafer Jul 3, 2024
ca0e7fe
remove TODOP
plafer Jul 3, 2024
78e35fc
remove unused `MastNode::new_dyncall()`
plafer Jul 3, 2024
411f9f3
Remove `Error` type
plafer Jul 3, 2024
624984c
add TODOP
plafer Jul 3, 2024
858582a
complete test `serialize_deserialize_all_nodes`
plafer Jul 3, 2024
4e5efd3
check digest on deserialization
plafer Jul 3, 2024
3f522b8
remove TODOP
plafer Jul 3, 2024
161578d
safely decode mast node ids
plafer Jul 3, 2024
2ab1cf9
use method syntax in `MastNodeType` decoding
plafer Jul 3, 2024
c8cfa8e
TODOPs
plafer Jul 3, 2024
a360959
rewrite <= expression
plafer Jul 3, 2024
c8ba463
new `MastNodeType`
plafer Jul 3, 2024
ad18580
implement `Deserializable` for `MastNodeType`
plafer Jul 3, 2024
996498f
migrate tests to new
plafer Jul 3, 2024
e60bfc2
Use new MastNodeType
plafer Jul 3, 2024
578bda9
rename string_table_builder_ module
plafer Jul 3, 2024
d25671c
implement `BasicBlockDataBuilder`
plafer Jul 3, 2024
99f4544
add TODOP
plafer Jul 3, 2024
0d20629
BasicBlockDataDecoder
plafer Jul 3, 2024
b66f81b
use `BasicBlockDataDecoder`
plafer Jul 3, 2024
f9a3a0b
add headers
plafer Jul 3, 2024
df621c5
add `MastNodeInfo` method
plafer Jul 3, 2024
2afd588
return `Result` instead of `Option`
plafer Jul 3, 2024
9106a6f
Remove TODOP
plafer Jul 3, 2024
fe8b7a7
docs
plafer Jul 3, 2024
5869525
chore: add section separators and fix typos
bobbinth Jul 7, 2024
8cb3462
refactor: change type of the error code of u32assert2 from Felt to u3…
Fumuran Jul 10, 2024
5ec4826
impl `Serializable` for `Operation`
plafer Jul 10, 2024
d4a50e9
impl Deserializable for `Operation`
plafer Jul 10, 2024
3ce71b9
`StringTableBuilder`: switch to using blake 3
plafer Jul 10, 2024
db33dc7
`EncodedDecoratorVariant`: moved discriminant bit logic to `discrimin…
plafer Jul 10, 2024
10f02a6
Remove basic block offset
plafer Jul 10, 2024
421518d
Cargo: don't specify patch versions
plafer Jul 10, 2024
cf100c5
make deserialization more efficient
plafer Jul 10, 2024
f50073d
num-traits and num-derive: set default-features false
plafer Jul 10, 2024
aacb9e9
Merge branch 'next' into plafer-mast-forest-serialization
plafer Jul 11, 2024
956aac1
Remove `OperationData`
plafer Jul 11, 2024
9fe4e0e
`StringRef`: move string length to data buffer
plafer Jul 11, 2024
c525828
store offset in block
plafer Jul 11, 2024
2b332e1
Use `source.read_u32/u64()`
plafer Jul 12, 2024
9ca910a
Update `MastNodeInfo` docstring
plafer Jul 12, 2024
5c6f287
rename arguments in `encode_u32_pair`
plafer Jul 12, 2024
58df61e
Use basic block offset in deserialization
plafer Jul 12, 2024
1cdc419
`BasicBlockDataDecoder`: use `ByteReader::read_u16/32()` methods
plafer Jul 12, 2024
f45d0c5
`StringTableBuilder`: fix comment
plafer Jul 12, 2024
43cadeb
Remove `StringRef` in favor of `DataOffset`
plafer Jul 12, 2024
7dec428
cleanup `MastNodeType` serialization
plafer Jul 12, 2024
c081b00
derive `Copy` for `MastNodeType`
plafer Jul 12, 2024
c32ef22
`MastNodeType` tests
plafer Jul 12, 2024
c7ee9c8
add `MastNodeType` tests
plafer Jul 12, 2024
f9d2e59
use assert
plafer Jul 12, 2024
781fc73
fix asserts
plafer Jul 12, 2024
fa91716
`ModuleGraph::recompute()` reverse edge caller/callee
plafer Jul 16, 2024
1bd84ec
Implement `Assembler::assemble_library()`
plafer Jul 16, 2024
04e6b0a
Merge branch 'next' into plafer-mast-forest-serialization
plafer Jul 17, 2024
e6ef660
Merge branch 'plafer-mast-forest-serialization' into plafer-mast-libr…
plafer Jul 17, 2024
0a9cfad
changelog
plafer Jul 17, 2024
1c0e0a5
Merge branch 'plafer-mast-forest-serialization' into plafer-mast-libr…
plafer Jul 17, 2024
40cbbb9
fix docs
plafer Jul 17, 2024
727a62a
Merge branch 'plafer-mast-forest-serialization' into plafer-mast-libr…
plafer Jul 17, 2024
f405a2b
Introduce `CompiledFQDN`
plafer Jul 17, 2024
4236a84
Introduce `WrapperModule` to module graph
plafer Jul 17, 2024
c1947c2
split `ModuleGraph::add_module()`
plafer Jul 17, 2024
7878032
fix compile errors from API changes
plafer Jul 17, 2024
b3e337a
fix debug structs
plafer Jul 17, 2024
a4a5e17
fix `Assembler::get_module_exports()`
plafer Jul 18, 2024
b130167
fix `process_graph_worklist`
plafer Jul 18, 2024
1b5a1b5
fix procedure
plafer Jul 18, 2024
9bb9ed5
fix `NameResolver`
plafer Jul 18, 2024
f5699f1
move `CompiledModule`
plafer Jul 18, 2024
8d148ab
`CompiledLibrary::into_compiled_modules`
plafer Jul 18, 2024
2904e1e
`Assembler::add_compiled_library()`
plafer Jul 18, 2024
2adf48d
changelog
plafer Jul 18, 2024
da72cd0
Merge branch 'next' into plafer-mast-library-compilation
plafer Jul 18, 2024
f9d6c15
fix `assemble_library()` signature
plafer Jul 18, 2024
5061941
test `compiled_library()`
plafer Jul 18, 2024
4fba058
nits
plafer Jul 18, 2024
c287f73
register mast roots in `Assembler::add_compiled_library()`
plafer Jul 18, 2024
f5880e7
fix resolve
plafer Jul 18, 2024
b657031
`ModuleGraph::topological_sort_from_root`: only include AST procedures
plafer Jul 18, 2024
c0fb87a
`Assembler::resolve_target()`: look for digest in module graph first
plafer Jul 19, 2024
d3b856c
remove `AssemblyContext::allow_phantom_calls` flag
plafer Jul 19, 2024
096f289
remove TODOP
plafer Jul 19, 2024
f0efb06
`ResolvedProcedure` is no longer `Spanned`
plafer Jul 19, 2024
cca6fe2
improve test
plafer Jul 19, 2024
c83ba0b
remove TODOP
plafer Jul 19, 2024
db5a415
`CompiledProcedure` -> `ProcedureInfo`
plafer Jul 19, 2024
d0c1726
Document `CompiledLibrary`
plafer Jul 19, 2024
f5c8154
Rename `CompiledModule` -> `ModuleInfo`
plafer Jul 19, 2024
3456d9c
Refactor `ModuleInfo`
plafer Jul 19, 2024
7d7af17
`ModuleWrapper` -> `WrappedModule`
plafer Jul 19, 2024
033b741
Document `PendingModuleWrapper`
plafer Jul 19, 2024
7190323
document `Assembler::assemble_library()`
plafer Jul 19, 2024
1ee70da
fix TODOP
plafer Jul 19, 2024
9263fbb
rename
plafer Jul 19, 2024
c0ee866
Merge branch 'next' into plafer-mast-library-compilation
plafer Jul 19, 2024
f12ce36
Merge branch 'next' into plafer-mast-library-compilation
plafer Jul 24, 2024
5b81eec
Merge branch 'next' into plafer-mast-library-compilation
plafer Jul 25, 2024
a784b00
fix test
plafer Jul 25, 2024
98ae7bc
cleanup `ModuleGraph::topological_sort_from_root`
plafer Jul 25, 2024
250e86d
fix CI
plafer Jul 25, 2024
42a991a
re-implement `Spanned` for `ResolvedProcedure`
plafer Jul 25, 2024
8669dfc
reintroduce proper error message
plafer Jul 25, 2024
d444d67
remove unused methods
plafer Jul 25, 2024
48d59a9
Remove all `allow(unused)` methods
plafer Jul 25, 2024
770b25d
Document `unwrap_ast()` call
plafer Jul 26, 2024
53e6555
`NameResolver`: remove use of `unwrap_ast()`
plafer Jul 26, 2024
30ef4c5
Document or remove all calls to `WrappedModule.unwrap_ast()`
plafer Jul 26, 2024
2c43ed4
rename `PendingWrappedModule`
plafer Jul 26, 2024
258aa99
Add `ModuleGraph::add_compiled_modules()`
plafer Jul 26, 2024
49879de
Remove `ModuleGraph::add_module_info()`
plafer Jul 26, 2024
302c4cc
refactor: remove Assembler::compile_program() internal method
bobbinth Jul 28, 2024
fa4b79e
refactor: remove Assembler::assemble_with_options() internal method
bobbinth Jul 28, 2024
021e0cc
feat: implement Assembler:assemble_kernel()
bobbinth Jul 29, 2024
ede435a
chore: remove unused assembly errors
bobbinth Jul 29, 2024
52970ad
feat: add AssemblerError
bobbinth Jul 29, 2024
0f2cfe4
refactor: add ModuleGraph::with_kernel() constructor
bobbinth Jul 29, 2024
58dd399
chore: update changelog
bobbinth Jul 29, 2024
ea032fc
Merge branch 'next' into bobbin-assemble-kernel
bobbinth Jul 29, 2024
3b6db74
chore: fix lint
bobbinth Jul 29, 2024
a3fab87
refactor: introduce KernelLibrary
bobbinth Jul 29, 2024
a5a151d
chore: fix lints
bobbinth Jul 29, 2024
8292606
refactor: remove ModuleIndex param from Module::exported_procedures()
bobbinth Jul 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
- Relaxed the parser to allow one branch of an `if.(true|false)` to be empty
- Added support for immediate values for `u32and`, `u32or`, `u32xor` and `u32not` bitwise instructions (#1362).
- Optimized `std::sys::truncate_stuck` procedure (#1384).
- Updated CI and Makefile to standardise it accross Miden repositories (#1342).
- Updated CI and Makefile to standardize it across Miden repositories (#1342).
- Add serialization/deserialization for `MastForest` (#1370)
- Assembler: add the ability to compile MAST libraries, and to assemble a program using compiled libraries (#1401)
- Updated CI to support `CHANGELOG.md` modification checking and `no changelog` label (#1406)
- Introduced `MastForestError` to enforce `MastForest` node count invariant (#1394)
- Added functions to `MastForest` and `MastForestBuilder` to add and ensure nodes with fewer LOC (#1404, #1412)
- Made `Assembler` single-use (#1409)
- Added functions to `MastForestBuilder` to allow ensuring of nodes with fewer LOC (#1404)
- [BREAKING] Made `Assembler` single-use (#1409).
- Removed `ProcedureCache` from the assembler (#1411).
- Added `Assembler::assemble_library()` (#1413)
- Added functions to `MastForest` and `MastForestBuilder` to add and ensure nodes with fewer LOC (#1404, #1412)
- Added `Assembler::assemble_library()` (#1413).
- Added `Assembler::assemble_kernel()` (#1418).

#### Changed

Expand Down
11 changes: 11 additions & 0 deletions assembly/src/assembler/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,14 @@ impl ModuleIndex {
self.0 as usize
}
}

impl core::ops::Add<ProcedureIndex> for ModuleIndex {
type Output = GlobalProcedureIndex;

fn add(self, rhs: ProcedureIndex) -> Self::Output {
GlobalProcedureIndex {
module: self,
index: rhs,
}
}
}
94 changes: 56 additions & 38 deletions assembly/src/assembler/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::{
ast::{
self, FullyQualifiedProcedureName, InvocationTarget, InvokeKind, ModuleKind, ProcedureIndex,
},
ast::{self, FullyQualifiedProcedureName, InvocationTarget, InvokeKind, ModuleKind},
diagnostics::Report,
library::CompiledLibrary,
library::{CompiledLibrary, KernelLibrary},
sema::SemanticAnalysisError,
AssemblyError, Compile, CompileOptions, Library, LibraryNamespace, LibraryPath, RpoDigest,
Spanned,
Expand Down Expand Up @@ -62,18 +60,13 @@ pub struct Assembler {
// ------------------------------------------------------------------------------------------------
/// Constructors
impl Assembler {
/// Start building an [Assembler]
pub fn new() -> Self {
Self::default()
}

/// Start building an [`Assembler`] with the given [`Kernel`].
pub fn with_kernel(kernel: Kernel) -> Self {
let mut assembler = Self::new();

assembler.module_graph.set_kernel(None, kernel);

assembler
/// Start building an [`Assembler`] with a kernel defined by the provided [KernelLibrary].
pub fn with_kernel(kernel_lib: KernelLibrary) -> Self {
let (kernel, kernel_module, _) = kernel_lib.into_parts();
Self {
module_graph: ModuleGraph::with_kernel(kernel, kernel_module),
..Default::default()
}
}

/// Sets the default behavior of this assembler with regard to warning diagnostics.
Expand Down Expand Up @@ -149,7 +142,8 @@ impl Assembler {
pub fn add_compiled_library(&mut self, library: CompiledLibrary) -> Result<(), Report> {
self.module_graph
.add_compiled_modules(library.into_module_infos())
.map_err(Report::from)
.map_err(Report::from)?;
Ok(())
}

/// Adds the library to provide modules for the compilation.
Expand Down Expand Up @@ -235,7 +229,11 @@ impl Assembler {
// ------------------------------------------------------------------------------------------------
/// Compilation/Assembly
impl Assembler {
/// Assembles a set of modules into a library.
/// Assembles a set of modules into a [CompiledLibrary].
///
/// # Errors
///
/// Returns an error if parsing or compilation of the specified modules fails.
pub fn assemble_library(
mut self,
modules: impl Iterator<Item = impl Compile>,
Expand All @@ -254,29 +252,14 @@ impl Assembler {
let exports = {
let mut exports = Vec::new();

for ast_module_idx in ast_module_indices {
for module_idx in ast_module_indices {
// Note: it is safe to use `unwrap_ast()` here, since all modules looped over are
// AST (we just added them to the module graph)
let ast_module = self.module_graph[ast_module_idx].unwrap_ast().clone();

for (proc_idx, procedure) in ast_module.procedures().enumerate() {
// Only add exports; locals will be added if they are in the call graph rooted
// at those procedures
if !procedure.visibility().is_exported() {
continue;
}

let gid = GlobalProcedureIndex {
module: ast_module_idx,
index: ProcedureIndex::new(proc_idx),
};
let ast_module = self.module_graph[module_idx].unwrap_ast().clone();

self.compile_subgraph(gid, false, &mut mast_forest_builder)?;

exports.push(FullyQualifiedProcedureName::new(
ast_module.path().clone(),
procedure.name().clone(),
));
for (proc_idx, fqn) in ast_module.exported_procedures() {
self.compile_subgraph(module_idx + proc_idx, false, &mut mast_forest_builder)?;
exports.push(fqn);
}
}

Expand All @@ -286,6 +269,41 @@ impl Assembler {
Ok(CompiledLibrary::new(mast_forest_builder.build(), exports)?)
}

/// Assembles the provided module into a [KernelLibrary] intended to be used as a Kernel.
///
/// # Errors
///
/// Returns an error if parsing or compilation of the specified modules fails.
pub fn assemble_kernel(mut self, module: impl Compile) -> Result<KernelLibrary, Report> {
let options = CompileOptions {
kind: ModuleKind::Kernel,
warnings_as_errors: self.warnings_as_errors,
path: Some(LibraryPath::from(LibraryNamespace::Kernel)),
};

let module = module.compile_with_options(options)?;
let module_idx = self.module_graph.add_ast_module(module)?;

self.module_graph.recompute()?;

let mut mast_forest_builder = MastForestBuilder::default();

// Note: it is safe to use `unwrap_ast()` here, since all modules looped over are
// AST (we just added them to the module graph)
let ast_module = self.module_graph[module_idx].unwrap_ast().clone();

let exports = ast_module
.exported_procedures()
.map(|(proc_idx, fqn)| {
self.compile_subgraph(module_idx + proc_idx, false, &mut mast_forest_builder)?;
Ok(fqn)
})
.collect::<Result<Vec<FullyQualifiedProcedureName>, Report>>()?;

let library = CompiledLibrary::new(mast_forest_builder.build(), exports)?;
Ok(library.try_into()?)
}

/// Compiles the provided module into a [`Program`]. The resulting program can be executed on
/// Miden VM.
///
Expand Down
35 changes: 28 additions & 7 deletions assembly/src/assembler/module_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ use crate::{
ProcedureName, ResolvedProcedure,
},
library::{ModuleInfo, ProcedureInfo},
AssemblyError, LibraryPath, RpoDigest, Spanned,
AssemblyError, LibraryNamespace, LibraryPath, RpoDigest, Spanned,
};

// WRAPPER STRUCTS
// ================================================================================================

/// Wraps all supported representations of a procedure in the module graph.
///
/// Currently, there are two supported representations:
Expand Down Expand Up @@ -168,15 +171,15 @@ impl ModuleGraph {
pub fn add_compiled_modules(
&mut self,
module_infos: impl Iterator<Item = ModuleInfo>,
) -> Result<(), AssemblyError> {
) -> Result<Vec<ModuleIndex>, AssemblyError> {
let module_indices: Vec<ModuleIndex> = module_infos
.map(|module| self.add_module(PendingWrappedModule::Info(module)))
.collect::<Result<_, _>>()?;

self.recompute()?;

// Register all procedures as roots
for module_index in module_indices {
for &module_index in module_indices.iter() {
for (proc_index, proc) in self[module_index].unwrap_info().clone().procedure_infos() {
let gid = GlobalProcedureIndex {
module: module_index,
Expand All @@ -187,7 +190,7 @@ impl ModuleGraph {
}
}

Ok(())
Ok(module_indices)
}

/// Add `module` to the graph.
Expand Down Expand Up @@ -238,9 +241,27 @@ impl ModuleGraph {
// ------------------------------------------------------------------------------------------------
/// Kernels
impl ModuleGraph {
pub(super) fn set_kernel(&mut self, kernel_index: Option<ModuleIndex>, kernel: Kernel) {
self.kernel_index = kernel_index;
self.kernel = kernel;
/// Returns a new [ModuleGraph] instantiated from the provided kernel and kernel info module.
///
/// Note: it is assumed that kernel and kernel_module are consistent, but this is not checked.
///
/// TODO: consider passing `KerneLibrary` into this constructor as a parameter instead.
pub(super) fn with_kernel(kernel: Kernel, kernel_module: ModuleInfo) -> Self {
assert!(!kernel.is_empty());
assert_eq!(kernel_module.path(), &LibraryPath::from(LibraryNamespace::Kernel));

// add kernel module to the graph
// TODO: simplify this to avoid using Self::add_compiled_modules()
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
let mut graph = Self::default();
let module_indexes = graph
.add_compiled_modules([kernel_module].into_iter())
.expect("failed to add kernel module to the module graph");
assert_eq!(module_indexes[0], ModuleIndex::new(0), "kernel should be the first module");

graph.kernel_index = Some(module_indexes[0]);
graph.kernel = kernel;

graph
}

pub fn kernel(&self) -> &Kernel {
Expand Down
8 changes: 4 additions & 4 deletions assembly/src/assembler/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn nested_blocks() {
}
}

let assembler = Assembler::new().with_library(&DummyLibrary::default()).unwrap();
let assembler = Assembler::default().with_library(&DummyLibrary::default()).unwrap();

// The expected `MastForest` for the program (that we will build by hand)
let mut expected_mast_forest_builder = MastForestBuilder::default();
Expand Down Expand Up @@ -200,7 +200,7 @@ fn nested_blocks() {
/// forest.
#[test]
fn duplicate_procedure() {
let assembler = Assembler::new();
let assembler = Assembler::default();

let program_source = r#"
proc.foo
Expand All @@ -227,7 +227,7 @@ fn duplicate_procedure() {
/// Ensures that equal MAST nodes don't get added twice to a MAST forest
#[test]
fn duplicate_nodes() {
let assembler = Assembler::new();
let assembler = Assembler::default();

let program_source = r#"
begin
Expand Down Expand Up @@ -317,7 +317,7 @@ fn explicit_fully_qualified_procedure_references() {
}
}

let assembler = Assembler::new().with_library(&DummyLibrary::default()).unwrap();
let assembler = Assembler::default().with_library(&DummyLibrary::default()).unwrap();

let program = r#"
begin
Expand Down
25 changes: 24 additions & 1 deletion assembly/src/ast/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use alloc::{
};
use core::fmt;

use super::{Export, Import, LocalNameResolver, ProcedureIndex, ProcedureName, ResolvedProcedure};
use super::{
Export, FullyQualifiedProcedureName, Import, LocalNameResolver, ProcedureIndex, ProcedureName,
ResolvedProcedure,
};
use crate::{
ast::{AliasTarget, AstSerdeOptions, Ident},
diagnostics::{Report, SourceFile},
Expand Down Expand Up @@ -365,6 +368,26 @@ impl Module {
self.procedures.iter_mut()
}

/// Returns procedures exported from this module.
///
/// Each exported procedure is represented by its local procedure index and a fully qualified
/// name.
pub fn exported_procedures(
&self,
) -> impl Iterator<Item = (ProcedureIndex, FullyQualifiedProcedureName)> + '_ {
self.procedures.iter().enumerate().filter_map(|(proc_idx, p)| {
// skip un-exported procedures
if !p.visibility().is_exported() {
return None;
}

let proc_idx = ProcedureIndex::new(proc_idx);
let fqn = FullyQualifiedProcedureName::new(self.path().clone(), p.name().clone());

Some((proc_idx, fqn))
})
}

/// Get an iterator over the imports declared in this module.
///
/// See [Import] for details on what information is available for imports.
Expand Down
Loading
Loading