Skip to content

Commit

Permalink
feature: parse Wasm components
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat committed Jan 9, 2024
1 parent fb8aca3 commit 6cc007e
Show file tree
Hide file tree
Showing 32 changed files with 9,458 additions and 986 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion frontend-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ edition.workspace = true
miden-hir.workspace = true
miden-hir-type.workspace = true
miden-diagnostics.workspace = true

thiserror.workspace = true
smallvec.workspace = true
log.workspace = true
anyhow.workspace = true
wasmparser = "0.118.1"
derive_more = "0.99"
indexmap = "2.1"
gimli = { version = "0.28.0", default-features = false, features = ['read', 'std'] }

[dev-dependencies]
wat = "1.0.69"
Expand Down
56 changes: 33 additions & 23 deletions frontend-wasm/src/code_translator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ use std::collections::{hash_map, HashMap};
use std::u64;

use crate::error::{WasmError, WasmResult};
use crate::module::environ::ModuleInfo;
use crate::module::func_translation_state::ControlStackFrame;
use crate::module::func_translation_state::{ElseData, FuncTranslationState};
use crate::module::func_translation_state::{ControlStackFrame, ElseData, FuncTranslationState};
use crate::module::function_builder_ext::FunctionBuilderExt;
use crate::module::types::{ir_type, BlockType, GlobalIndex, ModuleTypes};
use crate::module::Module;
use crate::ssa::Variable;
use crate::unsupported_diag;
use crate::wasm_types::{BlockType, GlobalIndex};
use miden_diagnostics::{DiagnosticsHandler, SourceSpan};
use miden_hir::cranelift_entity::packed_option::ReservedValue;
use miden_hir::Type::*;
Expand All @@ -42,12 +41,13 @@ pub fn translate_operator(
op: &Operator,
builder: &mut FunctionBuilderExt,
state: &mut FuncTranslationState,
mod_info: &ModuleInfo,
mod_info: &Module,
mod_types: &ModuleTypes,
diagnostics: &DiagnosticsHandler,
span: SourceSpan,
) -> WasmResult<()> {
if !state.reachable {
translate_unreachable_operator(&op, builder, state, mod_info, span)?;
translate_unreachable_operator(&op, builder, state, mod_types, span)?;
return Ok(());
}

Expand All @@ -74,14 +74,14 @@ pub fn translate_operator(
/********************************** Globals ****************************************/
Operator::GlobalGet { global_index } => {
let global_index = GlobalIndex::from_u32(*global_index);
let name = mod_info.global_name(global_index);
let ty = mod_info.globals[global_index].ty.clone();
let name = mod_info.name_section.globals_names[&global_index].clone();
let ty = ir_type(mod_info.globals[global_index].ty)?;
state.push1(builder.ins().load_symbol(name, ty, span));
}
Operator::GlobalSet { global_index } => {
let global_index = GlobalIndex::from_u32(*global_index);
let name = mod_info.global_name(global_index);
let ty = (&mod_info.globals[global_index]).ty.clone();
let name = mod_info.name_section.globals_names[&global_index].clone();
let ty = ir_type(mod_info.globals[global_index].ty)?;
let ptr = builder
.ins()
.symbol_addr(name, Ptr(ty.clone().into()), span);
Expand All @@ -103,9 +103,9 @@ pub fn translate_operator(
}
Operator::Nop => {}
/***************************** Control flow blocks *********************************/
Operator::Block { blockty } => translate_block(blockty, builder, state, mod_info, span)?,
Operator::Loop { blockty } => translate_loop(blockty, builder, state, mod_info, span)?,
Operator::If { blockty } => translate_if(blockty, state, builder, mod_info, span)?,
Operator::Block { blockty } => translate_block(blockty, builder, state, mod_types, span)?,
Operator::Loop { blockty } => translate_loop(blockty, builder, state, mod_types, span)?,
Operator::If { blockty } => translate_if(blockty, state, builder, mod_types, span)?,
Operator::Else => translate_else(state, builder, span)?,
Operator::End => translate_end(state, builder, span),

Expand All @@ -116,7 +116,15 @@ pub fn translate_operator(
Operator::Return => translate_return(state, builder, diagnostics, span)?,
/************************************ Calls ****************************************/
Operator::Call { function_index } => {
translate_call(state, builder, function_index, mod_info, span, diagnostics)?;
translate_call(
state,
builder,
function_index,
mod_info,
mod_types,
span,
diagnostics,
)?;
}
/******************************* Memory management *********************************/
Operator::MemoryGrow { .. } => {
Expand Down Expand Up @@ -608,14 +616,16 @@ fn translate_call(
state: &mut FuncTranslationState,
builder: &mut FunctionBuilderExt,
function_index: &u32,
mod_info: &ModuleInfo,
mod_info: &Module,
mod_types: &ModuleTypes,
span: SourceSpan,
diagnostics: &DiagnosticsHandler,
) -> WasmResult<()> {
let (fident, num_args) = state.get_direct_func(
builder.data_flow_graph_mut(),
*function_index,
mod_info,
mod_types,
diagnostics,
)?;
let args = state.peekn_mut(num_args);
Expand Down Expand Up @@ -722,10 +732,10 @@ fn translate_block(
blockty: &wasmparser::BlockType,
builder: &mut FunctionBuilderExt,
state: &mut FuncTranslationState,
module_info: &ModuleInfo,
mod_types: &ModuleTypes,
span: SourceSpan,
) -> WasmResult<()> {
let blockty = BlockType::from_wasm(blockty, module_info)?;
let blockty = BlockType::from_wasm(blockty, mod_types)?;
let next = builder.create_block_with_params(blockty.results.clone(), span);
state.push_block(next, blockty.params.len(), blockty.results.len());
Ok(())
Expand Down Expand Up @@ -844,10 +854,10 @@ fn translate_if(
blockty: &wasmparser::BlockType,
state: &mut FuncTranslationState,
builder: &mut FunctionBuilderExt,
module_info: &ModuleInfo,
mod_types: &ModuleTypes,
span: SourceSpan,
) -> WasmResult<()> {
let blockty = BlockType::from_wasm(blockty, module_info)?;
let blockty = BlockType::from_wasm(blockty, mod_types)?;
let cond = state.pop1();
let cond_i1 = builder.ins().neq_imm(cond, Immediate::I32(0), span);
let next_block = builder.create_block();
Expand Down Expand Up @@ -906,10 +916,10 @@ fn translate_loop(
blockty: &wasmparser::BlockType,
builder: &mut FunctionBuilderExt,
state: &mut FuncTranslationState,
module_info: &ModuleInfo,
mod_types: &ModuleTypes,
span: SourceSpan,
) -> WasmResult<()> {
let blockty = BlockType::from_wasm(blockty, module_info)?;
let blockty = BlockType::from_wasm(blockty, mod_types)?;
let loop_body = builder.create_block_with_params(blockty.params.clone(), span);
let next = builder.create_block_with_params(blockty.results.clone(), span);
builder
Expand All @@ -931,15 +941,15 @@ fn translate_unreachable_operator(
op: &Operator,
builder: &mut FunctionBuilderExt,
state: &mut FuncTranslationState,
module_info: &ModuleInfo,
mod_types: &ModuleTypes,
span: SourceSpan,
) -> WasmResult<()> {
debug_assert!(!state.reachable);
match *op {
Operator::If { blockty } => {
// Push a placeholder control stack entry. The if isn't reachable,
// so we don't have any branches anywhere.
let blockty = BlockType::from_wasm(&blockty, module_info)?;
let blockty = BlockType::from_wasm(&blockty, mod_types)?;
state.push_if(
Block::reserved_value(),
ElseData::NoElse {
Expand Down
11 changes: 7 additions & 4 deletions frontend-wasm/src/code_translator/tests_unsupported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ use wasmparser::MemArg;
use wasmparser::Operator;
use wasmparser::Operator::*;

use crate::module::environ::ModuleInfo;
use crate::module::func_translation_state::FuncTranslationState;
use crate::module::function_builder_ext::FunctionBuilderContext;
use crate::module::function_builder_ext::FunctionBuilderExt;
use crate::module::Module;
use crate::test_utils::test_diagnostics;

use super::translate_operator;

fn check_unsupported(op: &Operator) {
let diagnostics = test_diagnostics();
let mod_builder = ModuleBuilder::new("noname");
let module_info = ModuleInfo::new(mod_builder.name());
let mut module_builder = ModuleBuilder::new(module_info.name.as_str());
let mod_name = "noname";
let mod_builder = ModuleBuilder::new(mod_name);
let module_info = Module::new();
let mut module_builder = ModuleBuilder::new(mod_name);
let sig = Signature {
params: vec![],
results: vec![],
Expand All @@ -31,11 +32,13 @@ fn check_unsupported(op: &Operator) {
let mut fb_ctx = FunctionBuilderContext::new();
let mut state = FuncTranslationState::new();
let mut builder_ext = FunctionBuilderExt::new(&mut module_func_builder, &mut fb_ctx);
let mod_types = Default::default();
let result = translate_operator(
op,
&mut builder_ext,
&mut state,
&module_info,
&mod_types,
&diagnostics,
SourceSpan::default(),
);
Expand Down
7 changes: 7 additions & 0 deletions frontend-wasm/src/component/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// Possible encodings of strings within the component model.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum StringEncoding {
Utf8,
Utf16,
CompactUtf16,
}
11 changes: 11 additions & 0 deletions frontend-wasm/src/component/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! Support for the Wasm component model translation
//!
//! This module contains all of the internal type definitions to parse and
//! translate the component model.
mod info;
pub mod translate;
mod types;

pub use self::info::*;
pub use self::types::*;
Loading

0 comments on commit 6cc007e

Please sign in to comment.