Complete support for global init expressions.
This commit is contained in:
@@ -197,6 +197,7 @@ impl WasmRuntime for DummyRuntime {
|
|||||||
fn declare_table_elements(
|
fn declare_table_elements(
|
||||||
&mut self,
|
&mut self,
|
||||||
_table_index: TableIndex,
|
_table_index: TableIndex,
|
||||||
|
_base: Option<GlobalIndex>,
|
||||||
_offset: usize,
|
_offset: usize,
|
||||||
_elements: &[FunctionIndex],
|
_elements: &[FunctionIndex],
|
||||||
) {
|
) {
|
||||||
@@ -208,11 +209,11 @@ impl WasmRuntime for DummyRuntime {
|
|||||||
fn declare_data_initialization(
|
fn declare_data_initialization(
|
||||||
&mut self,
|
&mut self,
|
||||||
_memory_index: MemoryIndex,
|
_memory_index: MemoryIndex,
|
||||||
|
_base: Option<GlobalIndex>,
|
||||||
_offset: usize,
|
_offset: usize,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
) -> Result<(), String> {
|
) {
|
||||||
// We do nothing
|
// We do nothing
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declare_func_export(&mut self, func_index: FunctionIndex, name: &str) {
|
fn declare_func_export(&mut self, func_index: FunctionIndex, name: &str) {
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ pub trait WasmRuntime: FuncEnvironment {
|
|||||||
fn declare_table_elements(
|
fn declare_table_elements(
|
||||||
&mut self,
|
&mut self,
|
||||||
table_index: TableIndex,
|
table_index: TableIndex,
|
||||||
|
base: Option<GlobalIndex>,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
elements: &[FunctionIndex],
|
elements: &[FunctionIndex],
|
||||||
);
|
);
|
||||||
@@ -192,9 +193,10 @@ pub trait WasmRuntime: FuncEnvironment {
|
|||||||
fn declare_data_initialization(
|
fn declare_data_initialization(
|
||||||
&mut self,
|
&mut self,
|
||||||
memory_index: MemoryIndex,
|
memory_index: MemoryIndex,
|
||||||
|
base: Option<GlobalIndex>,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<(), String>;
|
);
|
||||||
|
|
||||||
/// Declares a function export to the runtime.
|
/// Declares a function export to the runtime.
|
||||||
fn declare_func_export(&mut self, func_index: FunctionIndex, name: &str);
|
fn declare_func_export(&mut self, func_index: FunctionIndex, name: &str);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ pub fn parse_import_section(
|
|||||||
},
|
},
|
||||||
size: tab.limits.initial as usize,
|
size: tab.limits.initial as usize,
|
||||||
maximum: tab.limits.maximum.map(|x| x as usize),
|
maximum: tab.limits.maximum.map(|x| x as usize),
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
ParserState::EndSection => break,
|
ParserState::EndSection => break,
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
@@ -227,7 +227,6 @@ pub fn parse_global_section(
|
|||||||
GlobalInit::GlobalRef(global_index as GlobalIndex)
|
GlobalInit::GlobalRef(global_index as GlobalIndex)
|
||||||
}
|
}
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
|
|
||||||
};
|
};
|
||||||
match *parser.read() {
|
match *parser.read() {
|
||||||
ParserState::EndInitExpressionBody => (),
|
ParserState::EndInitExpressionBody => (),
|
||||||
@@ -261,35 +260,14 @@ pub fn parse_data_section(
|
|||||||
ParserState::BeginInitExpressionBody => (),
|
ParserState::BeginInitExpressionBody => (),
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
};
|
};
|
||||||
let mut offset = match *parser.read() {
|
let (base, offset) = match *parser.read() {
|
||||||
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
||||||
if value < 0 {
|
(None, value as u32 as usize)
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from(
|
|
||||||
"negative \
|
|
||||||
offset value",
|
|
||||||
)));
|
|
||||||
} else {
|
|
||||||
value as usize
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => {
|
ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => {
|
||||||
match runtime.get_global(global_index as GlobalIndex).initializer {
|
match runtime.get_global(global_index as GlobalIndex).initializer {
|
||||||
GlobalInit::I32Const(value) => {
|
GlobalInit::I32Const(value) => (None, value as u32 as usize),
|
||||||
if value < 0 {
|
GlobalInit::Import() => (Some(global_index as GlobalIndex), 0),
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from(
|
|
||||||
"\
|
|
||||||
negative offset value",
|
|
||||||
)));
|
|
||||||
} else {
|
|
||||||
value as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GlobalInit::Import() => {
|
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from(
|
|
||||||
"\
|
|
||||||
imported globals not supported",
|
|
||||||
)))
|
|
||||||
} // TODO: add runtime support
|
|
||||||
_ => panic!("should not happen"),
|
_ => panic!("should not happen"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -303,17 +281,20 @@ pub fn parse_data_section(
|
|||||||
ParserState::BeginDataSectionEntryBody(_) => (),
|
ParserState::BeginDataSectionEntryBody(_) => (),
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
};
|
};
|
||||||
|
let mut running_offset = offset;
|
||||||
loop {
|
loop {
|
||||||
let data = match *parser.read() {
|
let data = match *parser.read() {
|
||||||
ParserState::DataSectionEntryBodyChunk(data) => data,
|
ParserState::DataSectionEntryBodyChunk(data) => data,
|
||||||
ParserState::EndDataSectionEntryBody => break,
|
ParserState::EndDataSectionEntryBody => break,
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
};
|
};
|
||||||
match runtime.declare_data_initialization(memory_index as MemoryIndex, offset, data) {
|
runtime.declare_data_initialization(
|
||||||
Ok(()) => (),
|
memory_index as MemoryIndex,
|
||||||
Err(s) => return Err(SectionParsingError::WrongSectionContent(s)),
|
base,
|
||||||
};
|
running_offset,
|
||||||
offset += data.len();
|
data,
|
||||||
|
);
|
||||||
|
running_offset += data.len();
|
||||||
}
|
}
|
||||||
match *parser.read() {
|
match *parser.read() {
|
||||||
ParserState::EndDataSectionEntry => (),
|
ParserState::EndDataSectionEntry => (),
|
||||||
@@ -354,7 +335,7 @@ pub fn parse_elements_section(
|
|||||||
) -> Result<(), SectionParsingError> {
|
) -> Result<(), SectionParsingError> {
|
||||||
loop {
|
loop {
|
||||||
let table_index = match *parser.read() {
|
let table_index = match *parser.read() {
|
||||||
ParserState::BeginElementSectionEntry(ref table_index) => *table_index as TableIndex,
|
ParserState::BeginElementSectionEntry(table_index) => table_index as TableIndex,
|
||||||
ParserState::EndSection => break,
|
ParserState::EndSection => break,
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
};
|
};
|
||||||
@@ -362,30 +343,14 @@ pub fn parse_elements_section(
|
|||||||
ParserState::BeginInitExpressionBody => (),
|
ParserState::BeginInitExpressionBody => (),
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
};
|
};
|
||||||
let offset = match *parser.read() {
|
let (base, offset) = match *parser.read() {
|
||||||
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
|
||||||
if value < 0 {
|
(None, value as u32 as usize)
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from(
|
|
||||||
"negative \
|
|
||||||
offset value",
|
|
||||||
)));
|
|
||||||
} else {
|
|
||||||
value as usize
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => {
|
ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => {
|
||||||
match runtime.get_global(global_index as GlobalIndex).initializer {
|
match runtime.get_global(global_index as GlobalIndex).initializer {
|
||||||
GlobalInit::I32Const(value) => {
|
GlobalInit::I32Const(value) => (None, value as u32 as usize),
|
||||||
if value < 0 {
|
GlobalInit::Import() => (Some(global_index as GlobalIndex), 0),
|
||||||
return Err(SectionParsingError::WrongSectionContent(String::from(
|
|
||||||
"\
|
|
||||||
negative offset value",
|
|
||||||
)));
|
|
||||||
} else {
|
|
||||||
value as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GlobalInit::Import() => 0, // TODO: add runtime support
|
|
||||||
_ => panic!("should not happen"),
|
_ => panic!("should not happen"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -399,7 +364,7 @@ pub fn parse_elements_section(
|
|||||||
ParserState::ElementSectionEntryBody(ref elements) => {
|
ParserState::ElementSectionEntryBody(ref elements) => {
|
||||||
let elems: Vec<FunctionIndex> =
|
let elems: Vec<FunctionIndex> =
|
||||||
elements.iter().map(|&x| x as FunctionIndex).collect();
|
elements.iter().map(|&x| x as FunctionIndex).collect();
|
||||||
runtime.declare_table_elements(table_index, offset, &elems)
|
runtime.declare_table_elements(table_index, base, offset, &elems)
|
||||||
}
|
}
|
||||||
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user