forked from libre-chip/fayalite
		
	WIP implementing simulator
This commit is contained in:
		
							parent
							
								
									6f904148c4
								
							
						
					
					
						commit
						479d59b287
					
				
					 3 changed files with 1104 additions and 248 deletions
				
			
		|  | @ -313,7 +313,7 @@ impl TargetChild { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, PartialEq, Eq, Hash)] | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | ||||||
| pub enum Target { | pub enum Target { | ||||||
|     Base(Interned<TargetBase>), |     Base(Interned<TargetBase>), | ||||||
|     Child(TargetChild), |     Child(TargetChild), | ||||||
|  |  | ||||||
|  | @ -1,28 +1,32 @@ | ||||||
| //! Fayalite Simulation
 | //! Fayalite Simulation
 | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     bundle::{Bundle, BundleType}, |     bundle::{Bundle, BundleField, BundleType}, | ||||||
|     enum_::Enum, |     enum_::Enum, | ||||||
|     expr::Expr, |     expr::{ | ||||||
|     int::Bool, |         target::{ | ||||||
|     intern::{Intern, Interned}, |             Target, TargetBase, TargetPathArrayElement, TargetPathBundleField, TargetPathElement, | ||||||
|     module::{ |         }, | ||||||
|         Block, Module, ModuleBody, NormalModuleBody, Stmt, StmtConnect, StmtFormal, StmtIf, |         Expr, | ||||||
|         StmtMatch, |     }, | ||||||
|  |     int::Bool, | ||||||
|  |     intern::{Intern, Interned, Memoize}, | ||||||
|  |     module::{ | ||||||
|  |         AnnotatedModuleIO, Block, Instance, Module, ModuleBody, NormalModuleBody, Stmt, | ||||||
|  |         StmtConnect, StmtDeclaration, StmtFormal, StmtIf, StmtInstance, StmtMatch, | ||||||
|  |     }, | ||||||
|  |     sim::interpreter::{ | ||||||
|  |         Insn, Insns, InsnsBuilding, InsnsBuildingDone, SlotDebugData, StatePartLayout, TypeIndex, | ||||||
|  |         TypeIndexRange, TypeLayout, | ||||||
|     }, |     }, | ||||||
|     sim::interpreter::{Insn, Insns, InsnsBuilding}, |  | ||||||
|     source_location::SourceLocation, |     source_location::SourceLocation, | ||||||
|  |     ty::CanonicalType, | ||||||
| }; | }; | ||||||
| use hashbrown::HashMap; | use hashbrown::HashMap; | ||||||
| use std::{cell::RefCell, rc::Rc}; | use std::fmt; | ||||||
| 
 | 
 | ||||||
| mod interpreter; | mod interpreter; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] |  | ||||||
| struct CompilingModule { |  | ||||||
|     compiled_module: Option<CompiledModule>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||||||
| enum CondStack { | enum CondStack { | ||||||
|     Always, |     Always, | ||||||
|  | @ -44,32 +48,279 @@ enum CondStack { | ||||||
|     }, |     }, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(PartialEq, Eq, Hash, Clone, Copy)] | ||||||
|  | enum InstantiatedModule { | ||||||
|  |     Base(Interned<Module<Bundle>>), | ||||||
|  |     Child { | ||||||
|  |         parent: Interned<InstantiatedModule>, | ||||||
|  |         instance: Interned<Instance<Bundle>>, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl InstantiatedModule { | ||||||
|  |     fn leaf_module(self) -> Interned<Module<Bundle>> { | ||||||
|  |         match self { | ||||||
|  |             InstantiatedModule::Base(base) => base, | ||||||
|  |             InstantiatedModule::Child { instance, .. } => instance.instantiated(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     fn write_path(self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         match self { | ||||||
|  |             InstantiatedModule::Base(base) => fmt::Debug::fmt(&base.name_id(), f), | ||||||
|  |             InstantiatedModule::Child { parent, instance } => { | ||||||
|  |                 parent.write_path(f)?; | ||||||
|  |                 write!(f, ".{}", instance.name_id()) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl fmt::Debug for InstantiatedModule { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         write!(f, "InstantiatedModule(")?; | ||||||
|  |         self.write_path(f)?; | ||||||
|  |         write!(f, ": {})", self.leaf_module().name_id()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||||||
|  | struct TargetInInstantiatedModule { | ||||||
|  |     instantiated_module: InstantiatedModule, | ||||||
|  |     target: Target, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||||||
|  | struct CompiledBundleField { | ||||||
|  |     offset: TypeIndex, | ||||||
|  |     ty: CompiledTypeLayout, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||||||
|  | enum CompiledTypeLayoutBody { | ||||||
|  |     Scalar, | ||||||
|  |     Array { | ||||||
|  |         /// debug names are ignored, use parent's layout instead
 | ||||||
|  |         element: Interned<CompiledTypeLayout>, | ||||||
|  |     }, | ||||||
|  |     Bundle { | ||||||
|  |         /// debug names are ignored, use parent's layout instead
 | ||||||
|  |         fields: Interned<[CompiledBundleField]>, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||||||
|  | struct CompiledTypeLayout { | ||||||
|  |     ty: CanonicalType, | ||||||
|  |     layout: TypeLayout<InsnsBuildingDone>, | ||||||
|  |     body: CompiledTypeLayoutBody, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl CompiledTypeLayout { | ||||||
|  |     fn with_prefixed_debug_names(self, prefix: &str) -> Self { | ||||||
|  |         let Self { ty, layout, body } = self; | ||||||
|  |         Self { | ||||||
|  |             ty, | ||||||
|  |             layout: layout.with_prefixed_debug_names(prefix), | ||||||
|  |             body, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     fn get(ty: CanonicalType) -> Self { | ||||||
|  |         #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||||||
|  |         struct MyMemoize; | ||||||
|  |         impl Memoize for MyMemoize { | ||||||
|  |             type Input = CanonicalType; | ||||||
|  |             type InputOwned = CanonicalType; | ||||||
|  |             type Output = CompiledTypeLayout; | ||||||
|  | 
 | ||||||
|  |             fn inner(self, input: &Self::Input) -> Self::Output { | ||||||
|  |                 match input { | ||||||
|  |                     CanonicalType::UInt(_) | ||||||
|  |                     | CanonicalType::SInt(_) | ||||||
|  |                     | CanonicalType::Bool(_) | ||||||
|  |                     | CanonicalType::Enum(_) | ||||||
|  |                     | CanonicalType::AsyncReset(_) | ||||||
|  |                     | CanonicalType::SyncReset(_) | ||||||
|  |                     | CanonicalType::Reset(_) | ||||||
|  |                     | CanonicalType::Clock(_) => { | ||||||
|  |                         let mut layout = TypeLayout::empty(); | ||||||
|  |                         let debug_data = SlotDebugData { name: "".intern() }; | ||||||
|  |                         if input.bit_width() > interpreter::SmallUInt::BITS as usize { | ||||||
|  |                             layout.big_slots = StatePartLayout::scalar(debug_data); | ||||||
|  |                         } else { | ||||||
|  |                             layout.small_slots = StatePartLayout::scalar(debug_data); | ||||||
|  |                         }; | ||||||
|  |                         CompiledTypeLayout { | ||||||
|  |                             ty: *input, | ||||||
|  |                             layout: layout.into(), | ||||||
|  |                             body: CompiledTypeLayoutBody::Scalar, | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     CanonicalType::Array(array) => { | ||||||
|  |                         let mut layout = TypeLayout::empty(); | ||||||
|  |                         let element = CompiledTypeLayout::get(array.element()).intern_sized(); | ||||||
|  |                         for index in 0..array.len() { | ||||||
|  |                             layout.allocate( | ||||||
|  |                                 &element | ||||||
|  |                                     .layout | ||||||
|  |                                     .with_prefixed_debug_names(&format!("[{index}]")), | ||||||
|  |                             ); | ||||||
|  |                         } | ||||||
|  |                         CompiledTypeLayout { | ||||||
|  |                             ty: *input, | ||||||
|  |                             layout: layout.into(), | ||||||
|  |                             body: CompiledTypeLayoutBody::Array { element }, | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     CanonicalType::Bundle(bundle) => { | ||||||
|  |                         let mut layout = TypeLayout::empty(); | ||||||
|  |                         let fields = bundle | ||||||
|  |                             .fields() | ||||||
|  |                             .iter() | ||||||
|  |                             .map( | ||||||
|  |                                 |BundleField { | ||||||
|  |                                      name, | ||||||
|  |                                      flipped: _, | ||||||
|  |                                      ty, | ||||||
|  |                                  }| { | ||||||
|  |                                     let ty = CompiledTypeLayout::get(*ty); | ||||||
|  |                                     let offset = layout | ||||||
|  |                                         .allocate( | ||||||
|  |                                             &ty.layout | ||||||
|  |                                                 .with_prefixed_debug_names(&format!(".{name}")), | ||||||
|  |                                         ) | ||||||
|  |                                         .start(); | ||||||
|  |                                     CompiledBundleField { offset, ty } | ||||||
|  |                                 }, | ||||||
|  |                             ) | ||||||
|  |                             .collect(); | ||||||
|  |                         CompiledTypeLayout { | ||||||
|  |                             ty: *input, | ||||||
|  |                             layout: layout.into(), | ||||||
|  |                             body: CompiledTypeLayoutBody::Bundle { fields }, | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         MyMemoize.get_owned(ty) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||||||
|  | struct CompiledValue { | ||||||
|  |     layout: CompiledTypeLayout, | ||||||
|  |     range: TypeIndexRange, | ||||||
|  |     write: Option<(CompiledTypeLayout, TypeIndexRange)>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl CompiledValue { | ||||||
|  |     fn map( | ||||||
|  |         self, | ||||||
|  |         mut f: impl FnMut(CompiledTypeLayout, TypeIndexRange) -> (CompiledTypeLayout, TypeIndexRange), | ||||||
|  |     ) -> Self { | ||||||
|  |         let (layout, range) = f(self.layout, self.range); | ||||||
|  |         Self { | ||||||
|  |             layout, | ||||||
|  |             range, | ||||||
|  |             write: self.write.map(|(layout, range)| f(layout, range)), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Compiler { | pub struct Compiler { | ||||||
|     insns: Insns<InsnsBuilding>, |     insns: Insns<InsnsBuilding>, | ||||||
|     modules: HashMap<Interned<Module<Bundle>>, Rc<RefCell<CompilingModule>>>, |     base_module: Interned<Module<Bundle>>, | ||||||
|     module_queue: Vec<Interned<Module<Bundle>>>, |     modules: HashMap<InstantiatedModule, CompiledModule>, | ||||||
|  |     compiled_values: HashMap<TargetInInstantiatedModule, CompiledValue>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Compiler { | impl Compiler { | ||||||
|     pub fn new() -> Self { |     pub fn new(base_module: Interned<Module<Bundle>>) -> Self { | ||||||
|         Self { |         Self { | ||||||
|             insns: Insns::new(), |             insns: Insns::new(), | ||||||
|  |             base_module, | ||||||
|             modules: HashMap::new(), |             modules: HashMap::new(), | ||||||
|             module_queue: Vec::new(), |             compiled_values: HashMap::new(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     pub fn add_module(&mut self, module: Interned<Module<Bundle>>) { |     fn compile_value(&mut self, target: TargetInInstantiatedModule) -> CompiledValue { | ||||||
|         self.modules.entry(module).or_insert_with(|| { |         if let Some(&retval) = self.compiled_values.get(&target) { | ||||||
|             self.module_queue.push(module); |             return retval; | ||||||
|             Rc::new(RefCell::new(CompilingModule { |         } | ||||||
|                 compiled_module: None, |         match target.target { | ||||||
|             })) |             Target::Base(base) => { | ||||||
|         }); |                 let unprefixed_layout = CompiledTypeLayout::get(base.canonical_ty()); | ||||||
|  |                 let layout = unprefixed_layout.with_prefixed_debug_names(&format!( | ||||||
|  |                     "{:?}.{:?}", | ||||||
|  |                     target.instantiated_module, | ||||||
|  |                     base.target_name() | ||||||
|  |                 )); | ||||||
|  |                 let range = self.insns.allocate_variable(&layout.layout); | ||||||
|  |                 let write = match *base { | ||||||
|  |                     TargetBase::ModuleIO(_) | ||||||
|  |                     | TargetBase::MemPort(_) | ||||||
|  |                     | TargetBase::Wire(_) | ||||||
|  |                     | TargetBase::Instance(_) => None, | ||||||
|  |                     TargetBase::Reg(_) => { | ||||||
|  |                         let write_layout = unprefixed_layout.with_prefixed_debug_names(&format!( | ||||||
|  |                             "{:?}.{:?}$next", | ||||||
|  |                             target.instantiated_module, | ||||||
|  |                             base.target_name() | ||||||
|  |                         )); | ||||||
|  |                         Some(( | ||||||
|  |                             write_layout, | ||||||
|  |                             self.insns.allocate_variable(&write_layout.layout), | ||||||
|  |                         )) | ||||||
|  |                     } | ||||||
|  |                 }; | ||||||
|  |                 CompiledValue { | ||||||
|  |                     range, | ||||||
|  |                     layout, | ||||||
|  |                     write, | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             Target::Child(target_child) => { | ||||||
|  |                 let parent = self.compile_value(TargetInInstantiatedModule { | ||||||
|  |                     instantiated_module: target.instantiated_module, | ||||||
|  |                     target: *target_child.parent(), | ||||||
|  |                 }); | ||||||
|  |                 match *target_child.path_element() { | ||||||
|  |                     TargetPathElement::BundleField(TargetPathBundleField { name }) => { | ||||||
|  |                         parent.map(|layout, range| { | ||||||
|  |                             let CompiledTypeLayout { | ||||||
|  |                                 ty: CanonicalType::Bundle(bundle), | ||||||
|  |                                 layout: _, | ||||||
|  |                                 body: CompiledTypeLayoutBody::Bundle { fields }, | ||||||
|  |                             } = layout | ||||||
|  |                             else { | ||||||
|  |                                 unreachable!(); | ||||||
|  |                             }; | ||||||
|  |                             let field_index = bundle.name_indexes()[&name]; | ||||||
|  |                             ( | ||||||
|  |                                 fields[field_index].ty, | ||||||
|  |                                 range.slice(TypeIndexRange::new( | ||||||
|  |                                     fields[field_index].offset, | ||||||
|  |                                     fields[field_index].ty.layout.len(), | ||||||
|  |                                 )), | ||||||
|  |                             ) | ||||||
|  |                         }) | ||||||
|  |                     } | ||||||
|  |                     TargetPathElement::ArrayElement(TargetPathArrayElement { index }) => parent | ||||||
|  |                         .map(|layout, range| { | ||||||
|  |                             let CompiledTypeLayoutBody::Array { element } = layout.body else { | ||||||
|  |                                 unreachable!(); | ||||||
|  |                             }; | ||||||
|  |                             (*element, range.index_array(element.layout.len(), index)) | ||||||
|  |                         }), | ||||||
|  |                     TargetPathElement::DynArrayElement(_) => unreachable!(), | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     fn compile_block( |     fn compile_block( | ||||||
|         &mut self, |         &mut self, | ||||||
|         module: Interned<Module<Bundle>>, |         parent_module: Interned<InstantiatedModule>, | ||||||
|         block: Block, |         block: Block, | ||||||
|         cond_stack: Interned<CondStack>, |         cond_stack: Interned<CondStack>, | ||||||
|     ) { |     ) { | ||||||
|  | @ -98,7 +349,7 @@ impl Compiler { | ||||||
|                     blocks: [then_block, else_block], |                     blocks: [then_block, else_block], | ||||||
|                 }) => { |                 }) => { | ||||||
|                     self.compile_block( |                     self.compile_block( | ||||||
|                         module, |                         parent_module, | ||||||
|                         then_block, |                         then_block, | ||||||
|                         CondStack::IfTrue { |                         CondStack::IfTrue { | ||||||
|                             parent: cond_stack, |                             parent: cond_stack, | ||||||
|  | @ -108,7 +359,7 @@ impl Compiler { | ||||||
|                         .intern_sized(), |                         .intern_sized(), | ||||||
|                     ); |                     ); | ||||||
|                     self.compile_block( |                     self.compile_block( | ||||||
|                         module, |                         parent_module, | ||||||
|                         else_block, |                         else_block, | ||||||
|                         CondStack::IfFalse { |                         CondStack::IfFalse { | ||||||
|                             parent: cond_stack, |                             parent: cond_stack, | ||||||
|  | @ -125,7 +376,7 @@ impl Compiler { | ||||||
|                 }) => { |                 }) => { | ||||||
|                     for (variant_index, block) in blocks.into_iter().enumerate() { |                     for (variant_index, block) in blocks.into_iter().enumerate() { | ||||||
|                         self.compile_block( |                         self.compile_block( | ||||||
|                             module, |                             parent_module, | ||||||
|                             block, |                             block, | ||||||
|                             CondStack::MatchArm { |                             CondStack::MatchArm { | ||||||
|                                 parent: cond_stack, |                                 parent: cond_stack, | ||||||
|  | @ -137,67 +388,79 @@ impl Compiler { | ||||||
|                         ); |                         ); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Stmt::Declaration(stmt_declaration) => todo!(), |                 Stmt::Declaration(declaration) => match declaration { | ||||||
|  |                     StmtDeclaration::Wire(wire) => todo!(), | ||||||
|  |                     StmtDeclaration::Reg(reg) => todo!(), | ||||||
|  |                     StmtDeclaration::Instance(StmtInstance { | ||||||
|  |                         annotations, | ||||||
|  |                         instance, | ||||||
|  |                     }) => { | ||||||
|  |                         self.compile_module( | ||||||
|  |                             InstantiatedModule::Child { | ||||||
|  |                                 parent: parent_module, | ||||||
|  |                                 instance: instance.intern_sized(), | ||||||
|  |                             } | ||||||
|  |                             .intern_sized(), | ||||||
|  |                         ); | ||||||
|  |                         todo!() | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     fn compile_module(&mut self, module: Interned<Module<Bundle>>) -> CompiledModule { |     fn compile_module(&mut self, module: Interned<InstantiatedModule>) -> &CompiledModule { | ||||||
|         let step_entry_pc = self.insns.next_insn_pc(); |         let module_io = module | ||||||
|         match module.body() { |             .leaf_module() | ||||||
|  |             .module_io() | ||||||
|  |             .iter() | ||||||
|  |             .map( | ||||||
|  |                 |&AnnotatedModuleIO { | ||||||
|  |                      annotations: _, | ||||||
|  |                      module_io, | ||||||
|  |                  }| { | ||||||
|  |                     self.compile_value(TargetInInstantiatedModule { | ||||||
|  |                         instantiated_module: *module, | ||||||
|  |                         target: Target::from(module_io), | ||||||
|  |                     }) | ||||||
|  |                 }, | ||||||
|  |             ) | ||||||
|  |             .collect(); | ||||||
|  |         match module.leaf_module().body() { | ||||||
|             ModuleBody::Normal(NormalModuleBody { body }) => { |             ModuleBody::Normal(NormalModuleBody { body }) => { | ||||||
|                 self.compile_block(module, body, CondStack::Always.intern_sized()) |                 self.compile_block(module, body, CondStack::Always.intern_sized()) | ||||||
|             } |             } | ||||||
|             ModuleBody::Extern(_extern_module_body) => { |             ModuleBody::Extern(_extern_module_body) => { | ||||||
|                 todo!("simulating extern module: {}", module.name_id()); |                 todo!("simulating extern module: {:?}", module); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         self.insns.push(Insn::Return, module.source_location()); |         let hashbrown::hash_map::Entry::Vacant(entry) = self.modules.entry(*module) else { | ||||||
|         CompiledModule { step_entry_pc } |             unreachable!("compiled same instantiated module twice"); | ||||||
|  |         }; | ||||||
|  |         entry.insert(CompiledModule { module_io }) | ||||||
|     } |     } | ||||||
|     pub fn run(mut self) -> Compiled { |     pub fn run(mut self) -> Compiled { | ||||||
|         while let Some(module) = self.module_queue.pop() { |         self.compile_module(InstantiatedModule::Base(self.base_module).intern_sized()); | ||||||
|             let compiling_module = self.modules[&module].clone(); |  | ||||||
|             let mut compiling_module = compiling_module.borrow_mut(); |  | ||||||
|             let CompilingModule { compiled_module } = &mut *compiling_module; |  | ||||||
|             assert!(compiled_module.is_none()); |  | ||||||
|             *compiled_module = Some(self.compile_module(module)); |  | ||||||
|         } |  | ||||||
|         Compiled { |         Compiled { | ||||||
|             insns: Insns::from(self.insns).intern_sized(), |             insns: Insns::from(self.insns).intern_sized(), | ||||||
|             modules: self |             modules: self.modules, | ||||||
|                 .modules |  | ||||||
|                 .into_iter() |  | ||||||
|                 .map(|(module, compiling_module)| { |  | ||||||
|                     ( |  | ||||||
|                         module, |  | ||||||
|                         Rc::into_inner(compiling_module) |  | ||||||
|                             .expect("only reference is Compiler::modules") |  | ||||||
|                             .into_inner() |  | ||||||
|                             .compiled_module |  | ||||||
|                             .expect("module is compiled by Compiler::run"), |  | ||||||
|                     ) |  | ||||||
|                 }) |  | ||||||
|                 .collect(), |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| struct CompiledModule { | struct CompiledModule { | ||||||
|     step_entry_pc: usize, |     module_io: Interned<[CompiledValue]>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Compiled { | pub struct Compiled { | ||||||
|     insns: Interned<Insns>, |     insns: Interned<Insns<InsnsBuildingDone>>, | ||||||
|     modules: HashMap<Interned<Module<Bundle>>, CompiledModule>, |     modules: HashMap<InstantiatedModule, CompiledModule>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Compiled { | impl Compiled { | ||||||
|     pub fn new<T: BundleType>(module: Module<T>) -> Self { |     pub fn new<T: BundleType>(module: Module<T>) -> Self { | ||||||
|         let mut compiler = Compiler::new(); |         Compiler::new(module.canonical().intern()).run() | ||||||
|         compiler.add_module(module.canonical().intern()); |  | ||||||
|         compiler.run() |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue