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

Sketch the new frontend component translator (no inlining) producing HIR2-style IR structure #367

Draft
wants to merge 18 commits into
base: next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
e0efac7
test: sketch new frontend translator (no inlining) producing HIR2
greenhat Jan 2, 2025
6510b26
refactor: move module id creation out of the loop
greenhat Jan 3, 2025
209d696
feature: function signatures in the `CanonLower` synthetic modules (i…
greenhat Jan 3, 2025
ffd5de8
feature: add function signatures in the export interface
greenhat Jan 3, 2025
bc484b2
feature: translate Wasm component with multiple export interfaces to …
greenhat Jan 10, 2025
2f036b1
feature: add inner_function for synthetic lower/lift functions
greenhat Jan 10, 2025
ebb7abb
feature: introduce `hir2_sketch::World` and create a component with an
greenhat Jan 13, 2025
08c80ee
refactor: remove InstantiatedComponent
greenhat Jan 13, 2025
40a936f
refactor: store `TypesRef` instead of `ParsedComponent` in
greenhat Jan 13, 2025
0ca3e42
refactor: remove unused code
greenhat Jan 13, 2025
03dbb7b
refactor: use qualified Severity in unsupported_diag! macro
greenhat Jan 13, 2025
4455db7
refactor: gracefully handle not supported Wasm component shapes
greenhat Jan 13, 2025
7cf7ba8
refactor: extract most LocalInitializer variant translation
greenhat Jan 13, 2025
96afbe1
chore: fix the build after the rebase
greenhat Jan 14, 2025
01a4362
draft: start hir2 Component building
greenhat Jan 17, 2025
abc5f78
fix: improve location tracking of aliasing violations
bitwalker Jan 17, 2025
2087ada
fix: restructure component builder creation to avoid aliasing violation
bitwalker Jan 17, 2025
769c714
fix: update expect test for hir2 integration
bitwalker Jan 17, 2025
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ log.workspace = true
hashbrown.workspace = true
miden-core.workspace = true
midenc-hir.workspace = true
midenc-hir2.workspace = true
midenc-hir-type.workspace = true
midenc-session.workspace = true
rustc-hash.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion frontend-wasm/src/code_translator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

use midenc_hir::{
cranelift_entity::packed_option::ReservedValue,
diagnostics::{DiagnosticsHandler, IntoDiagnostic, Report, Severity, SourceSpan},
diagnostics::{DiagnosticsHandler, IntoDiagnostic, Report, SourceSpan},
Block, FieldElement, Immediate, Inst, InstBuilder, Type,
Type::*,
Value,
Expand Down
27 changes: 25 additions & 2 deletions frontend-wasm/src/component/build_ir.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::rc::Rc;

use midenc_hir::diagnostics::Report;
use midenc_hir2::{dialects::builtin::BuiltinDialect, Context};
use midenc_session::Session;

use super::{
inline, translator::ComponentTranslator, ComponentTypesBuilder, LinearComponentTranslation,
ParsedRootComponent,
inline, translator::ComponentTranslator, translator2::ComponentTranslator2,
ComponentTypesBuilder, LinearComponentTranslation, ParsedRootComponent,
};
use crate::{
component::ComponentParser, error::WasmResult, supported_component_model_features,
Expand Down Expand Up @@ -61,3 +64,23 @@ fn inline(
.map_err(Report::msg)?;
Ok(component_dfg.finish())
}

/// Translate a Wasm component binary into Miden IR component
pub fn translate_component2(
wasm: &[u8],
config: &WasmTranslationConfig,
session: Rc<Session>,
) -> WasmResult<midenc_hir2::dialects::builtin::ComponentRef> {
let (mut component_types_builder, parsed_root_component) = parse(config, wasm, &session)?;
let context = Rc::new(Context::new(session));
let dialect = context.get_or_register_dialect::<BuiltinDialect>();
dialect.expect_registered_name::<midenc_hir2::dialects::builtin::Component>();
// context.get_or_register_dialect::<HirDialect>();
let translator = ComponentTranslator2::new(
&parsed_root_component.static_modules,
&parsed_root_component.static_components,
config,
context,
);
translator.translate2(&parsed_root_component.root_component, &mut component_types_builder)
}
16 changes: 10 additions & 6 deletions frontend-wasm/src/component/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use super::{
LocalCanonicalOptions, ParsedComponent, StringEncoding,
};
use crate::{
component::{dfg, LocalInitializer},
component::{dfg, CanonLift, CanonLower, ComponentInstantiation, LocalInitializer},
module::{module_env::ParsedModule, types::*, ModuleImport},
};

Expand Down Expand Up @@ -501,12 +501,12 @@ impl<'a> Inliner<'a> {
// Lowering a component function to a core wasm function. Here
// various metadata is recorded and then the final component gets an
// initializer recording the lowering.
Lower {
Lower(CanonLower {
func,
options,
canonical_abi,
lower_ty,
} => {
}) => {
let lower_ty =
types.convert_component_func_type(frame.translation.types_ref(), *lower_ty)?;
let options_lower = self.adapter_options(frame, options);
Expand Down Expand Up @@ -580,7 +580,7 @@ impl<'a> Inliner<'a> {
// Lifting a core wasm function is relatively easy for now in that
// some metadata about the lifting is simply recorded. This'll get
// plumbed through to exports or a fused adapter later on.
Lift(ty, func, options) => {
Lift(CanonLift { ty, func, options }) => {
let ty = types.convert_component_func_type(frame.translation.types_ref(), *ty)?;
let options = self.adapter_options(frame, options);
frame.component_funcs.push(ComponentFuncDef::Lifted {
Expand Down Expand Up @@ -732,7 +732,11 @@ impl<'a> Inliner<'a> {
// of this entire module, so the "easy" step here is to simply
// create a new inliner frame and return it to get pushed onto the
// stack.
ComponentInstantiate(component, args, ty) => {
ComponentInstantiate(ComponentInstantiation {
component,
args,
ty,
}) => {
let component: &ComponentDef<'a> = &frame.components[*component];
let index = RuntimeComponentInstanceIndex::from_u32(
self.result.num_runtime_component_instances,
Expand Down Expand Up @@ -826,7 +830,7 @@ impl<'a> Inliner<'a> {
frame.components.push(frame.closed_over_component(idx));
}

Export(item) => match item {
Export(_, item) => match item {
ComponentItem::Func(i) => {
frame.component_funcs.push(frame.component_funcs[*i].clone());
}
Expand Down
1 change: 1 addition & 0 deletions frontend-wasm/src/component/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod info;
mod inline;
mod parser;
mod translator;
mod translator2;
mod types;

pub use self::{info::*, parser::*, types::*};
73 changes: 50 additions & 23 deletions frontend-wasm/src/component/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ use std::mem;

use indexmap::IndexMap;
use midenc_hir::{
cranelift_entity::PrimaryMap,
diagnostics::{IntoDiagnostic, Severity},
FxBuildHasher, FxHashMap,
cranelift_entity::PrimaryMap, diagnostics::IntoDiagnostic, FxBuildHasher, FxHashMap,
};
use midenc_session::Session;
use wasmparser::{
Expand Down Expand Up @@ -183,23 +181,42 @@ pub struct ParsedComponent<'data> {
pub types: Option<Types>,
}

#[derive(Debug, Clone)]
pub struct CanonLower {
pub func: ComponentFuncIndex,
pub lower_ty: ComponentFuncTypeId,
pub canonical_abi: SignatureIndex,
pub options: LocalCanonicalOptions,
}

#[derive(Debug, Clone)]
pub struct CanonLift {
pub ty: ComponentFuncTypeId,
pub func: FuncIndex,
pub options: LocalCanonicalOptions,
}

#[derive(Debug, Clone)]
// component instances
pub struct ComponentInstantiation<'data> {
pub component: ComponentIndex,
pub args: FxHashMap<&'data str, ComponentItem>,
pub ty: ComponentInstanceTypeId,
}

// NB: the type information contained in `LocalInitializer` should always point
// to `wasmparser`'s type information, not ours. Component types cannot be
// fully determined due to resources until instantiations are known which is
// tracked during the inlining phase. This means that all type information below
// is straight from `wasmparser`'s passes.
#[derive(Debug)]
pub enum LocalInitializer<'data> {
// imports
Import(ComponentImportName<'data>, ComponentEntityType),

// canonical function sections
Lower {
func: ComponentFuncIndex,
lower_ty: ComponentFuncTypeId,
canonical_abi: SignatureIndex,
options: LocalCanonicalOptions,
},
Lift(ComponentFuncTypeId, FuncIndex, LocalCanonicalOptions),
Lower(CanonLower),
Lift(CanonLift),

// resources
Resource(AliasableResourceId, WasmType, Option<FuncIndex>),
Expand All @@ -217,12 +234,7 @@ pub enum LocalInitializer<'data> {
// components
ComponentStatic(StaticComponentIndex, ClosedOverVars),

// component instances
ComponentInstantiate(
ComponentIndex,
FxHashMap<&'data str, ComponentItem>,
ComponentInstanceTypeId,
),
ComponentInstantiate(ComponentInstantiation<'data>),
ComponentSynthetic(FxHashMap<&'data str, ComponentItem>),

// alias section
Expand All @@ -235,13 +247,13 @@ pub enum LocalInitializer<'data> {
AliasComponent(ClosedOverComponent),

// export section
Export(ComponentItem),
Export(&'data str, ComponentItem),
}

/// The "closure environment" of components themselves.
///
/// For more information see `LexicalScope`.
#[derive(Default)]
#[derive(Default, Debug)]
pub struct ClosedOverVars {
pub components: PrimaryMap<ComponentUpvarIndex, ClosedOverComponent>,
pub modules: PrimaryMap<ModuleUpvarIndex, ClosedOverModule>,
Expand All @@ -251,6 +263,7 @@ pub struct ClosedOverVars {
/// a component are being created.
///
/// For more information see `LexicalScope`.
#[derive(Debug)]
pub enum ClosedOverComponent {
/// A closed over component is coming from the local component's index
/// space, meaning a previously defined component is being captured.
Expand All @@ -263,12 +276,14 @@ pub enum ClosedOverComponent {
}

/// Same as `ClosedOverComponent`, but for modules.
#[derive(Debug)]
pub enum ClosedOverModule {
Local(ModuleIndex),
Upvar(ModuleUpvarIndex),
}

/// Representation of canonical ABI options.
#[derive(Debug, Clone)]
pub struct LocalCanonicalOptions {
pub string_encoding: StringEncoding,
pub memory: Option<MemoryIndex>,
Expand Down Expand Up @@ -349,6 +364,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
} => {
self.validator.version(num, encoding, &range).into_diagnostic()?;

// dbg!(&encoding);
match encoding {
Encoding::Component => {}
Encoding::Module => {
Expand Down Expand Up @@ -470,6 +486,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
let import = import.into_diagnostic()?;
let types = self.validator.types(0).unwrap();
let ty = types.component_entity_type_of_import(import.name.0).unwrap();
// dbg!(&import.name, &ty);
self.result.initializers.push(LocalInitializer::Import(import.name, ty));
}
Ok(())
Expand All @@ -494,7 +511,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
let ty = types.component_any_type_at(type_index).unwrap_func();
let func = FuncIndex::from_u32(core_func_index);
let options = canonical_options(&options);
LocalInitializer::Lift(ty, func, options)
LocalInitializer::Lift(CanonLift { ty, func, options })
}
wasmparser::CanonicalFunction::Lower {
func_index,
Expand All @@ -506,12 +523,12 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
let canonical_abi = self.core_func_signature(core_func_index);

core_func_index += 1;
LocalInitializer::Lower {
LocalInitializer::Lower(CanonLower {
func,
options,
canonical_abi,
lower_ty,
}
})
}
wasmparser::CanonicalFunction::ResourceNew { resource } => {
let resource = types.component_any_type_at(resource).unwrap_resource();
Expand All @@ -532,6 +549,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
LocalInitializer::ResourceRep(resource, ty)
}
};
// dbg!(&init);
self.result.initializers.push(init);
}
Ok(())
Expand Down Expand Up @@ -611,6 +629,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
instantiate_module_from_exports(&exports)
}
};
// dbg!(&init);
self.result.initializers.push(init);
}
Ok(())
Expand All @@ -637,6 +656,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
self.instantiate_component_from_exports(&exports)?
}
};
// dbg!(&init);
self.result.initializers.push(init);
index += 1;
}
Expand All @@ -655,10 +675,11 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
self.validator.component_export_section(&s).into_diagnostic()?;
for export in s {
let export = export.into_diagnostic()?;
// dbg!(&export);
let item = self.kind_to_item(export.kind, export.index)?;
let prev = self.result.exports.insert(export.name.0, item);
assert!(prev.is_none());
self.result.initializers.push(LocalInitializer::Export(item));
self.result.initializers.push(LocalInitializer::Export(export.name.0, item));
}
Ok(())
}
Expand Down Expand Up @@ -694,6 +715,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
alias_module_instance_export(kind, instance, name)
}
};
// dbg!(&init);
self.result.initializers.push(init);
}
Ok(())
Expand All @@ -712,7 +734,11 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
args.insert(arg.name, idx);
}

Ok(LocalInitializer::ComponentInstantiate(component, args, ty))
Ok(LocalInitializer::ComponentInstantiate(ComponentInstantiation {
component,
args,
ty,
}))
}

/// Creates a synthetic module from the list of items currently in the
Expand All @@ -727,6 +753,7 @@ impl<'a, 'data> ComponentParser<'a, 'data> {
map.insert(export.name.0, idx);
}

// dbg!(&map);
Ok(LocalInitializer::ComponentSynthetic(map))
}

Expand Down
10 changes: 6 additions & 4 deletions frontend-wasm/src/component/translator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use midenc_hir::{
cranelift_entity::PrimaryMap, diagnostics::Severity, CanonAbiImport, ComponentBuilder,
ComponentExport, FunctionIdent, FunctionType, FxHashMap, Ident, InterfaceFunctionIdent,
InterfaceIdent, MidenAbiImport, Symbol,
cranelift_entity::PrimaryMap, CanonAbiImport, ComponentBuilder, ComponentExport, FunctionIdent,
FunctionType, FxHashMap, Ident, InterfaceFunctionIdent, InterfaceIdent, MidenAbiImport, Symbol,
};
use midenc_hir_type::Abi;
use midenc_session::{DiagnosticsHandler, Session};
Expand Down Expand Up @@ -487,7 +486,10 @@ fn function_id_from_export(exporting_module: &Module, func_idx: FuncIndex) -> Fu
}

/// Convert the given Wasm component function type to the Miden IR lifted function type
fn convert_lifted_func_ty(ty: &TypeFuncIndex, component_types: &ComponentTypes) -> FunctionType {
pub fn convert_lifted_func_ty(
ty: &TypeFuncIndex,
component_types: &ComponentTypes,
) -> FunctionType {
let type_func = component_types[*ty].clone();
let params_types = component_types[type_func.params].clone().types;
let results_types = component_types[type_func.results].clone().types;
Expand Down
Loading
Loading