Update wasm-tools dependencies (#4970)
* Update wasm-tools dependencies This update brings in a number of features such as: * The component model binary format and AST has been slightly adjusted in a few locations. Names are dropped from parameters/results now in the internal representation since they were not used anyway. At this time the ability to bind a multi-return function has not been exposed. * The `wasmparser` validator pass will now share allocations with prior functions, providing what's probably a very minor speedup for Wasmtime itself. * The text format for many component-related tests now requires named parameters. * Some new relaxed-simd instructions are updated to be ignored. I hope to have a follow-up to expose the multi-return ability to the embedding API of components. * Update audit information for new crates
This commit is contained in:
@@ -30,6 +30,7 @@ use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::mem;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use wasmparser::{FuncValidatorAllocations, FunctionBody};
|
||||
use wasmtime_environ::{
|
||||
AddressMapSection, CacheStore, CompileError, FilePos, FlagValue, FunctionBodyData,
|
||||
FunctionInfo, InstructionAddressMap, Module, ModuleTranslation, ModuleTypes, PtrSize,
|
||||
@@ -51,6 +52,7 @@ struct CompilerContext {
|
||||
func_translator: FuncTranslator,
|
||||
codegen_context: Context,
|
||||
incremental_cache_ctx: Option<IncrementalCacheContext>,
|
||||
validator_allocations: FuncValidatorAllocations,
|
||||
}
|
||||
|
||||
impl Default for CompilerContext {
|
||||
@@ -59,6 +61,7 @@ impl Default for CompilerContext {
|
||||
func_translator: FuncTranslator::new(),
|
||||
codegen_context: Context::new(),
|
||||
incremental_cache_ctx: None,
|
||||
validator_allocations: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,13 +144,13 @@ impl Compiler {
|
||||
fn get_function_address_map(
|
||||
&self,
|
||||
context: &Context,
|
||||
data: &FunctionBodyData<'_>,
|
||||
body: &FunctionBody<'_>,
|
||||
body_len: u32,
|
||||
tunables: &Tunables,
|
||||
) -> FunctionAddressMap {
|
||||
// Generate artificial srcloc for function start/end to identify boundary
|
||||
// within module.
|
||||
let data = data.body.get_binary_reader();
|
||||
let data = body.get_binary_reader();
|
||||
let offset = data.original_position();
|
||||
let len = data.bytes_remaining();
|
||||
assert!((offset + len) <= u32::max_value() as usize);
|
||||
@@ -186,7 +189,7 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
&self,
|
||||
translation: &ModuleTranslation<'_>,
|
||||
func_index: DefinedFuncIndex,
|
||||
mut input: FunctionBodyData<'_>,
|
||||
input: FunctionBodyData<'_>,
|
||||
tunables: &Tunables,
|
||||
types: &ModuleTypes,
|
||||
) -> Result<Box<dyn Any + Send>, CompileError> {
|
||||
@@ -198,6 +201,7 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
mut func_translator,
|
||||
codegen_context: mut context,
|
||||
incremental_cache_ctx: mut cache_ctx,
|
||||
validator_allocations,
|
||||
} = self.take_context();
|
||||
|
||||
context.func.signature = func_signature(isa, translation, types, func_index);
|
||||
@@ -264,9 +268,11 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
readonly: false,
|
||||
});
|
||||
context.func.stack_limit = Some(stack_limit);
|
||||
let FunctionBodyData { validator, body } = input;
|
||||
let mut validator = validator.into_validator(validator_allocations);
|
||||
func_translator.translate_body(
|
||||
&mut input.validator,
|
||||
input.body.clone(),
|
||||
&mut validator,
|
||||
body.clone(),
|
||||
&mut context.func,
|
||||
&mut func_env,
|
||||
)?;
|
||||
@@ -300,7 +306,7 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
};
|
||||
|
||||
let address_transform =
|
||||
self.get_function_address_map(&context, &input, code_buf.len() as u32, tunables);
|
||||
self.get_function_address_map(&context, &body, code_buf.len() as u32, tunables);
|
||||
|
||||
let ranges = if tunables.generate_native_debuginfo {
|
||||
Some(context.compiled_code().unwrap().value_labels_ranges.clone())
|
||||
@@ -320,6 +326,7 @@ impl wasmtime_environ::Compiler for Compiler {
|
||||
func_translator,
|
||||
codegen_context: context,
|
||||
incremental_cache_ctx: cache_ctx,
|
||||
validator_allocations: validator.into_allocations(),
|
||||
});
|
||||
|
||||
Ok(Box::new(CompiledFunction {
|
||||
@@ -566,6 +573,7 @@ impl Compiler {
|
||||
mut func_translator,
|
||||
codegen_context: mut context,
|
||||
incremental_cache_ctx: mut cache_ctx,
|
||||
validator_allocations,
|
||||
} = self.take_context();
|
||||
|
||||
// The name doesn't matter here.
|
||||
@@ -634,6 +642,7 @@ impl Compiler {
|
||||
func_translator,
|
||||
codegen_context: context,
|
||||
incremental_cache_ctx: cache_ctx,
|
||||
validator_allocations,
|
||||
});
|
||||
Ok(func)
|
||||
}
|
||||
@@ -679,6 +688,7 @@ impl Compiler {
|
||||
mut func_translator,
|
||||
codegen_context: mut context,
|
||||
incremental_cache_ctx: mut cache_ctx,
|
||||
validator_allocations,
|
||||
} = self.take_context();
|
||||
|
||||
// The name doesn't matter here.
|
||||
@@ -713,6 +723,7 @@ impl Compiler {
|
||||
func_translator,
|
||||
codegen_context: context,
|
||||
incremental_cache_ctx: cache_ctx,
|
||||
validator_allocations,
|
||||
});
|
||||
Ok(func)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ impl ComponentCompiler for Compiler {
|
||||
mut func_translator,
|
||||
codegen_context: mut context,
|
||||
mut incremental_cache_ctx,
|
||||
validator_allocations,
|
||||
} = self.take_context();
|
||||
|
||||
context.func = ir::Function::with_name_signature(
|
||||
@@ -156,6 +157,7 @@ impl ComponentCompiler for Compiler {
|
||||
func_translator,
|
||||
codegen_context: context,
|
||||
incremental_cache_ctx,
|
||||
validator_allocations,
|
||||
});
|
||||
Ok(Box::new(func))
|
||||
}
|
||||
@@ -166,6 +168,7 @@ impl ComponentCompiler for Compiler {
|
||||
mut func_translator,
|
||||
codegen_context: mut context,
|
||||
mut incremental_cache_ctx,
|
||||
validator_allocations,
|
||||
} = self.take_context();
|
||||
context.func = ir::Function::with_name_signature(
|
||||
ir::UserFuncName::user(0, 0),
|
||||
@@ -187,6 +190,7 @@ impl ComponentCompiler for Compiler {
|
||||
func_translator,
|
||||
codegen_context: context,
|
||||
incremental_cache_ctx,
|
||||
validator_allocations,
|
||||
});
|
||||
Ok(Box::new(func))
|
||||
}
|
||||
@@ -205,6 +209,7 @@ impl ComponentCompiler for Compiler {
|
||||
mut func_translator,
|
||||
codegen_context: mut context,
|
||||
mut incremental_cache_ctx,
|
||||
validator_allocations,
|
||||
} = self.take_context();
|
||||
|
||||
context.func = ir::Function::with_name_signature(
|
||||
@@ -226,6 +231,7 @@ impl ComponentCompiler for Compiler {
|
||||
func_translator,
|
||||
codegen_context: context,
|
||||
incremental_cache_ctx,
|
||||
validator_allocations,
|
||||
});
|
||||
Ok(Box::new(func))
|
||||
}
|
||||
|
||||
@@ -626,32 +626,6 @@ impl<'a, 'data> Translator<'a, 'data> {
|
||||
// Aliases of instance exports (either core or component) will be
|
||||
// recorded as an initializer of the appropriate type with outer
|
||||
// aliases handled specially via upvars and type processing.
|
||||
Payload::AliasSection(s) => {
|
||||
self.validator.alias_section(&s)?;
|
||||
for alias in s {
|
||||
let init = match alias? {
|
||||
wasmparser::Alias::InstanceExport {
|
||||
kind,
|
||||
instance_index,
|
||||
name,
|
||||
} => {
|
||||
let instance = ModuleInstanceIndex::from_u32(instance_index);
|
||||
self.alias_module_instance_export(kind, instance, name)
|
||||
}
|
||||
wasmparser::Alias::Outer {
|
||||
kind: wasmparser::OuterAliasKind::Type,
|
||||
count,
|
||||
index,
|
||||
} => {
|
||||
let index = TypeIndex::from_u32(index);
|
||||
let ty = self.types.core_outer_type(count, index);
|
||||
self.types.push_core_typedef(ty);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
self.result.initializers.push(init);
|
||||
}
|
||||
}
|
||||
Payload::ComponentAliasSection(s) => {
|
||||
self.validator.component_alias_section(&s)?;
|
||||
for alias in s {
|
||||
@@ -670,6 +644,14 @@ impl<'a, 'data> Translator<'a, 'data> {
|
||||
self.alias_component_outer(kind, count, index);
|
||||
continue;
|
||||
}
|
||||
wasmparser::ComponentAlias::CoreInstanceExport {
|
||||
kind,
|
||||
instance_index,
|
||||
name,
|
||||
} => {
|
||||
let instance = ModuleInstanceIndex::from_u32(instance_index);
|
||||
self.alias_module_instance_export(kind, instance, name)
|
||||
}
|
||||
};
|
||||
self.result.initializers.push(init);
|
||||
}
|
||||
|
||||
@@ -509,19 +509,14 @@ impl ComponentTypesBuilder {
|
||||
);
|
||||
assert!(prev.is_none());
|
||||
}
|
||||
wasmparser::ModuleTypeDeclaration::Alias(alias) => match alias {
|
||||
wasmparser::Alias::Outer {
|
||||
kind: wasmparser::OuterAliasKind::Type,
|
||||
count,
|
||||
index,
|
||||
} => {
|
||||
let ty = self.core_outer_type(*count, TypeIndex::from_u32(*index));
|
||||
self.push_core_typedef(ty);
|
||||
}
|
||||
wasmparser::Alias::InstanceExport { .. } => {
|
||||
unreachable!("invalid alias {alias:?}")
|
||||
}
|
||||
},
|
||||
wasmparser::ModuleTypeDeclaration::OuterAlias {
|
||||
kind: wasmparser::OuterAliasKind::Type,
|
||||
count,
|
||||
index,
|
||||
} => {
|
||||
let ty = self.core_outer_type(*count, TypeIndex::from_u32(*index));
|
||||
self.push_core_typedef(ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,12 +635,12 @@ impl ComponentTypesBuilder {
|
||||
params: ty
|
||||
.params
|
||||
.iter()
|
||||
.map(|(name, ty)| (name.map(|s| s.to_string()), self.valtype(ty)))
|
||||
.map(|(_name, ty)| self.valtype(ty))
|
||||
.collect(),
|
||||
results: ty
|
||||
.results
|
||||
.iter()
|
||||
.map(|(name, ty)| (name.map(|s| s.to_string()), self.valtype(ty)))
|
||||
.map(|(_name, ty)| self.valtype(ty))
|
||||
.collect(),
|
||||
};
|
||||
self.add_func_type(ty)
|
||||
@@ -998,9 +993,9 @@ pub struct TypeComponentInstance {
|
||||
pub struct TypeFunc {
|
||||
/// The list of optionally named parameters for this function, and their
|
||||
/// types.
|
||||
pub params: Box<[(Option<String>, InterfaceType)]>,
|
||||
pub params: Box<[InterfaceType]>,
|
||||
/// The return values of this function.
|
||||
pub results: Box<[(Option<String>, InterfaceType)]>,
|
||||
pub results: Box<[InterfaceType]>,
|
||||
}
|
||||
|
||||
/// All possible interface types that values can have.
|
||||
|
||||
@@ -37,7 +37,7 @@ impl ComponentTypesBuilder {
|
||||
let mut params = match self.flatten_types(
|
||||
&options.options,
|
||||
MAX_FLAT_PARAMS,
|
||||
ty.params.iter().map(|(_, ty)| *ty),
|
||||
ty.params.iter().copied(),
|
||||
) {
|
||||
Some(list) => list,
|
||||
None => {
|
||||
@@ -50,7 +50,7 @@ impl ComponentTypesBuilder {
|
||||
let results = match self.flatten_types(
|
||||
&options.options,
|
||||
MAX_FLAT_RESULTS,
|
||||
ty.results.iter().map(|(_, ty)| *ty),
|
||||
ty.results.iter().map(|ty| *ty),
|
||||
) {
|
||||
Some(list) => list,
|
||||
None => {
|
||||
|
||||
@@ -313,9 +313,9 @@ impl Compiler<'_, '_> {
|
||||
|
||||
fn translate_params(&mut self, adapter: &AdapterData, param_locals: &[(u32, ValType)]) {
|
||||
let src_tys = &self.types[adapter.lower.ty].params;
|
||||
let src_tys = src_tys.iter().map(|(_, ty)| *ty).collect::<Vec<_>>();
|
||||
let src_tys = src_tys.iter().copied().collect::<Vec<_>>();
|
||||
let dst_tys = &self.types[adapter.lift.ty].params;
|
||||
let dst_tys = dst_tys.iter().map(|(_, ty)| *ty).collect::<Vec<_>>();
|
||||
let dst_tys = dst_tys.iter().copied().collect::<Vec<_>>();
|
||||
let lift_opts = &adapter.lift.options;
|
||||
let lower_opts = &adapter.lower.options;
|
||||
|
||||
@@ -389,9 +389,9 @@ impl Compiler<'_, '_> {
|
||||
result_locals: &[(u32, ValType)],
|
||||
) {
|
||||
let src_tys = &self.types[adapter.lift.ty].results;
|
||||
let src_tys = src_tys.iter().map(|(_, ty)| *ty).collect::<Vec<_>>();
|
||||
let src_tys = src_tys.iter().map(|ty| *ty).collect::<Vec<_>>();
|
||||
let dst_tys = &self.types[adapter.lower.ty].results;
|
||||
let dst_tys = dst_tys.iter().map(|(_, ty)| *ty).collect::<Vec<_>>();
|
||||
let dst_tys = dst_tys.iter().map(|ty| *ty).collect::<Vec<_>>();
|
||||
let lift_opts = &adapter.lift.options;
|
||||
let lower_opts = &adapter.lower.options;
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ use std::convert::{TryFrom, TryInto};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use wasmparser::{
|
||||
CustomSectionReader, DataKind, ElementItem, ElementKind, Encoding, ExternalKind, FuncValidator,
|
||||
FunctionBody, NameSectionReader, Naming, Operator, Parser, Payload, Type, TypeRef, Validator,
|
||||
ValidatorResources,
|
||||
CustomSectionReader, DataKind, ElementItem, ElementKind, Encoding, ExternalKind,
|
||||
FuncToValidate, FunctionBody, NameSectionReader, Naming, Operator, Parser, Payload, Type,
|
||||
TypeRef, Validator, ValidatorResources,
|
||||
};
|
||||
|
||||
/// Object containing the standalone environment information.
|
||||
@@ -90,7 +90,7 @@ pub struct FunctionBodyData<'a> {
|
||||
/// The body of the function, containing code and locals.
|
||||
pub body: FunctionBody<'a>,
|
||||
/// Validator for the function body
|
||||
pub validator: FuncValidator<ValidatorResources>,
|
||||
pub validator: FuncToValidate<ValidatorResources>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
||||
@@ -325,7 +325,7 @@ mod tests {
|
||||
(import "" "make_refs" (func (;2;) (type 3)))
|
||||
(func (;3;) (type 1) (param externref externref externref externref externref externref externref externref externref externref)
|
||||
(local externref)
|
||||
loop ;; label = @1
|
||||
loop ;; label = @0
|
||||
call 0
|
||||
call 2
|
||||
call 1
|
||||
|
||||
@@ -129,15 +129,15 @@ impl TryFrom<wasmparser::FuncType> for WasmFuncType {
|
||||
type Error = WasmError;
|
||||
fn try_from(ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
|
||||
let params = ty
|
||||
.params
|
||||
.into_vec()
|
||||
.into_iter()
|
||||
.params()
|
||||
.iter()
|
||||
.copied()
|
||||
.map(WasmType::try_from)
|
||||
.collect::<Result<_, Self::Error>>()?;
|
||||
let returns = ty
|
||||
.returns
|
||||
.into_vec()
|
||||
.into_iter()
|
||||
.results()
|
||||
.iter()
|
||||
.copied()
|
||||
.map(WasmType::try_from)
|
||||
.collect::<Result<_, Self::Error>>()?;
|
||||
Ok(Self::new(params, returns))
|
||||
|
||||
@@ -246,10 +246,8 @@ impl Func {
|
||||
let data = &store[self.0];
|
||||
let ty = &data.types[data.ty];
|
||||
|
||||
Params::typecheck_named_list(&ty.params, &data.types)
|
||||
.context("type mismatch with parameters")?;
|
||||
Return::typecheck_named_list(&ty.results, &data.types)
|
||||
.context("type mismatch with results")?;
|
||||
Params::typecheck_list(&ty.params, &data.types).context("type mismatch with parameters")?;
|
||||
Return::typecheck_list(&ty.results, &data.types).context("type mismatch with results")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -260,7 +258,7 @@ impl Func {
|
||||
data.types[data.ty]
|
||||
.params
|
||||
.iter()
|
||||
.map(|(_, ty)| Type::from(ty, &data.types))
|
||||
.map(|ty| Type::from(ty, &data.types))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -270,7 +268,7 @@ impl Func {
|
||||
data.types[data.ty]
|
||||
.results
|
||||
.iter()
|
||||
.map(|(_, ty)| Type::from(ty, &data.types))
|
||||
.map(|ty| Type::from(ty, &data.types))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -89,16 +89,8 @@ impl HostFunc {
|
||||
func: Box::new(DynamicContext {
|
||||
func,
|
||||
types: Types {
|
||||
params: ty
|
||||
.params
|
||||
.iter()
|
||||
.map(|(_, ty)| Type::from(ty, types))
|
||||
.collect(),
|
||||
results: ty
|
||||
.results
|
||||
.iter()
|
||||
.map(|(_, ty)| Type::from(ty, types))
|
||||
.collect(),
|
||||
params: ty.params.iter().map(|ty| Type::from(ty, types)).collect(),
|
||||
results: ty.results.iter().map(|ty| Type::from(ty, types)).collect(),
|
||||
},
|
||||
}),
|
||||
})
|
||||
@@ -123,8 +115,8 @@ where
|
||||
R: ComponentNamedList + Lower,
|
||||
{
|
||||
let ty = &types[ty];
|
||||
P::typecheck_named_list(&ty.params, types).context("type mismatch with parameters")?;
|
||||
R::typecheck_named_list(&ty.results, types).context("type mismatch with results")?;
|
||||
P::typecheck_list(&ty.params, types).context("type mismatch with parameters")?;
|
||||
R::typecheck_list(&ty.results, types).context("type mismatch with results")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -308,10 +308,7 @@ pub unsafe trait ComponentNamedList: ComponentType {
|
||||
/// Performs a typecheck to ensure that this `ComponentNamedList`
|
||||
/// implementor matches the types of the types in `params`.
|
||||
#[doc(hidden)]
|
||||
fn typecheck_named_list(
|
||||
params: &[(Option<String>, InterfaceType)],
|
||||
types: &ComponentTypes,
|
||||
) -> Result<()>;
|
||||
fn typecheck_list(params: &[InterfaceType], types: &ComponentTypes) -> Result<()>;
|
||||
}
|
||||
|
||||
/// A trait representing types which can be passed to and read from components
|
||||
@@ -1965,14 +1962,14 @@ macro_rules! impl_component_ty_for_tuples {
|
||||
unsafe impl<$($t,)*> ComponentNamedList for ($($t,)*)
|
||||
where $($t: ComponentType),*
|
||||
{
|
||||
fn typecheck_named_list(
|
||||
names: &[(Option<String>, InterfaceType)],
|
||||
fn typecheck_list(
|
||||
names: &[InterfaceType],
|
||||
_types: &ComponentTypes,
|
||||
) -> Result<()> {
|
||||
if names.len() != $n {
|
||||
bail!("expected {} types, found {}", $n, names.len());
|
||||
}
|
||||
let mut names = names.iter().map(|i| &i.1);
|
||||
let mut names = names.iter();
|
||||
$($t::typecheck(names.next().unwrap(), _types)?;)*
|
||||
debug_assert!(names.next().is_none());
|
||||
Ok(())
|
||||
|
||||
@@ -590,7 +590,13 @@ impl Module {
|
||||
}
|
||||
}
|
||||
|
||||
engine.run_maybe_parallel(functions, |(mut validator, body)| validator.validate(&body))?;
|
||||
engine.run_maybe_parallel(functions, |(validator, body)| {
|
||||
// FIXME: it would be best here to use a rayon-specific parallel
|
||||
// iterator that maintains state-per-thread to share the function
|
||||
// validator allocations (`Default::default` here) across multiple
|
||||
// functions.
|
||||
validator.into_validator(Default::default()).validate(&body)
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user