<commit_before>//! Translation skeletton that traverses the whole WebAssembly module and call helper functions
//! to deal with each part of it.
use wasmparser::{ParserState, SectionCode, ParserInput, Parser, WasmDecoder};
use sections_translator::{SectionParsingError, parse_function_signatures, parse_import_section,
                          parse_function_section, parse_export_section, parse_memory_section,
                          parse_global_section, parse_table_section, parse_elements_section,
                          parse_data_section};
use translation_utils::{type_to_type, Import, SignatureIndex, FunctionIndex, invert_hashmaps};
use cretonne::ir::{Function, Type, FuncRef, SigRef};
use code_translator::translate_function_body;
use cton_frontend::ILBuilder;
use std::collections::HashMap;
use runtime::WasmRuntime;

/// Output of the [`translate_module`](fn.translate_module.html) function.
pub struct TranslationResult {
    /// The translated functions.
    pub functions: Vec<FunctionTranslation>,
    /// When present, the index of the function defined as `start` of the module.
    pub start_index: Option<FunctionIndex>,
}

/// A function in a WebAssembly module can be either imported, or defined inside it.
#[derive(Clone)]
pub enum FunctionTranslation {
    /// A function defined inside the WebAssembly module.
    Code {
        /// The translation in Cretonne IL.
        il: Function,
        /// The mappings between Cretonne imports and indexes in the function index space.
        imports: ImportMappings,
    },
    /// An imported function.
    Import(),
}

#[derive(Clone,Debug)]
/// Mappings describing the relations between imports of the Cretonne IL functions and the
/// functions in the WebAssembly module.
pub struct ImportMappings {
    /// Find the index of a function in the WebAssembly module thanks to a `FuncRef`.
    pub functions: HashMap<FuncRef, FunctionIndex>,
    /// Find the index of a signature in the WebAssembly module thanks to a `SigRef`.
    pub signatures: HashMap<SigRef, SignatureIndex>,
}

impl ImportMappings {
    /// Create a new empty `ImportMappings`.
    pub fn new() -> ImportMappings {
        ImportMappings {
            functions: HashMap::new(),
            signatures: HashMap::new(),
        }
    }
}

/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cretonne IL
/// [`Function`](../cretonne/ir/function/struct.Function.html).
/// Returns the functions and also the mappings for imported functions and signature between the
/// indexes in the wasm module and the indexes inside each functions.
pub fn translate_module(data: &Vec<u8>,
                        runtime: &mut WasmRuntime)
                        -> Result<TranslationResult, String> {
    let mut parser = Parser::new(data.as_slice());
    match *parser.read() {
        ParserState::BeginWasm { .. } => {}
        ref s @ _ => panic!("modules should begin properly: {:?}", s),
    }
    let mut signatures = None;
    let mut functions: Option<Vec<SignatureIndex>> = None;
    let mut globals = Vec::new();
    let mut exports: Option<HashMap<FunctionIndex, String>> = None;
    let mut next_input = ParserInput::Default;
    let mut function_index: FunctionIndex = 0;
    let mut function_imports_count = 0;
    let mut start_index: Option<FunctionIndex> = None;
    loop {
        match *parser.read_with_input(next_input) {
            ParserState::BeginSection { code: SectionCode::Type, .. } => {
                match parse_function_signatures(&mut parser) {
                    Ok(sigs) => signatures = Some(sigs),
                    Err(SectionParsingError::WrongSectionContent(s)) => {
                        return Err(format!("wrong content in the type section: {}", s))
                    }
                };
                next_input = ParserInput::Default;
            }
            ParserState::BeginSection { code: SectionCode::Import, .. } => {
                match parse_import_section(&mut parser) {
                    Ok(imps) => {
                        for import in imps {
                            match import {
                                Import::Function { sig_index } => {<commit_msg>Handle wasmparser errors gracefully.<commit_after>//! Translation skeletton that traverses the whole WebAssembly module and call helper functions
//! to deal with each part of it.
use wasmparser::{ParserState, SectionCode, ParserInput, Parser, WasmDecoder, BinaryReaderError};
use sections_translator::{SectionParsingError, parse_function_signatures, parse_import_section,
                          parse_function_section, parse_export_section, parse_memory_section,
                          parse_global_section, parse_table_section, parse_elements_section,
                          parse_data_section};
use translation_utils::{type_to_type, Import, SignatureIndex, FunctionIndex, invert_hashmaps};
use cretonne::ir::{Function, Type, FuncRef, SigRef};
use code_translator::translate_function_body;
use cton_frontend::ILBuilder;
use std::collections::HashMap;
use runtime::WasmRuntime;

/// Output of the [`translate_module`](fn.translate_module.html) function.
pub struct TranslationResult {
    /// The translated functions.
    pub functions: Vec<FunctionTranslation>,
    /// When present, the index of the function defined as `start` of the module.
    pub start_index: Option<FunctionIndex>,
}

/// A function in a WebAssembly module can be either imported, or defined inside it.
#[derive(Clone)]
pub enum FunctionTranslation {
    /// A function defined inside the WebAssembly module.
    Code {
        /// The translation in Cretonne IL.
        il: Function,
        /// The mappings between Cretonne imports and indexes in the function index space.
        imports: ImportMappings,
    },
    /// An imported function.
    Import(),
}

#[derive(Clone,Debug)]
/// Mappings describing the relations between imports of the Cretonne IL functions and the
/// functions in the WebAssembly module.
pub struct ImportMappings {
    /// Find the index of a function in the WebAssembly module thanks to a `FuncRef`.
    pub functions: HashMap<FuncRef, FunctionIndex>,
    /// Find the index of a signature in the WebAssembly module thanks to a `SigRef`.
    pub signatures: HashMap<SigRef, SignatureIndex>,
}

impl ImportMappings {
    /// Create a new empty `ImportMappings`.
    pub fn new() -> ImportMappings {
        ImportMappings {
            functions: HashMap::new(),
            signatures: HashMap::new(),
        }
    }
}

/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cretonne IL
/// [`Function`](../cretonne/ir/function/struct.Function.html).
/// Returns the functions and also the mappings for imported functions and signature between the
/// indexes in the wasm module and the indexes inside each functions.
pub fn translate_module(data: &Vec<u8>,
                        runtime: &mut WasmRuntime)
                        -> Result<TranslationResult, String> {
    let mut parser = Parser::new(data.as_slice());
    match *parser.read() {
        ParserState::BeginWasm { .. } => {}
        ParserState::Error(BinaryReaderError { message, offset }) => {
            return Err(format!("at offset {}: {}", offset, message));
        }
        ref s @ _ => panic!("modules should begin properly: {:?}", s),
    }
    let mut signatures = None;
    let mut functions: Option<Vec<SignatureIndex>> = None;
    let mut globals = Vec::new();
    let mut exports: Option<HashMap<FunctionIndex, String>> = None;
    let mut next_input = ParserInput::Default;
    let mut function_index: FunctionIndex = 0;
    let mut function_imports_count = 0;
    let mut start_index: Option<FunctionIndex> = None;
    loop {
        match *parser.read_with_input(next_input) {
            ParserState::BeginSection { code: SectionCode::Type, .. } => {
                match parse_function_signatures(&mut parser) {
                    Ok(sigs) => signatures = Some(sigs),
                    Err(SectionParsingError::WrongSectionContent(s)) => {
                        return Err(format!("wrong content in the type section: {}", s))
                    }
                };
                next_input = ParserInput::Default;
            }
            ParserState::BeginSection { code: SectionCode::Import, .. } => {
                match parse_import_section(&mut parser) {
                    Ok(imps) => {
                        for import in imps {
                            match import {
                                Import::Function { sig_index } => {
{'fraction_non_alphanumeric': 0.09898919484140815, 'fraction_numerical': 0.0006971070059254096, 'mean_word_length': 2.649003815175922, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5304163', 'n_tokens_mistral': 2227, 'n_tokens_neox': 2186, 'n_words': 716}