|
|
|
@ -2,8 +2,6 @@ use std::collections::{HashMap, HashSet};
|
|
|
|
|
use std::error::Error;
|
|
|
|
|
use std::str;
|
|
|
|
|
|
|
|
|
|
use wasmparser::ExternalKind;
|
|
|
|
|
use wasmparser::FuncType;
|
|
|
|
|
use wasmparser::ImportSectionEntryType;
|
|
|
|
|
use wasmparser::MemoryType;
|
|
|
|
|
use wasmparser::Operator;
|
|
|
|
@ -14,6 +12,8 @@ use wasmparser::TableType;
|
|
|
|
|
use wasmparser::Type;
|
|
|
|
|
use wasmparser::WasmDecoder;
|
|
|
|
|
use wasmparser::{CustomSectionKind, Name, NameSectionReader, Naming, TypeOrFuncType};
|
|
|
|
|
use wasmparser::{ElemSectionEntryTable, ElementItem, ExternalKind};
|
|
|
|
|
use wasmparser::{FuncType, TypeDef};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct FunctionNameMap {
|
|
|
|
@ -88,11 +88,10 @@ impl Global {
|
|
|
|
|
Type::F32 => 4,
|
|
|
|
|
Type::F64 => 8,
|
|
|
|
|
Type::V128 => 16,
|
|
|
|
|
Type::AnyFunc => 4,
|
|
|
|
|
Type::AnyRef => 8,
|
|
|
|
|
Type::FuncRef => 4,
|
|
|
|
|
Type::ExternRef => 8,
|
|
|
|
|
Type::Func => 4,
|
|
|
|
|
Type::EmptyBlockType => 0,
|
|
|
|
|
Type::Null => 0,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -285,12 +284,12 @@ pub enum Instruction {
|
|
|
|
|
Nop,
|
|
|
|
|
Select,
|
|
|
|
|
|
|
|
|
|
GetLocal { index: u32 },
|
|
|
|
|
SetLocal { index: u32 },
|
|
|
|
|
TeeLocal { index: u32 },
|
|
|
|
|
LocalGet { index: u32 },
|
|
|
|
|
LocalSet { index: u32 },
|
|
|
|
|
LocalTee { index: u32 },
|
|
|
|
|
|
|
|
|
|
GetGlobal { index: u32 },
|
|
|
|
|
SetGlobal { index: u32 },
|
|
|
|
|
GlobalGet { index: u32 },
|
|
|
|
|
GlobalSet { index: u32 },
|
|
|
|
|
|
|
|
|
|
I32Const(i32),
|
|
|
|
|
|
|
|
|
@ -298,10 +297,10 @@ pub enum Instruction {
|
|
|
|
|
|
|
|
|
|
I32ReinterpretF32,
|
|
|
|
|
|
|
|
|
|
I32TruncSF32,
|
|
|
|
|
I32TruncUF32,
|
|
|
|
|
I32TruncSF64,
|
|
|
|
|
I32TruncUF64,
|
|
|
|
|
I32TruncF32S,
|
|
|
|
|
I32TruncF32U,
|
|
|
|
|
I32TruncF64S,
|
|
|
|
|
I32TruncF64U,
|
|
|
|
|
|
|
|
|
|
I32Add,
|
|
|
|
|
I32And,
|
|
|
|
@ -336,15 +335,15 @@ pub enum Instruction {
|
|
|
|
|
|
|
|
|
|
I64Const(i64),
|
|
|
|
|
|
|
|
|
|
I64ExtendSI32,
|
|
|
|
|
I64ExtendUI32,
|
|
|
|
|
I64ExtendI32S,
|
|
|
|
|
I64ExtendI32U,
|
|
|
|
|
|
|
|
|
|
I64ReinterpretF64,
|
|
|
|
|
|
|
|
|
|
I64TruncSF32,
|
|
|
|
|
I64TruncUF32,
|
|
|
|
|
I64TruncSF64,
|
|
|
|
|
I64TruncUF64,
|
|
|
|
|
I64TruncF32S,
|
|
|
|
|
I64TruncF32U,
|
|
|
|
|
I64TruncF64S,
|
|
|
|
|
I64TruncF64U,
|
|
|
|
|
|
|
|
|
|
I64Add,
|
|
|
|
|
I64And,
|
|
|
|
@ -383,10 +382,10 @@ pub enum Instruction {
|
|
|
|
|
|
|
|
|
|
F32ReinterpretI32,
|
|
|
|
|
|
|
|
|
|
F32ConvertSI32,
|
|
|
|
|
F32ConvertUI32,
|
|
|
|
|
F32ConvertSI64,
|
|
|
|
|
F32ConvertUI64,
|
|
|
|
|
F32ConvertI32S,
|
|
|
|
|
F32ConvertI32U,
|
|
|
|
|
F32ConvertI64S,
|
|
|
|
|
F32ConvertI64U,
|
|
|
|
|
|
|
|
|
|
F32Abs,
|
|
|
|
|
F32Add,
|
|
|
|
@ -417,10 +416,10 @@ pub enum Instruction {
|
|
|
|
|
|
|
|
|
|
F64ReinterpretI64,
|
|
|
|
|
|
|
|
|
|
F64ConvertSI32,
|
|
|
|
|
F64ConvertUI32,
|
|
|
|
|
F64ConvertSI64,
|
|
|
|
|
F64ConvertUI64,
|
|
|
|
|
F64ConvertI32S,
|
|
|
|
|
F64ConvertI32U,
|
|
|
|
|
F64ConvertI64S,
|
|
|
|
|
F64ConvertI64U,
|
|
|
|
|
|
|
|
|
|
F64Abs,
|
|
|
|
|
F64Add,
|
|
|
|
@ -538,14 +537,14 @@ impl<'a> From<&'a Operator<'a>> for Instruction {
|
|
|
|
|
Operator::Nop => Instruction::Nop,
|
|
|
|
|
Operator::Select => Instruction::Select,
|
|
|
|
|
|
|
|
|
|
Operator::GetLocal { local_index } => Instruction::GetLocal { index: local_index },
|
|
|
|
|
Operator::SetLocal { local_index } => Instruction::SetLocal { index: local_index },
|
|
|
|
|
Operator::TeeLocal { local_index } => Instruction::TeeLocal { index: local_index },
|
|
|
|
|
Operator::LocalGet { local_index } => Instruction::LocalGet { index: local_index },
|
|
|
|
|
Operator::LocalSet { local_index } => Instruction::LocalSet { index: local_index },
|
|
|
|
|
Operator::LocalTee { local_index } => Instruction::LocalTee { index: local_index },
|
|
|
|
|
|
|
|
|
|
Operator::GetGlobal { global_index } => Instruction::GetGlobal {
|
|
|
|
|
Operator::GlobalGet { global_index } => Instruction::GlobalGet {
|
|
|
|
|
index: global_index,
|
|
|
|
|
},
|
|
|
|
|
Operator::SetGlobal { global_index } => Instruction::SetGlobal {
|
|
|
|
|
Operator::GlobalSet { global_index } => Instruction::GlobalSet {
|
|
|
|
|
index: global_index,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
@ -555,10 +554,10 @@ impl<'a> From<&'a Operator<'a>> for Instruction {
|
|
|
|
|
|
|
|
|
|
Operator::I32ReinterpretF32 => Instruction::I32ReinterpretF32,
|
|
|
|
|
|
|
|
|
|
Operator::I32TruncSF32 => Instruction::I32TruncSF32,
|
|
|
|
|
Operator::I32TruncUF32 => Instruction::I32TruncUF32,
|
|
|
|
|
Operator::I32TruncSF64 => Instruction::I32TruncSF64,
|
|
|
|
|
Operator::I32TruncUF64 => Instruction::I32TruncUF64,
|
|
|
|
|
Operator::I32TruncF32S => Instruction::I32TruncF32S,
|
|
|
|
|
Operator::I32TruncF32U => Instruction::I32TruncF32U,
|
|
|
|
|
Operator::I32TruncF64S => Instruction::I32TruncF64S,
|
|
|
|
|
Operator::I32TruncF64U => Instruction::I32TruncF64U,
|
|
|
|
|
|
|
|
|
|
Operator::I32Add => Instruction::I32Add,
|
|
|
|
|
Operator::I32And => Instruction::I32And,
|
|
|
|
@ -593,15 +592,15 @@ impl<'a> From<&'a Operator<'a>> for Instruction {
|
|
|
|
|
|
|
|
|
|
Operator::I64Const { value } => Instruction::I64Const(value),
|
|
|
|
|
|
|
|
|
|
Operator::I64ExtendSI32 => Instruction::I64ExtendSI32,
|
|
|
|
|
Operator::I64ExtendUI32 => Instruction::I64ExtendUI32,
|
|
|
|
|
Operator::I64ExtendI32S => Instruction::I64ExtendI32S,
|
|
|
|
|
Operator::I64ExtendI32U => Instruction::I64ExtendI32U,
|
|
|
|
|
|
|
|
|
|
Operator::I64ReinterpretF64 => Instruction::I64ReinterpretF64,
|
|
|
|
|
|
|
|
|
|
Operator::I64TruncSF32 => Instruction::I64TruncSF32,
|
|
|
|
|
Operator::I64TruncUF32 => Instruction::I64TruncUF32,
|
|
|
|
|
Operator::I64TruncSF64 => Instruction::I64TruncSF64,
|
|
|
|
|
Operator::I64TruncUF64 => Instruction::I64TruncUF64,
|
|
|
|
|
Operator::I64TruncF32S => Instruction::I64TruncF32S,
|
|
|
|
|
Operator::I64TruncF32U => Instruction::I64TruncF32U,
|
|
|
|
|
Operator::I64TruncF64S => Instruction::I64TruncF64S,
|
|
|
|
|
Operator::I64TruncF64U => Instruction::I64TruncF64U,
|
|
|
|
|
|
|
|
|
|
Operator::I64Add => Instruction::I64Add,
|
|
|
|
|
Operator::I64And => Instruction::I64And,
|
|
|
|
@ -643,10 +642,10 @@ impl<'a> From<&'a Operator<'a>> for Instruction {
|
|
|
|
|
|
|
|
|
|
Operator::F32ReinterpretI32 => Instruction::F32ReinterpretI32,
|
|
|
|
|
|
|
|
|
|
Operator::F32ConvertSI32 => Instruction::F32ConvertSI32,
|
|
|
|
|
Operator::F32ConvertUI32 => Instruction::F32ConvertUI32,
|
|
|
|
|
Operator::F32ConvertSI64 => Instruction::F32ConvertSI64,
|
|
|
|
|
Operator::F32ConvertUI64 => Instruction::F32ConvertUI64,
|
|
|
|
|
Operator::F32ConvertI32S => Instruction::F32ConvertI32S,
|
|
|
|
|
Operator::F32ConvertI32U => Instruction::F32ConvertI32U,
|
|
|
|
|
Operator::F32ConvertI64S => Instruction::F32ConvertI64S,
|
|
|
|
|
Operator::F32ConvertI64U => Instruction::F32ConvertI64U,
|
|
|
|
|
|
|
|
|
|
Operator::F32Abs => Instruction::F32Abs,
|
|
|
|
|
Operator::F32Add => Instruction::F32Add,
|
|
|
|
@ -680,10 +679,10 @@ impl<'a> From<&'a Operator<'a>> for Instruction {
|
|
|
|
|
|
|
|
|
|
Operator::F64ReinterpretI64 => Instruction::F64ReinterpretI64,
|
|
|
|
|
|
|
|
|
|
Operator::F64ConvertSI32 => Instruction::F64ConvertSI32,
|
|
|
|
|
Operator::F64ConvertUI32 => Instruction::F64ConvertUI32,
|
|
|
|
|
Operator::F64ConvertSI64 => Instruction::F64ConvertSI64,
|
|
|
|
|
Operator::F64ConvertUI64 => Instruction::F64ConvertUI64,
|
|
|
|
|
Operator::F64ConvertI32S => Instruction::F64ConvertI32S,
|
|
|
|
|
Operator::F64ConvertI32U => Instruction::F64ConvertI32U,
|
|
|
|
|
Operator::F64ConvertI64S => Instruction::F64ConvertI64S,
|
|
|
|
|
Operator::F64ConvertI64U => Instruction::F64ConvertI64U,
|
|
|
|
|
|
|
|
|
|
Operator::F64Abs => Instruction::F64Abs,
|
|
|
|
|
Operator::F64Add => Instruction::F64Add,
|
|
|
|
@ -1088,7 +1087,18 @@ impl WasmModule {
|
|
|
|
|
fn process_type_section(&mut self, p: &mut Parser) -> ProcessState {
|
|
|
|
|
match p.read() {
|
|
|
|
|
&ParserState::TypeSectionEntry(ref f) => {
|
|
|
|
|
self.types.push(f.clone());
|
|
|
|
|
match f {
|
|
|
|
|
TypeDef::Func(func_type) => self.types.push(func_type.clone()),
|
|
|
|
|
TypeDef::Instance(_instance_type) => {
|
|
|
|
|
panic!(
|
|
|
|
|
"TypeDef::Instance (type {:?}) not implemented",
|
|
|
|
|
_instance_type
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
TypeDef::Module(_module_type) => {
|
|
|
|
|
panic!("TypeDef::Module (type {:?}) not implemented", _module_type)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ProcessState::TypeSection
|
|
|
|
|
}
|
|
|
|
|
&ParserState::EndSection => ProcessState::Outer,
|
|
|
|
@ -1117,7 +1127,9 @@ impl WasmModule {
|
|
|
|
|
match ty {
|
|
|
|
|
ImportSectionEntryType::Function(i) => {
|
|
|
|
|
let source = module.to_string();
|
|
|
|
|
let name = field.to_string();
|
|
|
|
|
let name = field
|
|
|
|
|
.expect("Expected imported function to have name")
|
|
|
|
|
.to_string();
|
|
|
|
|
let appended = source.clone() + "_" + &name;
|
|
|
|
|
self.functions.push(Function::Imported {
|
|
|
|
|
source,
|
|
|
|
@ -1129,7 +1141,9 @@ impl WasmModule {
|
|
|
|
|
}
|
|
|
|
|
ImportSectionEntryType::Global(global_ty) => {
|
|
|
|
|
let source = module.to_string();
|
|
|
|
|
let name = field.to_string();
|
|
|
|
|
let name = field
|
|
|
|
|
.expect("Expected imported global to have name")
|
|
|
|
|
.to_string();
|
|
|
|
|
let appended = source + "_" + &name;
|
|
|
|
|
|
|
|
|
|
self.globals.push(Global::Imported {
|
|
|
|
@ -1144,6 +1158,15 @@ impl WasmModule {
|
|
|
|
|
ImportSectionEntryType::Table(table_ty) => {
|
|
|
|
|
self.tables.push(*table_ty);
|
|
|
|
|
}
|
|
|
|
|
ImportSectionEntryType::Module(i) => {
|
|
|
|
|
panic!("ImportSectionEntryType::Module (idx {}) not implemented", i)
|
|
|
|
|
}
|
|
|
|
|
ImportSectionEntryType::Instance(i) => {
|
|
|
|
|
panic!(
|
|
|
|
|
"ImportSectionEntryType::Instance (idx {}) not implemented",
|
|
|
|
|
i
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ProcessState::ImportSection
|
|
|
|
|
}
|
|
|
|
@ -1336,9 +1359,17 @@ impl WasmModule {
|
|
|
|
|
|
|
|
|
|
fn process_table_element_section(&mut self, p: &mut Parser) -> ProcessState {
|
|
|
|
|
match p.read() {
|
|
|
|
|
&ParserState::BeginActiveElementSectionEntry(table_id) => {
|
|
|
|
|
ProcessState::TableElementEntry { table_id }
|
|
|
|
|
}
|
|
|
|
|
&ParserState::BeginElementSectionEntry { table, ty: _ } => match table {
|
|
|
|
|
ElemSectionEntryTable::Active(table_id) => {
|
|
|
|
|
ProcessState::TableElementEntry { table_id }
|
|
|
|
|
}
|
|
|
|
|
ElemSectionEntryTable::Passive => {
|
|
|
|
|
panic!("ElemSectionEntryTable::Passive not implemented")
|
|
|
|
|
}
|
|
|
|
|
ElemSectionEntryTable::Declared => {
|
|
|
|
|
panic!("ElemSectionEntryTable::Declared not implemented")
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
&ParserState::EndSection => ProcessState::Outer,
|
|
|
|
|
e => panic!("Have not implemented table element section state {:?}", e),
|
|
|
|
|
}
|
|
|
|
@ -1380,7 +1411,16 @@ impl WasmModule {
|
|
|
|
|
let mut function_indexes: Vec<u32> = Vec::new();
|
|
|
|
|
loop {
|
|
|
|
|
match p.read() {
|
|
|
|
|
&ParserState::ElementSectionEntryBody(ref v) => function_indexes.extend(v.iter()),
|
|
|
|
|
&ParserState::ElementSectionEntryBody(ref v) => {
|
|
|
|
|
for elem in v.iter() {
|
|
|
|
|
match elem {
|
|
|
|
|
ElementItem::Func(idx) => function_indexes.push(*idx),
|
|
|
|
|
ElementItem::Null(ty) => {
|
|
|
|
|
panic!("ElementItem::Null (type {:?}) not implemented", ty)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
&ParserState::EndElementSectionEntry => {
|
|
|
|
|
assert_eq!(table_id, 0);
|
|
|
|
|
let ti = TableInitializer {
|
|
|
|
|