Trait cranelift_wasm::ModuleEnvironment
source · pub trait ModuleEnvironment<'data> {
Show 43 methods
fn declare_type_func(
&mut self,
wasm_func_type: WasmFuncType
) -> WasmResult<()>;
fn declare_func_import(
&mut self,
index: TypeIndex,
module: &'data str,
field: &'data str
) -> WasmResult<()>;
fn declare_table_import(
&mut self,
table: Table,
module: &'data str,
field: &'data str
) -> WasmResult<()>;
fn declare_memory_import(
&mut self,
memory: Memory,
module: &'data str,
field: &'data str
) -> WasmResult<()>;
fn declare_global_import(
&mut self,
global: Global,
module: &'data str,
field: &'data str
) -> WasmResult<()>;
fn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>;
fn declare_table(&mut self, table: Table) -> WasmResult<()>;
fn declare_memory(&mut self, memory: Memory) -> WasmResult<()>;
fn declare_global(&mut self, global: Global) -> WasmResult<()>;
fn declare_func_export(
&mut self,
func_index: FuncIndex,
name: &'data str
) -> WasmResult<()>;
fn declare_table_export(
&mut self,
table_index: TableIndex,
name: &'data str
) -> WasmResult<()>;
fn declare_memory_export(
&mut self,
memory_index: MemoryIndex,
name: &'data str
) -> WasmResult<()>;
fn declare_global_export(
&mut self,
global_index: GlobalIndex,
name: &'data str
) -> WasmResult<()>;
fn declare_start_func(&mut self, index: FuncIndex) -> WasmResult<()>;
fn declare_table_elements(
&mut self,
table_index: TableIndex,
base: Option<GlobalIndex>,
offset: u32,
elements: Box<[FuncIndex]>
) -> WasmResult<()>;
fn declare_passive_element(
&mut self,
index: ElemIndex,
elements: Box<[FuncIndex]>
) -> WasmResult<()>;
fn declare_passive_data(
&mut self,
data_index: DataIndex,
data: &'data [u8]
) -> WasmResult<()>;
fn define_function_body(
&mut self,
validator: FuncValidator<ValidatorResources>,
body: FunctionBody<'data>
) -> WasmResult<()>;
fn declare_data_initialization(
&mut self,
memory_index: MemoryIndex,
base: Option<GlobalIndex>,
offset: u64,
data: &'data [u8]
) -> WasmResult<()>;
fn reserve_types(&mut self, _num: u32) -> WasmResult<()> { ... }
fn type_to_signature(&self, index: TypeIndex) -> WasmResult<SignatureIndex> { ... }
fn reserve_imports(&mut self, _num: u32) -> WasmResult<()> { ... }
fn declare_tag_import(
&mut self,
tag: Tag,
module: &'data str,
field: &'data str
) -> WasmResult<()> { ... }
fn finish_imports(&mut self) -> WasmResult<()> { ... }
fn reserve_func_types(&mut self, _num: u32) -> WasmResult<()> { ... }
fn reserve_tables(&mut self, _num: u32) -> WasmResult<()> { ... }
fn reserve_memories(&mut self, _num: u32) -> WasmResult<()> { ... }
fn reserve_tags(&mut self, _num: u32) -> WasmResult<()> { ... }
fn declare_tag(&mut self, tag: Tag) -> WasmResult<()> { ... }
fn reserve_globals(&mut self, _num: u32) -> WasmResult<()> { ... }
fn reserve_exports(&mut self, _num: u32) -> WasmResult<()> { ... }
fn declare_tag_export(
&mut self,
tag_index: TagIndex,
name: &'data str
) -> WasmResult<()> { ... }
fn finish_exports(&mut self) -> WasmResult<()> { ... }
fn reserve_table_elements(&mut self, _num: u32) -> WasmResult<()> { ... }
fn declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()> { ... }
fn reserve_passive_data(&mut self, count: u32) -> WasmResult<()> { ... }
fn reserve_function_bodies(&mut self, bodies: u32, code_section_offset: u64) { ... }
fn reserve_data_initializers(&mut self, _num: u32) -> WasmResult<()> { ... }
fn declare_module_name(&mut self, _name: &'data str) { ... }
fn declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str) { ... }
fn declare_local_name(
&mut self,
_func_index: FuncIndex,
_local_index: u32,
_name: &'data str
) { ... }
fn custom_section(
&mut self,
_name: &'data str,
_data: &'data [u8]
) -> WasmResult<()> { ... }
fn wasm_features(&self) -> WasmFeatures { ... }
}
Expand description
An object satisfying the ModuleEnvironment
trait can be passed as argument to the
translate_module
function. These methods should not be called
by the user, they are only for cranelift-wasm
internal use.
Required Methods§
sourcefn declare_type_func(&mut self, wasm_func_type: WasmFuncType) -> WasmResult<()>
fn declare_type_func(&mut self, wasm_func_type: WasmFuncType) -> WasmResult<()>
Declares a function signature to the environment.
sourcefn declare_func_import(
&mut self,
index: TypeIndex,
module: &'data str,
field: &'data str
) -> WasmResult<()>
fn declare_func_import(
&mut self,
index: TypeIndex,
module: &'data str,
field: &'data str
) -> WasmResult<()>
Declares a function import to the environment.
sourcefn declare_table_import(
&mut self,
table: Table,
module: &'data str,
field: &'data str
) -> WasmResult<()>
fn declare_table_import(
&mut self,
table: Table,
module: &'data str,
field: &'data str
) -> WasmResult<()>
Declares a table import to the environment.
sourcefn declare_memory_import(
&mut self,
memory: Memory,
module: &'data str,
field: &'data str
) -> WasmResult<()>
fn declare_memory_import(
&mut self,
memory: Memory,
module: &'data str,
field: &'data str
) -> WasmResult<()>
Declares a memory import to the environment.
sourcefn declare_global_import(
&mut self,
global: Global,
module: &'data str,
field: &'data str
) -> WasmResult<()>
fn declare_global_import(
&mut self,
global: Global,
module: &'data str,
field: &'data str
) -> WasmResult<()>
Declares a global import to the environment.
sourcefn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>
fn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>
Declares the type (signature) of a local function in the module.
sourcefn declare_table(&mut self, table: Table) -> WasmResult<()>
fn declare_table(&mut self, table: Table) -> WasmResult<()>
Declares a table to the environment.
sourcefn declare_memory(&mut self, memory: Memory) -> WasmResult<()>
fn declare_memory(&mut self, memory: Memory) -> WasmResult<()>
Declares a memory to the environment
sourcefn declare_global(&mut self, global: Global) -> WasmResult<()>
fn declare_global(&mut self, global: Global) -> WasmResult<()>
Declares a global to the environment.
sourcefn declare_func_export(
&mut self,
func_index: FuncIndex,
name: &'data str
) -> WasmResult<()>
fn declare_func_export(
&mut self,
func_index: FuncIndex,
name: &'data str
) -> WasmResult<()>
Declares a function export to the environment.
sourcefn declare_table_export(
&mut self,
table_index: TableIndex,
name: &'data str
) -> WasmResult<()>
fn declare_table_export(
&mut self,
table_index: TableIndex,
name: &'data str
) -> WasmResult<()>
Declares a table export to the environment.
sourcefn declare_memory_export(
&mut self,
memory_index: MemoryIndex,
name: &'data str
) -> WasmResult<()>
fn declare_memory_export(
&mut self,
memory_index: MemoryIndex,
name: &'data str
) -> WasmResult<()>
Declares a memory export to the environment.
sourcefn declare_global_export(
&mut self,
global_index: GlobalIndex,
name: &'data str
) -> WasmResult<()>
fn declare_global_export(
&mut self,
global_index: GlobalIndex,
name: &'data str
) -> WasmResult<()>
Declares a global export to the environment.
sourcefn declare_start_func(&mut self, index: FuncIndex) -> WasmResult<()>
fn declare_start_func(&mut self, index: FuncIndex) -> WasmResult<()>
Declares the optional start function.
sourcefn declare_table_elements(
&mut self,
table_index: TableIndex,
base: Option<GlobalIndex>,
offset: u32,
elements: Box<[FuncIndex]>
) -> WasmResult<()>
fn declare_table_elements(
&mut self,
table_index: TableIndex,
base: Option<GlobalIndex>,
offset: u32,
elements: Box<[FuncIndex]>
) -> WasmResult<()>
Fills a declared table with references to functions in the module.
sourcefn declare_passive_element(
&mut self,
index: ElemIndex,
elements: Box<[FuncIndex]>
) -> WasmResult<()>
fn declare_passive_element(
&mut self,
index: ElemIndex,
elements: Box<[FuncIndex]>
) -> WasmResult<()>
Declare a passive element segment.
sourcefn declare_passive_data(
&mut self,
data_index: DataIndex,
data: &'data [u8]
) -> WasmResult<()>
fn declare_passive_data(
&mut self,
data_index: DataIndex,
data: &'data [u8]
) -> WasmResult<()>
Declare a passive data segment.
sourcefn define_function_body(
&mut self,
validator: FuncValidator<ValidatorResources>,
body: FunctionBody<'data>
) -> WasmResult<()>
fn define_function_body(
&mut self,
validator: FuncValidator<ValidatorResources>,
body: FunctionBody<'data>
) -> WasmResult<()>
Provides the contents of a function body.
sourcefn declare_data_initialization(
&mut self,
memory_index: MemoryIndex,
base: Option<GlobalIndex>,
offset: u64,
data: &'data [u8]
) -> WasmResult<()>
fn declare_data_initialization(
&mut self,
memory_index: MemoryIndex,
base: Option<GlobalIndex>,
offset: u64,
data: &'data [u8]
) -> WasmResult<()>
Fills a declared memory with bytes at module instantiation.
Provided Methods§
sourcefn reserve_types(&mut self, _num: u32) -> WasmResult<()>
fn reserve_types(&mut self, _num: u32) -> WasmResult<()>
Provides the number of types up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
pub fn parse_type_section<'a>(
types: TypeSectionReader<'a>,
environ: &mut dyn ModuleEnvironment<'a>,
) -> WasmResult<()> {
let count = types.get_count();
environ.reserve_types(count)?;
for entry in types {
match entry? {
Type::Func(wasm_func_ty) => {
environ.declare_type_func(wasm_func_ty.clone().try_into()?)?;
}
}
}
Ok(())
}
sourcefn type_to_signature(&self, index: TypeIndex) -> WasmResult<SignatureIndex>
fn type_to_signature(&self, index: TypeIndex) -> WasmResult<SignatureIndex>
Translates a type index to its signature index, only called for type indices which point to functions.
sourcefn reserve_imports(&mut self, _num: u32) -> WasmResult<()>
fn reserve_imports(&mut self, _num: u32) -> WasmResult<()>
Provides the number of imports up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
pub fn parse_import_section<'data>(
imports: ImportSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
environ.reserve_imports(imports.get_count())?;
for entry in imports {
let import = entry?;
match import.ty {
TypeRef::Func(sig) => {
environ.declare_func_import(
TypeIndex::from_u32(sig),
import.module,
import.name,
)?;
}
TypeRef::Memory(ty) => {
environ.declare_memory_import(memory(ty), import.module, import.name)?;
}
TypeRef::Tag(e) => {
environ.declare_tag_import(tag(e), import.module, import.name)?;
}
TypeRef::Global(ty) => {
let ty = global(ty, GlobalInit::Import)?;
environ.declare_global_import(ty, import.module, import.name)?;
}
TypeRef::Table(ty) => {
let ty = table(ty)?;
environ.declare_table_import(ty, import.module, import.name)?;
}
}
}
environ.finish_imports()?;
Ok(())
}
sourcefn declare_tag_import(
&mut self,
tag: Tag,
module: &'data str,
field: &'data str
) -> WasmResult<()>
fn declare_tag_import(
&mut self,
tag: Tag,
module: &'data str,
field: &'data str
) -> WasmResult<()>
Declares an tag import to the environment.
Examples found in repository?
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
pub fn parse_import_section<'data>(
imports: ImportSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
environ.reserve_imports(imports.get_count())?;
for entry in imports {
let import = entry?;
match import.ty {
TypeRef::Func(sig) => {
environ.declare_func_import(
TypeIndex::from_u32(sig),
import.module,
import.name,
)?;
}
TypeRef::Memory(ty) => {
environ.declare_memory_import(memory(ty), import.module, import.name)?;
}
TypeRef::Tag(e) => {
environ.declare_tag_import(tag(e), import.module, import.name)?;
}
TypeRef::Global(ty) => {
let ty = global(ty, GlobalInit::Import)?;
environ.declare_global_import(ty, import.module, import.name)?;
}
TypeRef::Table(ty) => {
let ty = table(ty)?;
environ.declare_table_import(ty, import.module, import.name)?;
}
}
}
environ.finish_imports()?;
Ok(())
}
sourcefn finish_imports(&mut self) -> WasmResult<()>
fn finish_imports(&mut self) -> WasmResult<()>
Notifies the implementation that all imports have been declared.
Examples found in repository?
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
pub fn parse_import_section<'data>(
imports: ImportSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
environ.reserve_imports(imports.get_count())?;
for entry in imports {
let import = entry?;
match import.ty {
TypeRef::Func(sig) => {
environ.declare_func_import(
TypeIndex::from_u32(sig),
import.module,
import.name,
)?;
}
TypeRef::Memory(ty) => {
environ.declare_memory_import(memory(ty), import.module, import.name)?;
}
TypeRef::Tag(e) => {
environ.declare_tag_import(tag(e), import.module, import.name)?;
}
TypeRef::Global(ty) => {
let ty = global(ty, GlobalInit::Import)?;
environ.declare_global_import(ty, import.module, import.name)?;
}
TypeRef::Table(ty) => {
let ty = table(ty)?;
environ.declare_table_import(ty, import.module, import.name)?;
}
}
}
environ.finish_imports()?;
Ok(())
}
sourcefn reserve_func_types(&mut self, _num: u32) -> WasmResult<()>
fn reserve_func_types(&mut self, _num: u32) -> WasmResult<()>
Provides the number of defined functions up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
pub fn parse_function_section(
functions: FunctionSectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
let num_functions = functions.get_count();
if num_functions == std::u32::MAX {
// We reserve `u32::MAX` for our own use in cranelift-entity.
return Err(WasmError::ImplLimitExceeded);
}
environ.reserve_func_types(num_functions)?;
for entry in functions {
let sigindex = entry?;
environ.declare_func_type(TypeIndex::from_u32(sigindex))?;
}
Ok(())
}
sourcefn reserve_tables(&mut self, _num: u32) -> WasmResult<()>
fn reserve_tables(&mut self, _num: u32) -> WasmResult<()>
Provides the number of defined tables up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
141 142 143 144 145 146 147 148 149 150 151 152 153
pub fn parse_table_section(
tables: TableSectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_tables(tables.get_count())?;
for entry in tables {
let ty = table(entry?)?;
environ.declare_table(ty)?;
}
Ok(())
}
sourcefn reserve_memories(&mut self, _num: u32) -> WasmResult<()>
fn reserve_memories(&mut self, _num: u32) -> WasmResult<()>
Provides the number of defined memories up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
156 157 158 159 160 161 162 163 164 165 166 167 168
pub fn parse_memory_section(
memories: MemorySectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_memories(memories.get_count())?;
for entry in memories {
let memory = memory(entry?);
environ.declare_memory(memory)?;
}
Ok(())
}
Provides the number of defined tags up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
171 172 173 174 175 176 177 178 179 180 181 182 183
pub fn parse_tag_section(
tags: TagSectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_tags(tags.get_count())?;
for entry in tags {
let tag = tag(entry?);
environ.declare_tag(tag)?;
}
Ok(())
}
sourcefn declare_tag(&mut self, tag: Tag) -> WasmResult<()>
fn declare_tag(&mut self, tag: Tag) -> WasmResult<()>
Declares an tag to the environment
Examples found in repository?
171 172 173 174 175 176 177 178 179 180 181 182 183
pub fn parse_tag_section(
tags: TagSectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_tags(tags.get_count())?;
for entry in tags {
let tag = tag(entry?);
environ.declare_tag(tag)?;
}
Ok(())
}
sourcefn reserve_globals(&mut self, _num: u32) -> WasmResult<()>
fn reserve_globals(&mut self, _num: u32) -> WasmResult<()>
Provides the number of defined globals up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
pub fn parse_global_section(
globals: GlobalSectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_globals(globals.get_count())?;
for entry in globals {
let wasmparser::Global { ty, init_expr } = entry?;
let mut init_expr_reader = init_expr.get_binary_reader();
let initializer = match init_expr_reader.read_operator()? {
Operator::I32Const { value } => GlobalInit::I32Const(value),
Operator::I64Const { value } => GlobalInit::I64Const(value),
Operator::F32Const { value } => GlobalInit::F32Const(value.bits()),
Operator::F64Const { value } => GlobalInit::F64Const(value.bits()),
Operator::V128Const { value } => {
GlobalInit::V128Const(u128::from_le_bytes(*value.bytes()))
}
Operator::RefNull { ty: _ } => GlobalInit::RefNullConst,
Operator::RefFunc { function_index } => {
GlobalInit::RefFunc(FuncIndex::from_u32(function_index))
}
Operator::GlobalGet { global_index } => {
GlobalInit::GetGlobal(GlobalIndex::from_u32(global_index))
}
ref s => {
return Err(wasm_unsupported!(
"unsupported init expr in global section: {:?}",
s
));
}
};
let ty = global(ty, initializer)?;
environ.declare_global(ty)?;
}
Ok(())
}
sourcefn reserve_exports(&mut self, _num: u32) -> WasmResult<()>
fn reserve_exports(&mut self, _num: u32) -> WasmResult<()>
Provides the number of exports up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
pub fn parse_export_section<'data>(
exports: ExportSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
environ.reserve_exports(exports.get_count())?;
for entry in exports {
let Export {
name,
ref kind,
index,
} = entry?;
// The input has already been validated, so we should be able to
// assume valid UTF-8 and use `from_utf8_unchecked` if performance
// becomes a concern here.
let index = index as usize;
match *kind {
ExternalKind::Func => environ.declare_func_export(FuncIndex::new(index), name)?,
ExternalKind::Table => environ.declare_table_export(TableIndex::new(index), name)?,
ExternalKind::Memory => environ.declare_memory_export(MemoryIndex::new(index), name)?,
ExternalKind::Tag => environ.declare_tag_export(TagIndex::new(index), name)?,
ExternalKind::Global => environ.declare_global_export(GlobalIndex::new(index), name)?,
}
}
environ.finish_exports()?;
Ok(())
}
sourcefn declare_tag_export(
&mut self,
tag_index: TagIndex,
name: &'data str
) -> WasmResult<()>
fn declare_tag_export(
&mut self,
tag_index: TagIndex,
name: &'data str
) -> WasmResult<()>
Declares an tag export to the environment.
Examples found in repository?
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
pub fn parse_export_section<'data>(
exports: ExportSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
environ.reserve_exports(exports.get_count())?;
for entry in exports {
let Export {
name,
ref kind,
index,
} = entry?;
// The input has already been validated, so we should be able to
// assume valid UTF-8 and use `from_utf8_unchecked` if performance
// becomes a concern here.
let index = index as usize;
match *kind {
ExternalKind::Func => environ.declare_func_export(FuncIndex::new(index), name)?,
ExternalKind::Table => environ.declare_table_export(TableIndex::new(index), name)?,
ExternalKind::Memory => environ.declare_memory_export(MemoryIndex::new(index), name)?,
ExternalKind::Tag => environ.declare_tag_export(TagIndex::new(index), name)?,
ExternalKind::Global => environ.declare_global_export(GlobalIndex::new(index), name)?,
}
}
environ.finish_exports()?;
Ok(())
}
sourcefn finish_exports(&mut self) -> WasmResult<()>
fn finish_exports(&mut self) -> WasmResult<()>
Notifies the implementation that all exports have been declared.
Examples found in repository?
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
pub fn parse_export_section<'data>(
exports: ExportSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
environ.reserve_exports(exports.get_count())?;
for entry in exports {
let Export {
name,
ref kind,
index,
} = entry?;
// The input has already been validated, so we should be able to
// assume valid UTF-8 and use `from_utf8_unchecked` if performance
// becomes a concern here.
let index = index as usize;
match *kind {
ExternalKind::Func => environ.declare_func_export(FuncIndex::new(index), name)?,
ExternalKind::Table => environ.declare_table_export(TableIndex::new(index), name)?,
ExternalKind::Memory => environ.declare_memory_export(MemoryIndex::new(index), name)?,
ExternalKind::Tag => environ.declare_tag_export(TagIndex::new(index), name)?,
ExternalKind::Global => environ.declare_global_export(GlobalIndex::new(index), name)?,
}
}
environ.finish_exports()?;
Ok(())
}
sourcefn reserve_table_elements(&mut self, _num: u32) -> WasmResult<()>
fn reserve_table_elements(&mut self, _num: u32) -> WasmResult<()>
Provides the number of element initializers up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
pub fn parse_element_section<'data>(
elements: ElementSectionReader<'data>,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_table_elements(elements.get_count())?;
for (index, entry) in elements.into_iter().enumerate() {
let Element {
kind,
items,
ty: _,
range: _,
} = entry?;
let segments = read_elems(&items)?;
match kind {
ElementKind::Active {
table_index,
offset_expr,
} => {
let mut offset_expr_reader = offset_expr.get_binary_reader();
let (base, offset) = match offset_expr_reader.read_operator()? {
Operator::I32Const { value } => (None, value as u32),
Operator::GlobalGet { global_index } => {
(Some(GlobalIndex::from_u32(global_index)), 0)
}
ref s => {
return Err(wasm_unsupported!(
"unsupported init expr in element section: {:?}",
s
));
}
};
environ.declare_table_elements(
TableIndex::from_u32(table_index),
base,
offset,
segments,
)?
}
ElementKind::Passive => {
let index = ElemIndex::from_u32(index as u32);
environ.declare_passive_element(index, segments)?;
}
ElementKind::Declared => {
environ.declare_elements(segments)?;
}
}
}
Ok(())
}
sourcefn declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()>
fn declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()>
Indicates that a declarative element segment was seen in the wasm module.
Examples found in repository?
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
pub fn parse_element_section<'data>(
elements: ElementSectionReader<'data>,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_table_elements(elements.get_count())?;
for (index, entry) in elements.into_iter().enumerate() {
let Element {
kind,
items,
ty: _,
range: _,
} = entry?;
let segments = read_elems(&items)?;
match kind {
ElementKind::Active {
table_index,
offset_expr,
} => {
let mut offset_expr_reader = offset_expr.get_binary_reader();
let (base, offset) = match offset_expr_reader.read_operator()? {
Operator::I32Const { value } => (None, value as u32),
Operator::GlobalGet { global_index } => {
(Some(GlobalIndex::from_u32(global_index)), 0)
}
ref s => {
return Err(wasm_unsupported!(
"unsupported init expr in element section: {:?}",
s
));
}
};
environ.declare_table_elements(
TableIndex::from_u32(table_index),
base,
offset,
segments,
)?
}
ElementKind::Passive => {
let index = ElemIndex::from_u32(index as u32);
environ.declare_passive_element(index, segments)?;
}
ElementKind::Declared => {
environ.declare_elements(segments)?;
}
}
}
Ok(())
}
sourcefn reserve_passive_data(&mut self, count: u32) -> WasmResult<()>
fn reserve_passive_data(&mut self, count: u32) -> WasmResult<()>
Provides the number of passive data segments up front.
By default this does nothing, but implementations may use this to pre-allocate memory if desired.
Examples found in repository?
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
pub fn translate_module<'data>(
data: &'data [u8],
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
let _tt = timing::wasm_translate_module();
let mut validator = Validator::new_with_features(environ.wasm_features());
for payload in Parser::new(0).parse_all(data) {
match payload? {
Payload::Version {
num,
encoding,
range,
} => {
validator.version(num, encoding, &range)?;
}
Payload::End(offset) => {
validator.end(offset)?;
}
Payload::TypeSection(types) => {
validator.type_section(&types)?;
parse_type_section(types, environ)?;
}
Payload::ImportSection(imports) => {
validator.import_section(&imports)?;
parse_import_section(imports, environ)?;
}
Payload::FunctionSection(functions) => {
validator.function_section(&functions)?;
parse_function_section(functions, environ)?;
}
Payload::TableSection(tables) => {
validator.table_section(&tables)?;
parse_table_section(tables, environ)?;
}
Payload::MemorySection(memories) => {
validator.memory_section(&memories)?;
parse_memory_section(memories, environ)?;
}
Payload::TagSection(tags) => {
validator.tag_section(&tags)?;
parse_tag_section(tags, environ)?;
}
Payload::GlobalSection(globals) => {
validator.global_section(&globals)?;
parse_global_section(globals, environ)?;
}
Payload::ExportSection(exports) => {
validator.export_section(&exports)?;
parse_export_section(exports, environ)?;
}
Payload::StartSection { func, range } => {
validator.start_section(func, &range)?;
parse_start_section(func, environ)?;
}
Payload::ElementSection(elements) => {
validator.element_section(&elements)?;
parse_element_section(elements, environ)?;
}
Payload::CodeSectionStart { count, range, .. } => {
validator.code_section_start(count, &range)?;
environ.reserve_function_bodies(count, range.start as u64);
}
Payload::CodeSectionEntry(body) => {
let func_validator = validator
.code_section_entry(&body)?
.into_validator(Default::default());
environ.define_function_body(func_validator, body)?;
}
Payload::DataSection(data) => {
validator.data_section(&data)?;
parse_data_section(data, environ)?;
}
Payload::DataCountSection { count, range } => {
validator.data_count_section(count, &range)?;
// NOTE: the count here is the total segment count, not the passive segment count
environ.reserve_passive_data(count)?;
}
Payload::CustomSection(s) if s.name() == "name" => {
let result = NameSectionReader::new(s.data(), s.data_offset())
.map_err(|e| e.into())
.and_then(|s| parse_name_section(s, environ));
if let Err(e) = result {
log::warn!("failed to parse name section {:?}", e);
}
}
Payload::CustomSection(s) => environ.custom_section(s.name(), s.data())?,
other => {
validator.payload(&other)?;
panic!("unimplemented section {:?}", other);
}
}
}
Ok(())
}
sourcefn reserve_function_bodies(&mut self, bodies: u32, code_section_offset: u64)
fn reserve_function_bodies(&mut self, bodies: u32, code_section_offset: u64)
Indicates how many functions the code section reports and the byte offset of where the code sections starts.
Examples found in repository?
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
pub fn translate_module<'data>(
data: &'data [u8],
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
let _tt = timing::wasm_translate_module();
let mut validator = Validator::new_with_features(environ.wasm_features());
for payload in Parser::new(0).parse_all(data) {
match payload? {
Payload::Version {
num,
encoding,
range,
} => {
validator.version(num, encoding, &range)?;
}
Payload::End(offset) => {
validator.end(offset)?;
}
Payload::TypeSection(types) => {
validator.type_section(&types)?;
parse_type_section(types, environ)?;
}
Payload::ImportSection(imports) => {
validator.import_section(&imports)?;
parse_import_section(imports, environ)?;
}
Payload::FunctionSection(functions) => {
validator.function_section(&functions)?;
parse_function_section(functions, environ)?;
}
Payload::TableSection(tables) => {
validator.table_section(&tables)?;
parse_table_section(tables, environ)?;
}
Payload::MemorySection(memories) => {
validator.memory_section(&memories)?;
parse_memory_section(memories, environ)?;
}
Payload::TagSection(tags) => {
validator.tag_section(&tags)?;
parse_tag_section(tags, environ)?;
}
Payload::GlobalSection(globals) => {
validator.global_section(&globals)?;
parse_global_section(globals, environ)?;
}
Payload::ExportSection(exports) => {
validator.export_section(&exports)?;
parse_export_section(exports, environ)?;
}
Payload::StartSection { func, range } => {
validator.start_section(func, &range)?;
parse_start_section(func, environ)?;
}
Payload::ElementSection(elements) => {
validator.element_section(&elements)?;
parse_element_section(elements, environ)?;
}
Payload::CodeSectionStart { count, range, .. } => {
validator.code_section_start(count, &range)?;
environ.reserve_function_bodies(count, range.start as u64);
}
Payload::CodeSectionEntry(body) => {
let func_validator = validator
.code_section_entry(&body)?
.into_validator(Default::default());
environ.define_function_body(func_validator, body)?;
}
Payload::DataSection(data) => {
validator.data_section(&data)?;
parse_data_section(data, environ)?;
}
Payload::DataCountSection { count, range } => {
validator.data_count_section(count, &range)?;
// NOTE: the count here is the total segment count, not the passive segment count
environ.reserve_passive_data(count)?;
}
Payload::CustomSection(s) if s.name() == "name" => {
let result = NameSectionReader::new(s.data(), s.data_offset())
.map_err(|e| e.into())
.and_then(|s| parse_name_section(s, environ));
if let Err(e) = result {
log::warn!("failed to parse name section {:?}", e);
}
}
Payload::CustomSection(s) => environ.custom_section(s.name(), s.data())?,
other => {
validator.payload(&other)?;
panic!("unimplemented section {:?}", other);
}
}
}
Ok(())
}
sourcefn reserve_data_initializers(&mut self, _num: u32) -> WasmResult<()>
fn reserve_data_initializers(&mut self, _num: u32) -> WasmResult<()>
Provides the number of data initializers up front. By default this does nothing, but implementations can use this to preallocate memory if desired.
Examples found in repository?
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
pub fn parse_data_section<'data>(
data: DataSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
environ.reserve_data_initializers(data.get_count())?;
for (index, entry) in data.into_iter().enumerate() {
let Data {
kind,
data,
range: _,
} = entry?;
match kind {
DataKind::Active {
memory_index,
offset_expr,
} => {
let mut offset_expr_reader = offset_expr.get_binary_reader();
let (base, offset) = match offset_expr_reader.read_operator()? {
Operator::I32Const { value } => (None, value as u64),
Operator::I64Const { value } => (None, value as u64),
Operator::GlobalGet { global_index } => {
(Some(GlobalIndex::from_u32(global_index)), 0)
}
ref s => {
return Err(wasm_unsupported!(
"unsupported init expr in data section: {:?}",
s
))
}
};
environ.declare_data_initialization(
MemoryIndex::from_u32(memory_index),
base,
offset,
data,
)?;
}
DataKind::Passive => {
let index = DataIndex::from_u32(index as u32);
environ.declare_passive_data(index, data)?;
}
}
}
Ok(())
}
sourcefn declare_module_name(&mut self, _name: &'data str)
fn declare_module_name(&mut self, _name: &'data str)
Declares the name of a module to the environment.
By default this does nothing, but implementations can use this to read the module name subsection of the custom name section if desired.
Examples found in repository?
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
pub fn parse_name_section<'data>(
names: NameSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
for subsection in names {
match subsection? {
wasmparser::Name::Function(names) => {
for name in names {
let Naming { index, name } = name?;
// We reserve `u32::MAX` for our own use in cranelift-entity.
if index != u32::max_value() {
environ.declare_func_name(FuncIndex::from_u32(index), name);
}
}
}
wasmparser::Name::Module { name, .. } => {
environ.declare_module_name(name);
}
wasmparser::Name::Local(reader) => {
for f in reader {
let f = f?;
if f.index == u32::max_value() {
continue;
}
for name in f.names {
let Naming { index, name } = name?;
environ.declare_local_name(FuncIndex::from_u32(f.index), index, name)
}
}
}
wasmparser::Name::Label(_)
| wasmparser::Name::Type(_)
| wasmparser::Name::Table(_)
| wasmparser::Name::Global(_)
| wasmparser::Name::Memory(_)
| wasmparser::Name::Element(_)
| wasmparser::Name::Data(_)
| wasmparser::Name::Unknown { .. } => {}
}
}
Ok(())
}
sourcefn declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str)
fn declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str)
Declares the name of a function to the environment.
By default this does nothing, but implementations can use this to read the function name subsection of the custom name section if desired.
Examples found in repository?
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
pub fn parse_name_section<'data>(
names: NameSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
for subsection in names {
match subsection? {
wasmparser::Name::Function(names) => {
for name in names {
let Naming { index, name } = name?;
// We reserve `u32::MAX` for our own use in cranelift-entity.
if index != u32::max_value() {
environ.declare_func_name(FuncIndex::from_u32(index), name);
}
}
}
wasmparser::Name::Module { name, .. } => {
environ.declare_module_name(name);
}
wasmparser::Name::Local(reader) => {
for f in reader {
let f = f?;
if f.index == u32::max_value() {
continue;
}
for name in f.names {
let Naming { index, name } = name?;
environ.declare_local_name(FuncIndex::from_u32(f.index), index, name)
}
}
}
wasmparser::Name::Label(_)
| wasmparser::Name::Type(_)
| wasmparser::Name::Table(_)
| wasmparser::Name::Global(_)
| wasmparser::Name::Memory(_)
| wasmparser::Name::Element(_)
| wasmparser::Name::Data(_)
| wasmparser::Name::Unknown { .. } => {}
}
}
Ok(())
}
sourcefn declare_local_name(
&mut self,
_func_index: FuncIndex,
_local_index: u32,
_name: &'data str
)
fn declare_local_name(
&mut self,
_func_index: FuncIndex,
_local_index: u32,
_name: &'data str
)
Declares the name of a function’s local to the environment.
By default this does nothing, but implementations can use this to read the local name subsection of the custom name section if desired.
Examples found in repository?
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
pub fn parse_name_section<'data>(
names: NameSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
for subsection in names {
match subsection? {
wasmparser::Name::Function(names) => {
for name in names {
let Naming { index, name } = name?;
// We reserve `u32::MAX` for our own use in cranelift-entity.
if index != u32::max_value() {
environ.declare_func_name(FuncIndex::from_u32(index), name);
}
}
}
wasmparser::Name::Module { name, .. } => {
environ.declare_module_name(name);
}
wasmparser::Name::Local(reader) => {
for f in reader {
let f = f?;
if f.index == u32::max_value() {
continue;
}
for name in f.names {
let Naming { index, name } = name?;
environ.declare_local_name(FuncIndex::from_u32(f.index), index, name)
}
}
}
wasmparser::Name::Label(_)
| wasmparser::Name::Type(_)
| wasmparser::Name::Table(_)
| wasmparser::Name::Global(_)
| wasmparser::Name::Memory(_)
| wasmparser::Name::Element(_)
| wasmparser::Name::Data(_)
| wasmparser::Name::Unknown { .. } => {}
}
}
Ok(())
}
sourcefn custom_section(
&mut self,
_name: &'data str,
_data: &'data [u8]
) -> WasmResult<()>
fn custom_section(
&mut self,
_name: &'data str,
_data: &'data [u8]
) -> WasmResult<()>
Indicates that a custom section has been found in the wasm file
Examples found in repository?
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
pub fn translate_module<'data>(
data: &'data [u8],
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
let _tt = timing::wasm_translate_module();
let mut validator = Validator::new_with_features(environ.wasm_features());
for payload in Parser::new(0).parse_all(data) {
match payload? {
Payload::Version {
num,
encoding,
range,
} => {
validator.version(num, encoding, &range)?;
}
Payload::End(offset) => {
validator.end(offset)?;
}
Payload::TypeSection(types) => {
validator.type_section(&types)?;
parse_type_section(types, environ)?;
}
Payload::ImportSection(imports) => {
validator.import_section(&imports)?;
parse_import_section(imports, environ)?;
}
Payload::FunctionSection(functions) => {
validator.function_section(&functions)?;
parse_function_section(functions, environ)?;
}
Payload::TableSection(tables) => {
validator.table_section(&tables)?;
parse_table_section(tables, environ)?;
}
Payload::MemorySection(memories) => {
validator.memory_section(&memories)?;
parse_memory_section(memories, environ)?;
}
Payload::TagSection(tags) => {
validator.tag_section(&tags)?;
parse_tag_section(tags, environ)?;
}
Payload::GlobalSection(globals) => {
validator.global_section(&globals)?;
parse_global_section(globals, environ)?;
}
Payload::ExportSection(exports) => {
validator.export_section(&exports)?;
parse_export_section(exports, environ)?;
}
Payload::StartSection { func, range } => {
validator.start_section(func, &range)?;
parse_start_section(func, environ)?;
}
Payload::ElementSection(elements) => {
validator.element_section(&elements)?;
parse_element_section(elements, environ)?;
}
Payload::CodeSectionStart { count, range, .. } => {
validator.code_section_start(count, &range)?;
environ.reserve_function_bodies(count, range.start as u64);
}
Payload::CodeSectionEntry(body) => {
let func_validator = validator
.code_section_entry(&body)?
.into_validator(Default::default());
environ.define_function_body(func_validator, body)?;
}
Payload::DataSection(data) => {
validator.data_section(&data)?;
parse_data_section(data, environ)?;
}
Payload::DataCountSection { count, range } => {
validator.data_count_section(count, &range)?;
// NOTE: the count here is the total segment count, not the passive segment count
environ.reserve_passive_data(count)?;
}
Payload::CustomSection(s) if s.name() == "name" => {
let result = NameSectionReader::new(s.data(), s.data_offset())
.map_err(|e| e.into())
.and_then(|s| parse_name_section(s, environ));
if let Err(e) = result {
log::warn!("failed to parse name section {:?}", e);
}
}
Payload::CustomSection(s) => environ.custom_section(s.name(), s.data())?,
other => {
validator.payload(&other)?;
panic!("unimplemented section {:?}", other);
}
}
}
Ok(())
}
sourcefn wasm_features(&self) -> WasmFeatures
fn wasm_features(&self) -> WasmFeatures
Returns the list of enabled wasm features this translation will be using.
Examples found in repository?
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
pub fn translate_module<'data>(
data: &'data [u8],
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
let _tt = timing::wasm_translate_module();
let mut validator = Validator::new_with_features(environ.wasm_features());
for payload in Parser::new(0).parse_all(data) {
match payload? {
Payload::Version {
num,
encoding,
range,
} => {
validator.version(num, encoding, &range)?;
}
Payload::End(offset) => {
validator.end(offset)?;
}
Payload::TypeSection(types) => {
validator.type_section(&types)?;
parse_type_section(types, environ)?;
}
Payload::ImportSection(imports) => {
validator.import_section(&imports)?;
parse_import_section(imports, environ)?;
}
Payload::FunctionSection(functions) => {
validator.function_section(&functions)?;
parse_function_section(functions, environ)?;
}
Payload::TableSection(tables) => {
validator.table_section(&tables)?;
parse_table_section(tables, environ)?;
}
Payload::MemorySection(memories) => {
validator.memory_section(&memories)?;
parse_memory_section(memories, environ)?;
}
Payload::TagSection(tags) => {
validator.tag_section(&tags)?;
parse_tag_section(tags, environ)?;
}
Payload::GlobalSection(globals) => {
validator.global_section(&globals)?;
parse_global_section(globals, environ)?;
}
Payload::ExportSection(exports) => {
validator.export_section(&exports)?;
parse_export_section(exports, environ)?;
}
Payload::StartSection { func, range } => {
validator.start_section(func, &range)?;
parse_start_section(func, environ)?;
}
Payload::ElementSection(elements) => {
validator.element_section(&elements)?;
parse_element_section(elements, environ)?;
}
Payload::CodeSectionStart { count, range, .. } => {
validator.code_section_start(count, &range)?;
environ.reserve_function_bodies(count, range.start as u64);
}
Payload::CodeSectionEntry(body) => {
let func_validator = validator
.code_section_entry(&body)?
.into_validator(Default::default());
environ.define_function_body(func_validator, body)?;
}
Payload::DataSection(data) => {
validator.data_section(&data)?;
parse_data_section(data, environ)?;
}
Payload::DataCountSection { count, range } => {
validator.data_count_section(count, &range)?;
// NOTE: the count here is the total segment count, not the passive segment count
environ.reserve_passive_data(count)?;
}
Payload::CustomSection(s) if s.name() == "name" => {
let result = NameSectionReader::new(s.data(), s.data_offset())
.map_err(|e| e.into())
.and_then(|s| parse_name_section(s, environ));
if let Err(e) = result {
log::warn!("failed to parse name section {:?}", e);
}
}
Payload::CustomSection(s) => environ.custom_section(s.name(), s.data())?,
other => {
validator.payload(&other)?;
panic!("unimplemented section {:?}", other);
}
}
}
Ok(())
}