cargo fmt

This commit is contained in:
Bo Yao
2021-04-21 16:06:12 -07:00
parent 4f220c474b
commit dadc81296a
222 changed files with 7728 additions and 2755 deletions

View File

@@ -75,16 +75,21 @@ pub fn run_basic_static_function(store: &Store, compiler_name: &str, c: &mut Cri
), ),
i32, i32,
> = dyn_f_many.native().unwrap(); > = dyn_f_many.native().unwrap();
c.bench_function(&format!("basic static func with many args {}", compiler_name), |b| { c.bench_function(
b.iter(|| { &format!("basic static func with many args {}", compiler_name),
let result = black_box( |b| {
f_many b.iter(|| {
.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) let result = black_box(
.unwrap(), f_many
); .call(
assert_eq!(result, 210); 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
}) )
}); .unwrap(),
);
assert_eq!(result, 210);
})
},
);
} }
pub fn run_basic_dynamic_function(store: &Store, compiler_name: &str, c: &mut Criterion) { pub fn run_basic_dynamic_function(store: &Store, compiler_name: &str, c: &mut Criterion) {
@@ -105,37 +110,40 @@ pub fn run_basic_dynamic_function(store: &Store, compiler_name: &str, c: &mut Cr
}); });
let dyn_f_many: &Function = instance.exports.get("add20").unwrap(); let dyn_f_many: &Function = instance.exports.get("add20").unwrap();
c.bench_function(&format!("basic dynfunc with many args {}", compiler_name), |b| { c.bench_function(
b.iter(|| { &format!("basic dynfunc with many args {}", compiler_name),
let dyn_result = black_box( |b| {
dyn_f_many b.iter(|| {
.call(&[ let dyn_result = black_box(
Val::I32(1), dyn_f_many
Val::I32(2), .call(&[
Val::I32(3), Val::I32(1),
Val::I32(4), Val::I32(2),
Val::I32(5), Val::I32(3),
Val::I32(6), Val::I32(4),
Val::I32(7), Val::I32(5),
Val::I32(8), Val::I32(6),
Val::I32(9), Val::I32(7),
Val::I32(10), Val::I32(8),
Val::I32(11), Val::I32(9),
Val::I32(12), Val::I32(10),
Val::I32(13), Val::I32(11),
Val::I32(14), Val::I32(12),
Val::I32(15), Val::I32(13),
Val::I32(16), Val::I32(14),
Val::I32(17), Val::I32(15),
Val::I32(18), Val::I32(16),
Val::I32(19), Val::I32(17),
Val::I32(20), Val::I32(18),
]) Val::I32(19),
.unwrap(), Val::I32(20),
); ])
assert_eq!(dyn_result[0], Val::I32(210)); .unwrap(),
}) );
}); assert_eq!(dyn_result[0], Val::I32(210));
})
},
);
} }
fn run_static_benchmarks(_c: &mut Criterion) { fn run_static_benchmarks(_c: &mut Criterion) {

View File

@@ -30,8 +30,11 @@ fn main() -> anyhow::Result<()> {
// Spectests test generation // Spectests test generation
{ {
let mut spectests = let mut spectests = Testsuite {
Testsuite { buffer: String::new(), path: vec![], ignores: ignores.clone() }; buffer: String::new(),
path: vec![],
ignores: ignores.clone(),
};
with_features(&mut spectests, &compilers, |mut spectests| { with_features(&mut spectests, &compilers, |mut spectests| {
with_test_module(&mut spectests, "spec", |spectests| { with_test_module(&mut spectests, "spec", |spectests| {
@@ -64,7 +67,11 @@ fn main() -> anyhow::Result<()> {
// Wasitest test generation // Wasitest test generation
{ {
let mut wasitests = Testsuite { buffer: String::new(), path: vec![], ignores }; let mut wasitests = Testsuite {
buffer: String::new(),
path: vec![],
ignores,
};
let wasi_versions = ["unstable", "snapshot1"]; let wasi_versions = ["unstable", "snapshot1"];
with_features(&mut wasitests, &compilers, |mut wasitests| { with_features(&mut wasitests, &compilers, |mut wasitests| {
with_test_module(&mut wasitests, "wasitests", |wasitests| { with_test_module(&mut wasitests, "wasitests", |wasitests| {

View File

@@ -87,7 +87,10 @@ fn main() -> anyhow::Result<()> {
// When we call a function it can either succeed or fail. We expect it to fail. // When we call a function it can either succeed or fail. We expect it to fail.
match run_func.call(1, 7) { match run_func.call(1, 7) {
Ok(result) => { Ok(result) => {
bail!("Expected early termination with `ExitCode`, found: {}", result); bail!(
"Expected early termination with `ExitCode`, found: {}",
result
);
} }
// In case of a failure, which we expect, we attempt to downcast the error into the error // In case of a failure, which we expect, we attempt to downcast the error into the error
// type that we were expecting. // type that we were expecting.

View File

@@ -59,7 +59,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// produce an error. // produce an error.
// //
// Let's get it. // Let's get it.
let div_by_zero = instance.exports.get_function("div_by_zero")?.native::<(), i32>()?; let div_by_zero = instance
.exports
.get_function("div_by_zero")?
.native::<(), i32>()?;
println!("Calling `div_by_zero` function..."); println!("Calling `div_by_zero` function...");
// Let's call the `div_by_zero` exported function. // Let's call the `div_by_zero` exported function.

View File

@@ -88,7 +88,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// //
// We will use an exported function for the `one` global // We will use an exported function for the `one` global
// and the Global API for `some`. // and the Global API for `some`.
let get_one = instance.exports.get_function("get_one")?.native::<(), f32>()?; let get_one = instance
.exports
.get_function("get_one")?
.native::<(), f32>()?;
let one_value = get_one.call()?; let one_value = get_one.call()?;
let some_value = some.get(); let some_value = some.get();
@@ -117,7 +120,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// 2. Using the Global API directly. // 2. Using the Global API directly.
// //
// We will use both for the `some` global. // We will use both for the `some` global.
let set_some = instance.exports.get_function("set_some")?.native::<f32, ()>()?; let set_some = instance
.exports
.get_function("set_some")?
.native::<f32, ()>()?;
set_some.call(21.0)?; set_some.call(21.0)?;
let some_result = some.get(); let some_result = some.get();
println!("`some` value after `set_some`: {:?}", some_result); println!("`some` value after `set_some`: {:?}", some_result);

View File

@@ -50,7 +50,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Let's instantiate the Wasm module. // Let's instantiate the Wasm module.
let instance = Instance::new(&module, &import_object)?; let instance = Instance::new(&module, &import_object)?;
let load = instance.exports.get_native_function::<(), (WasmPtr<u8, Array>, i32)>("load")?; let load = instance
.exports
.get_native_function::<(), (WasmPtr<u8, Array>, i32)>("load")?;
// Here we go. // Here we go.
// //

View File

@@ -59,8 +59,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// covered in more detail in other examples. // covered in more detail in other examples.
println!("Creating the imported function..."); println!("Creating the imported function...");
let host_function_signature = FunctionType::new(vec![], vec![Type::I32]); let host_function_signature = FunctionType::new(vec![], vec![Type::I32]);
let host_function = let host_function = Function::new(&store, &host_function_signature, |_args| {
Function::new(&store, &host_function_signature, |_args| Ok(vec![Value::I32(42)])); Ok(vec![Value::I32(42)])
});
println!("Creating the imported global..."); println!("Creating the imported global...");
let host_global = Global::new(&store, Value::I32(42)); let host_global = Global::new(&store, Value::I32(42));

View File

@@ -85,7 +85,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Here we go. // Here we go.
// //
// The Wasm module exports a function called `sum`. Let's get it. // The Wasm module exports a function called `sum`. Let's get it.
let sum = instance.exports.get_function("sum")?.native::<(i32, i32), i32>()?; let sum = instance
.exports
.get_function("sum")?
.native::<(i32, i32), i32>()?;
println!("Calling `sum` function..."); println!("Calling `sum` function...");
// Let's call the `sum` exported function. It will call each // Let's call the `sum` exported function. It will call each

View File

@@ -100,8 +100,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Here we go. // Here we go.
// //
// The Wasm module exports a function called `increment_counter_loop`. Let's get it. // The Wasm module exports a function called `increment_counter_loop`. Let's get it.
let increment_counter_loop = let increment_counter_loop = instance
instance.exports.get_function("increment_counter_loop")?.native::<i32, i32>()?; .exports
.get_function("increment_counter_loop")?
.native::<i32, i32>()?;
let counter_value: i32 = *shared_counter.lock().unwrap(); let counter_value: i32 = *shared_counter.lock().unwrap();
println!("Initial ounter value: {:?}", counter_value); println!("Initial ounter value: {:?}", counter_value);

View File

@@ -65,8 +65,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// //
// The Wasm module only imports some globals. We'll have to interact // The Wasm module only imports some globals. We'll have to interact
// with them either using the Global API or exported functions. // with them either using the Global API or exported functions.
let get_some = instance.exports.get_function("get_some")?.native::<(), f32>()?; let get_some = instance
let get_other = instance.exports.get_function("get_other")?.native::<(), f32>()?; .exports
.get_function("get_some")?
.native::<(), f32>()?;
let get_other = instance
.exports
.get_function("get_other")?
.native::<(), f32>()?;
let some_result = get_some.call()?; let some_result = get_some.call()?;
let other_result = get_other.call()?; let other_result = get_other.call()?;
@@ -96,7 +102,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Altering global values through exported functions..."); println!("Altering global values through exported functions...");
// Changes made to global through exported functions will // Changes made to global through exported functions will
// be reflected on the host side. // be reflected on the host side.
let set_other = instance.exports.get_function("set_other")?.native::<f32, ()>()?; let set_other = instance
.exports
.get_function("set_other")?
.native::<f32, ()>()?;
set_other.call(42.0)?; set_other.call(42.0)?;
println!("other value (via Global API): {:?}", other.get()); println!("other value (via Global API): {:?}", other.get());

View File

@@ -60,7 +60,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Here we are retrieving the exported function. We won't go into details here // Here we are retrieving the exported function. We won't go into details here
// as the main focus of this example is to show how to create an instance out // as the main focus of this example is to show how to create an instance out
// of a Wasm module and have basic interactions with it. // of a Wasm module and have basic interactions with it.
let add_one = instance.exports.get_function("add_one")?.native::<i32, i32>()?; let add_one = instance
.exports
.get_function("add_one")?
.native::<i32, i32>()?;
println!("Calling `add_one` function..."); println!("Calling `add_one` function...");
let result = add_one.call(1)?; let result = add_one.call(1)?;

View File

@@ -87,7 +87,10 @@ fn main() -> anyhow::Result<()> {
// //
// Our module exports a single `add_one` function. We want to // Our module exports a single `add_one` function. We want to
// measure the cost of executing this function. // measure the cost of executing this function.
let add_one = instance.exports.get_function("add_one")?.native::<i32, i32>()?; let add_one = instance
.exports
.get_function("add_one")?
.native::<i32, i32>()?;
println!("Calling `add_one` function once..."); println!("Calling `add_one` function once...");
add_one.call(1)?; add_one.call(1)?;
@@ -99,9 +102,15 @@ fn main() -> anyhow::Result<()> {
// * `i32.const` is a `Operator::I32Const` which costs 1 point; // * `i32.const` is a `Operator::I32Const` which costs 1 point;
// * `i32.add` is a `Operator::I32Add` which costs 2 points. // * `i32.add` is a `Operator::I32Add` which costs 2 points.
let remaining_points_after_first_call = get_remaining_points(&instance); let remaining_points_after_first_call = get_remaining_points(&instance);
assert_eq!(remaining_points_after_first_call, MeteringPoints::Remaining(6)); assert_eq!(
remaining_points_after_first_call,
MeteringPoints::Remaining(6)
);
println!("Remaining points after the first call: {:?}", remaining_points_after_first_call); println!(
"Remaining points after the first call: {:?}",
remaining_points_after_first_call
);
println!("Calling `add_one` function twice..."); println!("Calling `add_one` function twice...");
add_one.call(1)?; add_one.call(1)?;
@@ -109,9 +118,15 @@ fn main() -> anyhow::Result<()> {
// We spent 4 more points with the second call. // We spent 4 more points with the second call.
// We have 2 remaining points. // We have 2 remaining points.
let remaining_points_after_second_call = get_remaining_points(&instance); let remaining_points_after_second_call = get_remaining_points(&instance);
assert_eq!(remaining_points_after_second_call, MeteringPoints::Remaining(2)); assert_eq!(
remaining_points_after_second_call,
MeteringPoints::Remaining(2)
);
println!("Remaining points after the second call: {:?}", remaining_points_after_second_call); println!(
"Remaining points after the second call: {:?}",
remaining_points_after_second_call
);
// Because calling our `add_one` function consumes 4 points, // Because calling our `add_one` function consumes 4 points,
// calling it a third time will fail: we already consume 8 // calling it a third time will fail: we already consume 8
@@ -119,7 +134,10 @@ fn main() -> anyhow::Result<()> {
println!("Calling `add_one` function a third time..."); println!("Calling `add_one` function a third time...");
match add_one.call(1) { match add_one.call(1) {
Ok(result) => { Ok(result) => {
bail!("Expected failure while calling `add_one`, found: {}", result); bail!(
"Expected failure while calling `add_one`, found: {}",
result
);
} }
Err(_) => { Err(_) => {
println!("Calling `add_one` failed."); println!("Calling `add_one` failed.");

View File

@@ -74,7 +74,14 @@ fn main() -> anyhow::Result<()> {
let guest_table = instance.exports.get_table("__indirect_function_table")?; let guest_table = instance.exports.get_table("__indirect_function_table")?;
// And demonstrate that it has the properties that we set in the Wasm. // And demonstrate that it has the properties that we set in the Wasm.
assert_eq!(guest_table.size(), 3); assert_eq!(guest_table.size(), 3);
assert_eq!(guest_table.ty(), &TableType { ty: Type::FuncRef, minimum: 3, maximum: Some(6) }); assert_eq!(
guest_table.ty(),
&TableType {
ty: Type::FuncRef,
minimum: 3,
maximum: Some(6)
}
);
// == Setting elements in a table == // == Setting elements in a table ==
@@ -101,7 +108,14 @@ fn main() -> anyhow::Result<()> {
assert_eq!(previous_size, 3); assert_eq!(previous_size, 3);
assert_eq!(guest_table.size(), 6); assert_eq!(guest_table.size(), 6);
assert_eq!(guest_table.ty(), &TableType { ty: Type::FuncRef, minimum: 3, maximum: Some(6) }); assert_eq!(
guest_table.ty(),
&TableType {
ty: Type::FuncRef,
minimum: 3,
maximum: Some(6)
}
);
// Now demonstrate that the function we grew the table with is actually in the table. // Now demonstrate that the function we grew the table with is actually in the table.
for table_index in 3..6 { for table_index in 3..6 {
if let Value::FuncRef(Some(f)) = guest_table.get(table_index as _).unwrap() { if let Value::FuncRef(Some(f)) = guest_table.get(table_index as _).unwrap() {

View File

@@ -105,7 +105,8 @@ impl<T: Tunables> Tunables for LimitingTunables<T> {
) -> Result<Arc<dyn vm::Memory>, MemoryError> { ) -> Result<Arc<dyn vm::Memory>, MemoryError> {
let adjusted = self.adjust_memory(ty); let adjusted = self.adjust_memory(ty);
self.validate_memory(&adjusted)?; self.validate_memory(&adjusted)?;
self.base.create_vm_memory(&adjusted, style, vm_definition_location) self.base
.create_vm_memory(&adjusted, style, vm_definition_location)
} }
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`]. /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
@@ -163,8 +164,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let instance = Instance::new(&module, &import_object)?; let instance = Instance::new(&module, &import_object)?;
// Check what happened // Check what happened
let mut memories: Vec<Memory> = let mut memories: Vec<Memory> = instance
instance.exports.iter().memories().map(|pair| pair.1.clone()).collect(); .exports
.iter()
.memories()
.map(|pair| pair.1.clone())
.collect();
assert_eq!(memories.len(), 1); assert_eq!(memories.len(), 1);
let first_memory = memories.pop().unwrap(); let first_memory = memories.pop().unwrap();

View File

@@ -21,8 +21,10 @@ use wasmer_engine_jit::JIT;
use wasmer_wasi::WasiState; use wasmer_wasi::WasiState;
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let wasm_path = let wasm_path = concat!(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/wasi-wast/wasi/unstable/hello.wasm"); env!("CARGO_MANIFEST_DIR"),
"/tests/wasi-wast/wasi/unstable/hello.wasm"
);
// Let's declare the Wasm module with the text representation. // Let's declare the Wasm module with the text representation.
let wasm_bytes = std::fs::read(wasm_path)?; let wasm_bytes = std::fs::read(wasm_path)?;

View File

@@ -17,8 +17,10 @@ use wasmer_engine_jit::JIT;
use wasmer_wasi::{Pipe, WasiState}; use wasmer_wasi::{Pipe, WasiState};
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let wasm_path = let wasm_path = concat!(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/wasi-wast/wasi/unstable/pipe_reverse.wasm"); env!("CARGO_MANIFEST_DIR"),
"/tests/wasi-wast/wasi/unstable/pipe_reverse.wasm"
);
// Let's declare the Wasm module with the text representation. // Let's declare the Wasm module with the text representation.
let wasm_bytes = std::fs::read(wasm_path)?; let wasm_bytes = std::fs::read(wasm_path)?;
@@ -36,8 +38,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// First, we create the `WasiEnv` with the stdio pipes // First, we create the `WasiEnv` with the stdio pipes
let input = Pipe::new(); let input = Pipe::new();
let output = Pipe::new(); let output = Pipe::new();
let mut wasi_env = let mut wasi_env = WasiState::new("hello")
WasiState::new("hello").stdin(Box::new(input)).stdout(Box::new(output)).finalize()?; .stdin(Box::new(input))
.stdout(Box::new(output))
.finalize()?;
println!("Instantiating module with WASI imports..."); println!("Instantiating module with WASI imports...");
// Then, we get the import object related to our WASI // Then, we get the import object related to our WASI

View File

@@ -140,7 +140,10 @@ pub struct LazyInit<T: Sized> {
impl<T> LazyInit<T> { impl<T> LazyInit<T> {
/// Creates an unitialized value. /// Creates an unitialized value.
pub fn new() -> Self { pub fn new() -> Self {
Self { data: std::mem::MaybeUninit::uninit(), initialized: false } Self {
data: std::mem::MaybeUninit::uninit(),
initialized: false,
}
} }
/// # Safety /// # Safety
@@ -173,16 +176,24 @@ impl<T> LazyInit<T> {
impl<T: std::fmt::Debug> std::fmt::Debug for LazyInit<T> { impl<T: std::fmt::Debug> std::fmt::Debug for LazyInit<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("LazyInit").field("data", &self.get_ref()).finish() f.debug_struct("LazyInit")
.field("data", &self.get_ref())
.finish()
} }
} }
impl<T: Clone> Clone for LazyInit<T> { impl<T: Clone> Clone for LazyInit<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
if let Some(inner) = self.get_ref() { if let Some(inner) = self.get_ref() {
Self { data: std::mem::MaybeUninit::new(inner.clone()), initialized: true } Self {
data: std::mem::MaybeUninit::new(inner.clone()),
initialized: true,
}
} else { } else {
Self { data: std::mem::MaybeUninit::uninit(), initialized: false } Self {
data: std::mem::MaybeUninit::uninit(),
initialized: false,
}
} }
} }
} }

View File

@@ -75,7 +75,9 @@ impl Exports {
/// Creates a new `Exports` with capacity `n`. /// Creates a new `Exports` with capacity `n`.
pub fn with_capacity(n: usize) -> Self { pub fn with_capacity(n: usize) -> Self {
Self { map: Arc::new(IndexMap::with_capacity(n)) } Self {
map: Arc::new(IndexMap::with_capacity(n)),
}
} }
/// Return the number of exports in the `Exports` map. /// Return the number of exports in the `Exports` map.
@@ -94,7 +96,9 @@ impl Exports {
S: Into<String>, S: Into<String>,
E: Into<Extern>, E: Into<Extern>,
{ {
Arc::get_mut(&mut self.map).unwrap().insert(name.into(), value.into()); Arc::get_mut(&mut self.map)
.unwrap()
.insert(name.into(), value.into());
} }
/// Get an export given a `name`. /// Get an export given a `name`.
@@ -144,7 +148,9 @@ impl Exports {
Args: WasmTypeList, Args: WasmTypeList,
Rets: WasmTypeList, Rets: WasmTypeList,
{ {
self.get_function(name)?.native().map_err(|_| ExportError::IncompatibleType) self.get_function(name)?
.native()
.map_err(|_| ExportError::IncompatibleType)
} }
/// Hack to get this working with nativefunc too /// Hack to get this working with nativefunc too
@@ -175,7 +181,9 @@ impl Exports {
/// Get an iterator over the exports. /// Get an iterator over the exports.
pub fn iter(&self) -> ExportsIterator<impl Iterator<Item = (&String, &Extern)>> { pub fn iter(&self) -> ExportsIterator<impl Iterator<Item = (&String, &Extern)>> {
ExportsIterator { iter: self.map.iter() } ExportsIterator {
iter: self.map.iter(),
}
} }
} }
@@ -252,7 +260,9 @@ where
impl FromIterator<(String, Extern)> for Exports { impl FromIterator<(String, Extern)> for Exports {
fn from_iter<I: IntoIterator<Item = (String, Extern)>>(iter: I) -> Self { fn from_iter<I: IntoIterator<Item = (String, Extern)>>(iter: I) -> Self {
Self { map: Arc::new(IndexMap::from_iter(iter)) } Self {
map: Arc::new(IndexMap::from_iter(iter)),
}
} }
} }
@@ -262,7 +272,10 @@ impl LikeNamespace for Exports {
} }
fn get_namespace_exports(&self) -> Vec<(String, Export)> { fn get_namespace_exports(&self) -> Vec<(String, Export)> {
self.map.iter().map(|(k, v)| (k.clone(), v.to_export())).collect() self.map
.iter()
.map(|(k, v)| (k.clone(), v.to_export()))
.collect()
} }
} }

View File

@@ -109,7 +109,9 @@ where
}); });
let host_env_clone_fn = |ptr: *mut c_void| -> *mut c_void { let host_env_clone_fn = |ptr: *mut c_void| -> *mut c_void {
let env_ref: &Env = unsafe { let env_ref: &Env = unsafe {
ptr.cast::<Env>().as_ref().expect("`ptr` to the environment is null when cloning it") ptr.cast::<Env>()
.as_ref()
.expect("`ptr` to the environment is null when cloning it")
}; };
Box::into_raw(Box::new(env_ref.clone())) as _ Box::into_raw(Box::new(env_ref.clone())) as _
}; };
@@ -350,7 +352,9 @@ impl Function {
} }
let function = inner::Function::<Args, Rets>::new(func); let function = inner::Function::<Args, Rets>::new(func);
let address = function.address() as *const VMFunctionBody; let address = function.address() as *const VMFunctionBody;
let vmctx = VMFunctionEnvironment { host_env: std::ptr::null_mut() as *mut _ }; let vmctx = VMFunctionEnvironment {
host_env: std::ptr::null_mut() as *mut _,
};
let signature = function.ty(); let signature = function.ty();
Self { Self {
@@ -513,7 +517,11 @@ impl Function {
results: &mut [Val], results: &mut [Val],
) -> Result<(), RuntimeError> { ) -> Result<(), RuntimeError> {
let format_types_for_error_message = |items: &[Val]| { let format_types_for_error_message = |items: &[Val]| {
items.iter().map(|param| param.ty().to_string()).collect::<Vec<String>>().join(", ") items
.iter()
.map(|param| param.ty().to_string())
.collect::<Vec<String>>()
.join(", ")
}; };
let signature = self.ty(); let signature = self.ty();
if signature.params().len() != params.len() { if signature.params().len() != params.len() {
@@ -790,7 +798,11 @@ impl Function {
} }
} }
Ok(NativeFunc::new(self.store.clone(), self.exported.clone(), self.definition.clone())) Ok(NativeFunc::new(
self.store.clone(),
self.exported.clone(),
self.definition.clone(),
))
} }
#[track_caller] #[track_caller]
@@ -814,7 +826,10 @@ impl<'a> Exportable<'a> for Function {
impl fmt::Debug for Function { impl fmt::Debug for Function {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.debug_struct("Function").field("ty", &self.ty()).finish() formatter
.debug_struct("Function")
.field("ty", &self.ty())
.finish()
} }
} }
@@ -890,7 +905,10 @@ trait VMDynamicFunctionCall<T: VMDynamicFunction> {
impl<T: VMDynamicFunction> VMDynamicFunctionCall<T> for VMDynamicFunctionContext<T> { impl<T: VMDynamicFunction> VMDynamicFunctionCall<T> for VMDynamicFunctionContext<T> {
fn from_context(ctx: T) -> Self { fn from_context(ctx: T) -> Self {
Self { address: Self::address_ptr(), ctx } Self {
address: Self::address_ptr(),
ctx,
}
} }
fn address_ptr() -> *const VMFunctionBody { fn address_ptr() -> *const VMFunctionBody {
@@ -1294,7 +1312,10 @@ mod inner {
T: HostFunctionKind, T: HostFunctionKind,
E: Sized, E: Sized,
{ {
Self { address: function.function_body_ptr(), _phantom: PhantomData } Self {
address: function.function_body_ptr(),
_phantom: PhantomData,
}
} }
/// Get the function type of this `Function`. /// Get the function type of this `Function`.
@@ -1713,8 +1734,14 @@ mod inner {
#[test] #[test]
fn test_function_types() { fn test_function_types() {
assert_eq!(Function::new(func).ty(), FunctionType::new(vec![], vec![])); assert_eq!(Function::new(func).ty(), FunctionType::new(vec![], vec![]));
assert_eq!(Function::new(func__i32).ty(), FunctionType::new(vec![], vec![Type::I32])); assert_eq!(
assert_eq!(Function::new(func_i32).ty(), FunctionType::new(vec![Type::I32], vec![])); Function::new(func__i32).ty(),
FunctionType::new(vec![], vec![Type::I32])
);
assert_eq!(
Function::new(func_i32).ty(),
FunctionType::new(vec![Type::I32], vec![])
);
assert_eq!( assert_eq!(
Function::new(func_i32__i32).ty(), Function::new(func_i32__i32).ty(),
FunctionType::new(vec![Type::I32], vec![Type::I32]) FunctionType::new(vec![Type::I32], vec![Type::I32])

View File

@@ -63,14 +63,20 @@ impl Global {
if !val.comes_from_same_store(store) { if !val.comes_from_same_store(store) {
return Err(RuntimeError::new("cross-`Store` globals are not supported")); return Err(RuntimeError::new("cross-`Store` globals are not supported"));
} }
let global = RuntimeGlobal::new(GlobalType { mutability, ty: val.ty() }); let global = RuntimeGlobal::new(GlobalType {
mutability,
ty: val.ty(),
});
unsafe { unsafe {
global global
.set_unchecked(val.clone()) .set_unchecked(val.clone())
.map_err(|e| RuntimeError::new(format!("create global for {:?}: {}", val, e)))?; .map_err(|e| RuntimeError::new(format!("create global for {:?}: {}", val, e)))?;
}; };
Ok(Self { store: store.clone(), global: Arc::new(global) }) Ok(Self {
store: store.clone(),
global: Arc::new(global),
})
} }
/// Returns the [`GlobalType`] of the `Global`. /// Returns the [`GlobalType`] of the `Global`.
@@ -169,13 +175,18 @@ impl Global {
return Err(RuntimeError::new("cross-`Store` values are not supported")); return Err(RuntimeError::new("cross-`Store` values are not supported"));
} }
unsafe { unsafe {
self.global.set(val).map_err(|e| RuntimeError::new(format!("{}", e)))?; self.global
.set(val)
.map_err(|e| RuntimeError::new(format!("{}", e)))?;
} }
Ok(()) Ok(())
} }
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportGlobal) -> Self { pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportGlobal) -> Self {
Self { store: store.clone(), global: wasmer_export.vm_global.from } Self {
store: store.clone(),
global: wasmer_export.vm_global.from,
}
} }
/// Returns whether or not these two globals refer to the same data. /// Returns whether or not these two globals refer to the same data.
@@ -207,8 +218,13 @@ impl fmt::Debug for Global {
impl<'a> Exportable<'a> for Global { impl<'a> Exportable<'a> for Global {
fn to_export(&self) -> Export { fn to_export(&self) -> Export {
ExportGlobal { vm_global: VMExportGlobal { from: self.global.clone(), instance_ref: None } } ExportGlobal {
.into() vm_global: VMExportGlobal {
from: self.global.clone(),
instance_ref: None,
},
}
.into()
} }
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> { fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {

View File

@@ -49,7 +49,10 @@ impl Memory {
let style = tunables.memory_style(&ty); let style = tunables.memory_style(&ty);
let memory = tunables.create_host_memory(&ty, &style)?; let memory = tunables.create_host_memory(&ty, &style)?;
Ok(Self { store: store.clone(), memory }) Ok(Self {
store: store.clone(),
memory,
})
} }
/// Returns the [`MemoryType`] of the `Memory`. /// Returns the [`MemoryType`] of the `Memory`.
@@ -219,7 +222,10 @@ impl Memory {
} }
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportMemory) -> Self { pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportMemory) -> Self {
Self { store: store.clone(), memory: wasmer_export.vm_memory.from } Self {
store: store.clone(),
memory: wasmer_export.vm_memory.from,
}
} }
/// Returns whether or not these two memories refer to the same data. /// Returns whether or not these two memories refer to the same data.
@@ -241,8 +247,13 @@ impl Memory {
impl<'a> Exportable<'a> for Memory { impl<'a> Exportable<'a> for Memory {
fn to_export(&self) -> Export { fn to_export(&self) -> Export {
ExportMemory { vm_memory: VMExportMemory { from: self.memory.clone(), instance_ref: None } } ExportMemory {
.into() vm_memory: VMExportMemory {
from: self.memory.clone(),
instance_ref: None,
},
}
.into()
} }
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> { fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {

View File

@@ -43,14 +43,19 @@ impl Table {
let item = init.into_table_reference(store)?; let item = init.into_table_reference(store)?;
let tunables = store.tunables(); let tunables = store.tunables();
let style = tunables.table_style(&ty); let style = tunables.table_style(&ty);
let table = tunables.create_host_table(&ty, &style).map_err(RuntimeError::new)?; let table = tunables
.create_host_table(&ty, &style)
.map_err(RuntimeError::new)?;
let num_elements = table.size(); let num_elements = table.size();
for i in 0..num_elements { for i in 0..num_elements {
set_table_item(table.as_ref(), i, item.clone())?; set_table_item(table.as_ref(), i, item.clone())?;
} }
Ok(Self { store: store.clone(), table }) Ok(Self {
store: store.clone(),
table,
})
} }
/// Returns the [`TableType`] of the `Table`. /// Returns the [`TableType`] of the `Table`.
@@ -111,7 +116,9 @@ impl Table {
len: u32, len: u32,
) -> Result<(), RuntimeError> { ) -> Result<(), RuntimeError> {
if !Store::same(&dst_table.store, &src_table.store) { if !Store::same(&dst_table.store, &src_table.store) {
return Err(RuntimeError::new("cross-`Store` table copies are not supported")); return Err(RuntimeError::new(
"cross-`Store` table copies are not supported",
));
} }
RuntimeTable::copy( RuntimeTable::copy(
dst_table.table.as_ref(), dst_table.table.as_ref(),
@@ -125,7 +132,10 @@ impl Table {
} }
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportTable) -> Self { pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportTable) -> Self {
Self { store: store.clone(), table: wasmer_export.vm_table.from } Self {
store: store.clone(),
table: wasmer_export.vm_table.from,
}
} }
/// Returns whether or not these two tables refer to the same data. /// Returns whether or not these two tables refer to the same data.
@@ -136,8 +146,13 @@ impl Table {
impl<'a> Exportable<'a> for Table { impl<'a> Exportable<'a> for Table {
fn to_export(&self) -> Export { fn to_export(&self) -> Export {
ExportTable { vm_table: VMExportTable { from: self.table.clone(), instance_ref: None } } ExportTable {
.into() vm_table: VMExportTable {
from: self.table.clone(),
instance_ref: None,
},
}
.into()
} }
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> { fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {

View File

@@ -137,7 +137,9 @@ impl IntoIterator for ImportObject {
type Item = ((String, String), Export); type Item = ((String, String), Export);
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
ImportObjectIterator { elements: self.get_objects() } ImportObjectIterator {
elements: self.get_objects(),
}
} }
} }
@@ -168,7 +170,10 @@ impl fmt::Debug for ImportObject {
} }
f.debug_struct("ImportObject") f.debug_struct("ImportObject")
.field("map", &SecretMap::new(self.map.lock().unwrap().borrow().len())) .field(
"map",
&SecretMap::new(self.map.lock().unwrap().borrow().len()),
)
.finish() .finish()
} }
} }

View File

@@ -125,8 +125,11 @@ impl Instance {
}) })
.collect::<Exports>(); .collect::<Exports>();
let instance = let instance = Self {
Self { handle: Arc::new(Mutex::new(handle)), module: module.clone(), exports }; handle: Arc::new(Mutex::new(handle)),
module: module.clone(),
exports,
};
// # Safety // # Safety
// `initialize_host_envs` should be called after instantiation but before // `initialize_host_envs` should be called after instantiation but before
@@ -165,6 +168,8 @@ impl Instance {
impl fmt::Debug for Instance { impl fmt::Debug for Instance {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Instance").field("exports", &self.exports).finish() f.debug_struct("Instance")
.field("exports", &self.exports)
.finish()
} }
} }

View File

@@ -2,7 +2,12 @@
html_logo_url = "https://github.com/wasmerio.png?size=200", html_logo_url = "https://github.com/wasmerio.png?size=200",
html_favicon_url = "https://wasmer.io/static/icons/favicon.ico" html_favicon_url = "https://wasmer.io/static/icons/favicon.ico"
)] )]
#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates, broken_intra_doc_links)] #![deny(
missing_docs,
trivial_numeric_casts,
unused_extern_crates,
broken_intra_doc_links
)]
#![warn(unused_import_braces)] #![warn(unused_import_braces)]
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",

View File

@@ -101,7 +101,10 @@ impl Module {
pub fn new(store: &Store, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> { pub fn new(store: &Store, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> {
#[cfg(feature = "wat")] #[cfg(feature = "wat")]
let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| { let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| {
CompileError::Wasm(WasmError::Generic(format!("Error when converting wat: {}", e))) CompileError::Wasm(WasmError::Generic(format!(
"Error when converting wat: {}",
e
)))
})?; })?;
Self::from_binary(store, bytes.as_ref()) Self::from_binary(store, bytes.as_ref())
@@ -250,7 +253,10 @@ impl Module {
} }
fn from_artifact(store: &Store, artifact: Arc<dyn Artifact>) -> Self { fn from_artifact(store: &Store, artifact: Arc<dyn Artifact>) -> Self {
Self { store: store.clone(), artifact } Self {
store: store.clone(),
artifact,
}
} }
pub(crate) fn instantiate( pub(crate) fn instantiate(
@@ -259,7 +265,8 @@ impl Module {
) -> Result<InstanceHandle, InstantiationError> { ) -> Result<InstanceHandle, InstantiationError> {
unsafe { unsafe {
let instance_handle = let instance_handle =
self.artifact.instantiate(self.store.tunables(), resolver, Box::new(()))?; self.artifact
.instantiate(self.store.tunables(), resolver, Box::new(()))?;
// After the instance handle is created, we need to initialize // After the instance handle is created, we need to initialize
// the data, call the start function and so. However, if any // the data, call the start function and so. However, if any
@@ -418,6 +425,8 @@ impl Module {
impl fmt::Debug for Module { impl fmt::Debug for Module {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Module").field("name", &self.name()).finish() f.debug_struct("Module")
.field("name", &self.name())
.finish()
} }
} }

View File

@@ -41,7 +41,12 @@ where
exported: ExportFunction, exported: ExportFunction,
definition: FunctionDefinition, definition: FunctionDefinition,
) -> Self { ) -> Self {
Self { definition, store, exported, _phantom: PhantomData } Self {
definition,
store,
exported,
_phantom: PhantomData,
}
} }
pub(crate) fn vmctx(&self) -> VMFunctionEnvironment { pub(crate) fn vmctx(&self) -> VMFunctionEnvironment {
@@ -92,7 +97,11 @@ where
Rets: WasmTypeList, Rets: WasmTypeList,
{ {
fn from(other: NativeFunc<Args, Rets>) -> Self { fn from(other: NativeFunc<Args, Rets>) -> Self {
Self { store: other.store, definition: other.definition, exported: other.exported } Self {
store: other.store,
definition: other.definition,
exported: other.exported,
}
} }
} }

View File

@@ -43,7 +43,10 @@ impl<T: Copy, Ty> WasmPtr<T, Ty> {
/// Create a new `WasmPtr` at the given offset. /// Create a new `WasmPtr` at the given offset.
#[inline] #[inline]
pub fn new(offset: u32) -> Self { pub fn new(offset: u32) -> Self {
Self { offset, _phantom: PhantomData } Self {
offset,
_phantom: PhantomData,
}
} }
/// Get the offset into Wasm linear memory for this `WasmPtr`. /// Get the offset into Wasm linear memory for this `WasmPtr`.
@@ -267,7 +270,10 @@ unsafe impl<T: Copy, Ty> FromToNativeWasmType for WasmPtr<T, Ty> {
self.offset as i32 self.offset as i32
} }
fn from_native(n: Self::Native) -> Self { fn from_native(n: Self::Native) -> Self {
Self { offset: n as u32, _phantom: PhantomData } Self {
offset: n as u32,
_phantom: PhantomData,
}
} }
} }
@@ -275,7 +281,10 @@ unsafe impl<T: Copy, Ty> ValueType for WasmPtr<T, Ty> {}
impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> { impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { offset: self.offset, _phantom: PhantomData } Self {
offset: self.offset,
_phantom: PhantomData,
}
} }
} }

View File

@@ -39,7 +39,10 @@ impl Store {
where where
E: Engine + ?Sized, E: Engine + ?Sized,
{ {
Self { engine: engine.cloned(), tunables: Arc::new(tunables) } Self {
engine: engine.cloned(),
tunables: Arc::new(tunables),
}
} }
/// Returns the [`Tunables`]. /// Returns the [`Tunables`].
@@ -106,7 +109,10 @@ impl Default for Store {
let config = get_config(); let config = get_config();
let engine = get_engine(config); let engine = get_engine(config);
let tunables = BaseTunables::for_target(engine.target()); let tunables = BaseTunables::for_target(engine.target());
Store { engine: Arc::new(engine), tunables: Arc::new(tunables) } Store {
engine: Arc::new(engine),
tunables: Arc::new(tunables),
}
} }
} }

View File

@@ -84,7 +84,9 @@ impl Tunables for BaseTunables {
offset_guard_size: self.static_memory_offset_guard_size, offset_guard_size: self.static_memory_offset_guard_size,
} }
} else { } else {
MemoryStyle::Dynamic { offset_guard_size: self.dynamic_memory_offset_guard_size } MemoryStyle::Dynamic {
offset_guard_size: self.dynamic_memory_offset_guard_size,
}
} }
} }
@@ -113,7 +115,11 @@ impl Tunables for BaseTunables {
style: &MemoryStyle, style: &MemoryStyle,
vm_definition_location: NonNull<VMMemoryDefinition>, vm_definition_location: NonNull<VMMemoryDefinition>,
) -> Result<Arc<dyn Memory>, MemoryError> { ) -> Result<Arc<dyn Memory>, MemoryError> {
Ok(Arc::new(LinearMemory::from_definition(&ty, &style, vm_definition_location)?)) Ok(Arc::new(LinearMemory::from_definition(
&ty,
&style,
vm_definition_location,
)?))
} }
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`]. /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
@@ -136,7 +142,11 @@ impl Tunables for BaseTunables {
style: &TableStyle, style: &TableStyle,
vm_definition_location: NonNull<VMTableDefinition>, vm_definition_location: NonNull<VMTableDefinition>,
) -> Result<Arc<dyn Table>, String> { ) -> Result<Arc<dyn Table>, String> {
Ok(Arc::new(LinearTable::from_definition(&ty, &style, vm_definition_location)?)) Ok(Arc::new(LinearTable::from_definition(
&ty,
&style,
vm_definition_location,
)?))
} }
} }
@@ -172,7 +182,10 @@ mod tests {
let requested = MemoryType::new(3, Some(16), true); let requested = MemoryType::new(3, Some(16), true);
let style = tunables.memory_style(&requested); let style = tunables.memory_style(&requested);
match style { match style {
MemoryStyle::Static { bound, offset_guard_size } => { MemoryStyle::Static {
bound,
offset_guard_size,
} => {
assert_eq!(bound, Pages(2048)); assert_eq!(bound, Pages(2048));
assert_eq!(offset_guard_size, 128); assert_eq!(offset_guard_size, 128);
} }

View File

@@ -66,8 +66,10 @@ impl ValFuncRef for Val {
let anyfunc: *const wasmer_vm::VMCallerCheckedAnyfunc = *func_ref; let anyfunc: *const wasmer_vm::VMCallerCheckedAnyfunc = *func_ref;
&*anyfunc &*anyfunc
}; };
let signature = let signature = store
store.engine().lookup_signature(item.type_index).expect("Signature not found in store"); .engine()
.lookup_signature(item.type_index)
.expect("Signature not found in store");
let export = wasmer_engine::ExportFunction { let export = wasmer_engine::ExportFunction {
// TODO: // TODO:
// figure out if we ever need a value here: need testing with complicated import patterns // figure out if we ever need a value here: need testing with complicated import patterns

View File

@@ -5,10 +5,22 @@ use wasmer::*;
fn global_new() -> Result<()> { fn global_new() -> Result<()> {
let store = Store::default(); let store = Store::default();
let global = Global::new(&store, Value::I32(10)); let global = Global::new(&store, Value::I32(10));
assert_eq!(*global.ty(), GlobalType { ty: Type::I32, mutability: Mutability::Const }); assert_eq!(
*global.ty(),
GlobalType {
ty: Type::I32,
mutability: Mutability::Const
}
);
let global_mut = Global::new_mut(&store, Value::I32(10)); let global_mut = Global::new_mut(&store, Value::I32(10));
assert_eq!(*global_mut.ty(), GlobalType { ty: Type::I32, mutability: Mutability::Var }); assert_eq!(
*global_mut.ty(),
GlobalType {
ty: Type::I32,
mutability: Mutability::Var
}
);
Ok(()) Ok(())
} }
@@ -49,7 +61,11 @@ fn global_set() -> Result<()> {
#[test] #[test]
fn table_new() -> Result<()> { fn table_new() -> Result<()> {
let store = Store::default(); let store = Store::default();
let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: None }; let table_type = TableType {
ty: Type::FuncRef,
minimum: 0,
maximum: None,
};
let f = Function::new_native(&store, || {}); let f = Function::new_native(&store, || {});
let table = Table::new(&store, table_type, Value::FuncRef(Some(f)))?; let table = Table::new(&store, table_type, Value::FuncRef(Some(f)))?;
assert_eq!(*table.ty(), table_type); assert_eq!(*table.ty(), table_type);
@@ -70,7 +86,11 @@ fn table_new() -> Result<()> {
#[ignore] #[ignore]
fn table_get() -> Result<()> { fn table_get() -> Result<()> {
let store = Store::default(); let store = Store::default();
let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: Some(1) }; let table_type = TableType {
ty: Type::FuncRef,
minimum: 0,
maximum: Some(1),
};
let f = Function::new_native(&store, |num: i32| num + 1); let f = Function::new_native(&store, |num: i32| num + 1);
let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?; let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
assert_eq!(*table.ty(), table_type); assert_eq!(*table.ty(), table_type);
@@ -89,7 +109,11 @@ fn table_set() -> Result<()> {
#[test] #[test]
fn table_grow() -> Result<()> { fn table_grow() -> Result<()> {
let store = Store::default(); let store = Store::default();
let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: Some(10) }; let table_type = TableType {
ty: Type::FuncRef,
minimum: 0,
maximum: Some(10),
};
let f = Function::new_native(&store, |num: i32| num + 1); let f = Function::new_native(&store, |num: i32| num + 1);
let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?; let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
// Growing to a bigger maximum should return None // Growing to a bigger maximum should return None
@@ -113,7 +137,11 @@ fn table_copy() -> Result<()> {
#[test] #[test]
fn memory_new() -> Result<()> { fn memory_new() -> Result<()> {
let store = Store::default(); let store = Store::default();
let memory_type = MemoryType { shared: false, minimum: Pages(0), maximum: Some(Pages(10)) }; let memory_type = MemoryType {
shared: false,
minimum: Pages(0),
maximum: Some(Pages(10)),
};
let memory = Memory::new(&store, memory_type)?; let memory = Memory::new(&store, memory_type)?;
assert_eq!(memory.size(), Pages(0)); assert_eq!(memory.size(), Pages(0));
assert_eq!(*memory.ty(), memory_type); assert_eq!(*memory.ty(), memory_type);
@@ -135,7 +163,10 @@ fn memory_grow() -> Result<()> {
let result = memory.grow(Pages(10)); let result = memory.grow(Pages(10));
assert_eq!( assert_eq!(
result, result,
Err(MemoryError::CouldNotGrow { current: 12.into(), attempted_delta: 10.into() }) Err(MemoryError::CouldNotGrow {
current: 12.into(),
attempted_delta: 10.into()
})
); );
let bad_desc = MemoryType::new(Pages(15), Some(Pages(10)), false); let bad_desc = MemoryType::new(Pages(15), Some(Pages(10)), false);
@@ -152,14 +183,20 @@ fn function_new() -> Result<()> {
let function = Function::new_native(&store, || {}); let function = Function::new_native(&store, || {});
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![])); assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
let function = Function::new_native(&store, |_a: i32| {}); let function = Function::new_native(&store, |_a: i32| {});
assert_eq!(function.ty().clone(), FunctionType::new(vec![Type::I32], vec![])); assert_eq!(
function.ty().clone(),
FunctionType::new(vec![Type::I32], vec![])
);
let function = Function::new_native(&store, |_a: i32, _b: i64, _c: f32, _d: f64| {}); let function = Function::new_native(&store, |_a: i32, _b: i64, _c: f32, _d: f64| {});
assert_eq!( assert_eq!(
function.ty().clone(), function.ty().clone(),
FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![]) FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![])
); );
let function = Function::new_native(&store, || -> i32 { 1 }); let function = Function::new_native(&store, || -> i32 { 1 });
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![Type::I32])); assert_eq!(
function.ty().clone(),
FunctionType::new(vec![], vec![Type::I32])
);
let function = Function::new_native(&store, || -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) }); let function = Function::new_native(&store, || -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) });
assert_eq!( assert_eq!(
function.ty().clone(), function.ty().clone(),
@@ -179,7 +216,10 @@ fn function_new_env() -> Result<()> {
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![])); assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
let function = let function =
Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv, _a: i32| {}); Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv, _a: i32| {});
assert_eq!(function.ty().clone(), FunctionType::new(vec![Type::I32], vec![])); assert_eq!(
function.ty().clone(),
FunctionType::new(vec![Type::I32], vec![])
);
let function = Function::new_native_with_env( let function = Function::new_native_with_env(
&store, &store,
my_env.clone(), my_env.clone(),
@@ -191,7 +231,10 @@ fn function_new_env() -> Result<()> {
); );
let function = let function =
Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv| -> i32 { 1 }); Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv| -> i32 { 1 });
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![Type::I32])); assert_eq!(
function.ty().clone(),
FunctionType::new(vec![], vec![Type::I32])
);
let function = Function::new_native_with_env( let function = Function::new_native_with_env(
&store, &store,
my_env.clone(), my_env.clone(),
@@ -370,7 +413,10 @@ fn manually_generate_wasmer_env() -> Result<()> {
env.val + arg1 + arg2 env.val + arg1 + arg2
} }
let mut env = MyEnv { val: 5, memory: LazyInit::new() }; let mut env = MyEnv {
val: 5,
memory: LazyInit::new(),
};
let result = host_function(&mut env, 7, 9); let result = host_function(&mut env, 7, 9);
assert_eq!(result, 21); assert_eq!(result, 21);

View File

@@ -30,7 +30,10 @@ fn exports_work_after_multiple_instances_have_been_freed() -> Result<()> {
drop(instance3); drop(instance3);
// All instances have been dropped, but `sum` continues to work! // All instances have been dropped, but `sum` continues to work!
assert_eq!(sum.call(&[Value::I32(1), Value::I32(2)])?.into_vec(), vec![Value::I32(3)],); assert_eq!(
sum.call(&[Value::I32(1), Value::I32(2)])?.into_vec(),
vec![Value::I32(3)],
);
Ok(()) Ok(())
} }

View File

@@ -63,19 +63,35 @@ fn imports() -> Result<()> {
// Now we test the iterators // Now we test the iterators
assert_eq!( assert_eq!(
module.imports().functions().collect::<Vec<_>>(), module.imports().functions().collect::<Vec<_>>(),
vec![ImportType::new("host", "func", FunctionType::new(vec![], vec![])),] vec![ImportType::new(
"host",
"func",
FunctionType::new(vec![], vec![])
),]
); );
assert_eq!( assert_eq!(
module.imports().memories().collect::<Vec<_>>(), module.imports().memories().collect::<Vec<_>>(),
vec![ImportType::new("host", "memory", MemoryType::new(Pages(1), None, false)),] vec![ImportType::new(
"host",
"memory",
MemoryType::new(Pages(1), None, false)
),]
); );
assert_eq!( assert_eq!(
module.imports().tables().collect::<Vec<_>>(), module.imports().tables().collect::<Vec<_>>(),
vec![ImportType::new("host", "table", TableType::new(Type::FuncRef, 1, None)),] vec![ImportType::new(
"host",
"table",
TableType::new(Type::FuncRef, 1, None)
),]
); );
assert_eq!( assert_eq!(
module.imports().globals().collect::<Vec<_>>(), module.imports().globals().collect::<Vec<_>>(),
vec![ImportType::new("host", "global", GlobalType::new(Type::I32, Mutability::Const)),] vec![ImportType::new(
"host",
"global",
GlobalType::new(Type::I32, Mutability::Const)
),]
); );
Ok(()) Ok(())
} }
@@ -93,9 +109,18 @@ fn exports() -> Result<()> {
assert_eq!( assert_eq!(
module.exports().collect::<Vec<_>>(), module.exports().collect::<Vec<_>>(),
vec![ vec![
ExportType::new("func", ExternType::Function(FunctionType::new(vec![], vec![]))), ExportType::new(
ExportType::new("memory", ExternType::Memory(MemoryType::new(Pages(1), None, false))), "func",
ExportType::new("table", ExternType::Table(TableType::new(Type::FuncRef, 1, None))), ExternType::Function(FunctionType::new(vec![], vec![]))
),
ExportType::new(
"memory",
ExternType::Memory(MemoryType::new(Pages(1), None, false))
),
ExportType::new(
"table",
ExternType::Table(TableType::new(Type::FuncRef, 1, None))
),
ExportType::new( ExportType::new(
"global", "global",
ExternType::Global(GlobalType::new(Type::I32, Mutability::Const)) ExternType::Global(GlobalType::new(Type::I32, Mutability::Const))
@@ -110,15 +135,24 @@ fn exports() -> Result<()> {
); );
assert_eq!( assert_eq!(
module.exports().memories().collect::<Vec<_>>(), module.exports().memories().collect::<Vec<_>>(),
vec![ExportType::new("memory", MemoryType::new(Pages(1), None, false)),] vec![ExportType::new(
"memory",
MemoryType::new(Pages(1), None, false)
),]
); );
assert_eq!( assert_eq!(
module.exports().tables().collect::<Vec<_>>(), module.exports().tables().collect::<Vec<_>>(),
vec![ExportType::new("table", TableType::new(Type::FuncRef, 1, None)),] vec![ExportType::new(
"table",
TableType::new(Type::FuncRef, 1, None)
),]
); );
assert_eq!( assert_eq!(
module.exports().globals().collect::<Vec<_>>(), module.exports().globals().collect::<Vec<_>>(),
vec![ExportType::new("global", GlobalType::new(Type::I32, Mutability::Const)),] vec![ExportType::new(
"global",
GlobalType::new(Type::I32, Mutability::Const)
),]
); );
Ok(()) Ok(())
} }

View File

@@ -112,8 +112,9 @@ fn func_ref_passed_and_called() -> Result<()> {
} }
{ {
let f: NativeFunc<(), i32> = let f: NativeFunc<(), i32> = instance
instance.exports.get_native_function("call_host_func_with_wasm_func")?; .exports
.get_native_function("call_host_func_with_wasm_func")?;
let result = f.call()?; let result = f.call()?;
assert_eq!(result, 63); assert_eq!(result, 63);
} }
@@ -414,10 +415,12 @@ fn extern_ref_ref_counting_table_instructions() -> Result<()> {
let module = Module::new(&store, wat)?; let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &imports! {})?; let instance = Instance::new(&module, &imports! {})?;
let grow_table_with_ref: NativeFunc<(ExternRef, i32), i32> = let grow_table_with_ref: NativeFunc<(ExternRef, i32), i32> = instance
instance.exports.get_native_function("grow_table_with_ref")?; .exports
let fill_table_with_ref: NativeFunc<(ExternRef, i32, i32), ()> = .get_native_function("grow_table_with_ref")?;
instance.exports.get_native_function("fill_table_with_ref")?; let fill_table_with_ref: NativeFunc<(ExternRef, i32, i32), ()> = instance
.exports
.get_native_function("fill_table_with_ref")?;
let copy_into_table2: NativeFunc<(), ()> = let copy_into_table2: NativeFunc<(), ()> =
instance.exports.get_native_function("copy_into_table2")?; instance.exports.get_native_function("copy_into_table2")?;
let table1: &Table = instance.exports.get_table("table1")?; let table1: &Table = instance.exports.get_table("table1")?;

View File

@@ -142,8 +142,9 @@ pub unsafe extern "C" fn wasmer_export_descriptors(
) { ) {
let module = &*(module as *const Module); let module = &*(module as *const Module);
let named_export_descriptors: Box<NamedExportDescriptors> = let named_export_descriptors: Box<NamedExportDescriptors> = Box::new(NamedExportDescriptors(
Box::new(NamedExportDescriptors(module.exports().into_iter().map(|e| e.into()).collect())); module.exports().into_iter().map(|e| e.into()).collect(),
));
*export_descriptors = *export_descriptors =
Box::into_raw(named_export_descriptors) as *mut wasmer_export_descriptors_t; Box::into_raw(named_export_descriptors) as *mut wasmer_export_descriptors_t;
} }
@@ -402,8 +403,10 @@ pub unsafe extern "C" fn wasmer_export_to_memory(
let named_export = &*(export as *const NamedExport); let named_export = &*(export as *const NamedExport);
let instance = named_export.instance.as_ref(); let instance = named_export.instance.as_ref();
if let Ok(exported_memory) = if let Ok(exported_memory) = instance
instance.instance.exports.get::<Memory>(&named_export.export_type.name()) .instance
.exports
.get::<Memory>(&named_export.export_type.name())
{ {
let mem = Box::new(exported_memory.clone()); let mem = Box::new(exported_memory.clone());
*memory = Box::into_raw(mem) as *mut wasmer_memory_t; *memory = Box::into_raw(mem) as *mut wasmer_memory_t;
@@ -446,12 +449,16 @@ pub unsafe extern "C" fn wasmer_export_func_call(
results_len: c_uint, results_len: c_uint,
) -> wasmer_result_t { ) -> wasmer_result_t {
if func.is_null() { if func.is_null() {
update_last_error(CApiError { msg: "func ptr is null".to_string() }); update_last_error(CApiError {
msg: "func ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
if params_len > 0 && params.is_null() { if params_len > 0 && params.is_null() {
update_last_error(CApiError { msg: "params ptr is null".to_string() }); update_last_error(CApiError {
msg: "params ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
@@ -472,7 +479,11 @@ pub unsafe extern "C" fn wasmer_export_func_call(
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize); let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
let instance = named_export.instance.as_ref(); let instance = named_export.instance.as_ref();
let f: &Function = match instance.instance.exports.get(&named_export.export_type.name()) { let f: &Function = match instance
.instance
.exports
.get(&named_export.export_type.name())
{
Ok(f) => f, Ok(f) => f,
Err(err) => { Err(err) => {
update_last_error(err); update_last_error(err);
@@ -519,7 +530,10 @@ pub unsafe extern "C" fn wasmer_export_func_call(
impl From<ExportType> for NamedExportDescriptor { impl From<ExportType> for NamedExportDescriptor {
fn from(et: ExportType) -> Self { fn from(et: ExportType) -> Self {
NamedExportDescriptor { name: et.name().to_string(), kind: et.into() } NamedExportDescriptor {
name: et.name().to_string(),
kind: et.into(),
}
} }
} }

View File

@@ -61,7 +61,10 @@ pub unsafe extern "C" fn wasmer_global_get_descriptor(
) -> wasmer_global_descriptor_t { ) -> wasmer_global_descriptor_t {
let global = &*(global as *mut Global); let global = &*(global as *mut Global);
let descriptor = global.ty(); let descriptor = global.ty();
wasmer_global_descriptor_t { mutable: descriptor.mutability.into(), kind: descriptor.ty.into() } wasmer_global_descriptor_t {
mutable: descriptor.mutability.into(),
kind: descriptor.ty.into(),
}
} }
/// Frees memory for the given Global /// Frees memory for the given Global

View File

@@ -343,7 +343,9 @@ pub unsafe extern "C" fn wasmer_import_object_iter_at_end(
let mut import_object_iter = if let Some(import_object_iter) = import_object_iter { let mut import_object_iter = if let Some(import_object_iter) = import_object_iter {
import_object_iter.cast::<WasmerImportObjectIterator>() import_object_iter.cast::<WasmerImportObjectIterator>()
} else { } else {
update_last_error(CApiError { msg: "import_object_iter must not be null".to_owned() }); update_last_error(CApiError {
msg: "import_object_iter must not be null".to_owned(),
});
return true; return true;
}; };
let iter = import_object_iter.as_mut(); let iter = import_object_iter.as_mut();
@@ -357,7 +359,11 @@ pub unsafe extern "C" fn wasmer_import_object_iter_destroy(
import_object_iter: Option<NonNull<wasmer_import_object_iter_t>>, import_object_iter: Option<NonNull<wasmer_import_object_iter_t>>,
) { ) {
if let Some(import_object_iter) = import_object_iter { if let Some(import_object_iter) = import_object_iter {
let _ = Box::from_raw(import_object_iter.cast::<WasmerImportObjectIterator>().as_ptr()); let _ = Box::from_raw(
import_object_iter
.cast::<WasmerImportObjectIterator>()
.as_ptr(),
);
} }
} }
@@ -420,8 +426,10 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
let mut import_data: HashMap<String, Exports> = HashMap::new(); let mut import_data: HashMap<String, Exports> = HashMap::new();
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize); let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
for import in imports { for import in imports {
let module_name = let module_name = slice::from_raw_parts(
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize); import.module_name.bytes,
import.module_name.bytes_len as usize,
);
let module_name = if let Ok(s) = std::str::from_utf8(module_name) { let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
s s
} else { } else {
@@ -430,8 +438,10 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
}); });
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
}; };
let import_name = let import_name = slice::from_raw_parts(
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize); import.import_name.bytes,
import.import_name.bytes_len as usize,
);
let import_name = if let Ok(s) = std::str::from_utf8(import_name) { let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
s s
} else { } else {
@@ -451,7 +461,9 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
// TODO: investigate consistent usage of `FunctionWrapper` in this context // TODO: investigate consistent usage of `FunctionWrapper` in this context
let func_wrapper = import.value.func as *mut FunctionWrapper; let func_wrapper = import.value.func as *mut FunctionWrapper;
let func_export = (*func_wrapper).func.as_ptr(); let func_export = (*func_wrapper).func.as_ptr();
import_object.instance_pointers_to_update.push((*func_wrapper).legacy_env.clone()); import_object
.instance_pointers_to_update
.push((*func_wrapper).legacy_env.clone());
Extern::Function((&*func_export).clone()) Extern::Function((&*func_export).clone())
} }
wasmer_import_export_kind::WASM_GLOBAL => { wasmer_import_export_kind::WASM_GLOBAL => {
@@ -464,7 +476,9 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
} }
}; };
let export_entry = import_data.entry(module_name.to_string()).or_insert_with(Exports::new); let export_entry = import_data
.entry(module_name.to_string())
.or_insert_with(Exports::new);
export_entry.insert(import_name.to_string(), export); export_entry.insert(import_name.to_string(), export);
} }
@@ -632,7 +646,9 @@ unsafe impl Sync for LegacyEnv {}
impl LegacyEnv { impl LegacyEnv {
pub(crate) fn ctx_ptr(&self) -> *mut CAPIInstance { pub(crate) fn ctx_ptr(&self) -> *mut CAPIInstance {
self.instance_ptr.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut()) self.instance_ptr
.map(|p| p.as_ptr())
.unwrap_or(ptr::null_mut())
} }
} }
@@ -750,7 +766,9 @@ pub unsafe extern "C" fn wasmer_trap(
error_message: *const c_char, error_message: *const c_char,
) -> wasmer_result_t { ) -> wasmer_result_t {
if error_message.is_null() { if error_message.is_null() {
update_last_error(CApiError { msg: "error_message is null in wasmer_trap".to_string() }); update_last_error(CApiError {
msg: "error_message is null in wasmer_trap".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }

View File

@@ -213,8 +213,9 @@ pub unsafe extern "C" fn wasmer_wasi_generate_default_import_object() -> *mut wa
let mut wasi_state_builder = wasi::WasiState::new("wasmer-wasi-default-program-name"); let mut wasi_state_builder = wasi::WasiState::new("wasmer-wasi-default-program-name");
let wasi_state = wasi_state_builder.build().unwrap(); let wasi_state = wasi_state_builder.build().unwrap();
let wasi_env = wasi::WasiEnv::new(wasi_state); let wasi_env = wasi::WasiEnv::new(wasi_state);
let import_object_inner: Box<dyn NamedResolver> = let import_object_inner: Box<dyn NamedResolver> = Box::new(
Box::new(wasi::generate_import_object_from_env(store, wasi_env, wasi::WasiVersion::Latest)); wasi::generate_import_object_from_env(store, wasi_env, wasi::WasiVersion::Latest),
);
let import_object: Box<CAPIImportObject> = Box::new(CAPIImportObject { let import_object: Box<CAPIImportObject> = Box::new(CAPIImportObject {
import_object: import_object_inner, import_object: import_object_inner,
imported_memories: vec![], imported_memories: vec![],

View File

@@ -124,25 +124,34 @@ pub unsafe extern "C" fn wasmer_instantiate(
let wasm_bytes = if let Some(wasm_bytes_inner) = wasm_bytes { let wasm_bytes = if let Some(wasm_bytes_inner) = wasm_bytes {
wasm_bytes_inner wasm_bytes_inner
} else { } else {
update_last_error(CApiError { msg: "wasm bytes ptr is null".to_string() }); update_last_error(CApiError {
msg: "wasm bytes ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
}; };
if imports_len > 0 && imports.is_null() { if imports_len > 0 && imports.is_null() {
update_last_error(CApiError { msg: "imports ptr is null".to_string() }); update_last_error(CApiError {
msg: "imports ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
let mut imported_memories = vec![]; let mut imported_memories = vec![];
let mut instance_pointers_to_update = vec![]; let mut instance_pointers_to_update = vec![];
let imports: &[wasmer_import_t] = let imports: &[wasmer_import_t] = if imports_len == 0 {
if imports_len == 0 { &[] } else { slice::from_raw_parts(imports, imports_len as usize) }; &[]
} else {
slice::from_raw_parts(imports, imports_len as usize)
};
let mut import_object = ImportObject::new(); let mut import_object = ImportObject::new();
let mut namespaces = HashMap::new(); let mut namespaces = HashMap::new();
for import in imports { for import in imports {
let module_name = let module_name = slice::from_raw_parts(
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize); import.module_name.bytes,
import.module_name.bytes_len as usize,
);
let module_name = if let Ok(s) = std::str::from_utf8(module_name) { let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
s s
} else { } else {
@@ -151,8 +160,10 @@ pub unsafe extern "C" fn wasmer_instantiate(
}); });
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
}; };
let import_name = let import_name = slice::from_raw_parts(
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize); import.import_name.bytes,
import.import_name.bytes_len as usize,
);
let import_name = if let Ok(s) = std::str::from_utf8(import_name) { let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
s s
} else { } else {
@@ -212,7 +223,11 @@ pub unsafe extern "C" fn wasmer_instantiate(
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
}; };
let c_api_instance = CAPIInstance { instance: new_instance, imported_memories, ctx_data: None }; let c_api_instance = CAPIInstance {
instance: new_instance,
imported_memories,
ctx_data: None,
};
let c_api_instance_pointer = Box::into_raw(Box::new(c_api_instance)); let c_api_instance_pointer = Box::into_raw(Box::new(c_api_instance));
for to_update in instance_pointers_to_update { for to_update in instance_pointers_to_update {
let mut to_update_guard = to_update.lock().unwrap(); let mut to_update_guard = to_update.lock().unwrap();
@@ -307,19 +322,25 @@ pub unsafe extern "C" fn wasmer_instance_call(
results_len: u32, results_len: u32,
) -> wasmer_result_t { ) -> wasmer_result_t {
if instance.is_null() { if instance.is_null() {
update_last_error(CApiError { msg: "instance ptr is null".to_string() }); update_last_error(CApiError {
msg: "instance ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
if name.is_null() { if name.is_null() {
update_last_error(CApiError { msg: "name ptr is null".to_string() }); update_last_error(CApiError {
msg: "name ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
if params_len > 0 && params.is_null() { if params_len > 0 && params.is_null() {
update_last_error(CApiError { msg: "params ptr is null".to_string() }); update_last_error(CApiError {
msg: "params ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
@@ -448,7 +469,10 @@ pub unsafe extern "C" fn wasmer_instance_exports(
.instance .instance
.module() .module()
.exports() .exports()
.map(|export_type| NamedExport { export_type, instance }) .map(|export_type| NamedExport {
export_type,
instance,
})
.collect(); .collect();
let named_exports: Box<NamedExports> = Box::new(NamedExports(exports_vec)); let named_exports: Box<NamedExports> = Box::new(NamedExports(exports_vec));
@@ -554,13 +578,19 @@ pub unsafe extern "C" fn wasmer_instance_context_memory(
{ {
name name
} else { } else {
update_last_error(CApiError { msg: "Could not find an exported memory".to_string() }); update_last_error(CApiError {
msg: "Could not find an exported memory".to_string(),
});
return None; return None;
}; };
let memory = instance.instance.exports.get_memory(exported_memory_name).expect(&format!( let memory = instance
"Module exports memory named `{}` but it's inaccessible", .instance
&exported_memory_name .exports
)); .get_memory(exported_memory_name)
.expect(&format!(
"Module exports memory named `{}` but it's inaccessible",
&exported_memory_name
));
Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t)) Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t))
} }
} }

View File

@@ -60,7 +60,11 @@ pub unsafe extern "C" fn wasmer_memory_new(
memory: *mut *mut wasmer_memory_t, memory: *mut *mut wasmer_memory_t,
limits: wasmer_limits_t, limits: wasmer_limits_t,
) -> wasmer_result_t { ) -> wasmer_result_t {
let max = if limits.max.has_some { Some(Pages(limits.max.some)) } else { None }; let max = if limits.max.has_some {
Some(Pages(limits.max.some))
} else {
None
};
let store = get_global_store(); let store = get_global_store();
let desc = MemoryType::new(Pages(limits.min), max, false); let desc = MemoryType::new(Pages(limits.min), max, false);
match Memory::new(store, desc) { match Memory::new(store, desc) {
@@ -69,7 +73,9 @@ pub unsafe extern "C" fn wasmer_memory_new(
wasmer_result_t::WASMER_OK wasmer_result_t::WASMER_OK
} }
Err(err) => { Err(err) => {
update_last_error(CApiError { msg: err.to_string() }); update_last_error(CApiError {
msg: err.to_string(),
});
wasmer_result_t::WASMER_ERROR wasmer_result_t::WASMER_ERROR
} }
} }
@@ -95,7 +101,9 @@ pub unsafe extern "C" fn wasmer_memory_new(
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -> wasmer_result_t { pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -> wasmer_result_t {
if memory.is_null() { if memory.is_null() {
update_last_error(CApiError { msg: "`memory` is NULL.".to_string() }); update_last_error(CApiError {
msg: "`memory` is NULL.".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
@@ -106,7 +114,9 @@ pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -
match grow_result { match grow_result {
Ok(_) => wasmer_result_t::WASMER_OK, Ok(_) => wasmer_result_t::WASMER_OK,
Err(err) => { Err(err) => {
update_last_error(CApiError { msg: err.to_string() }); update_last_error(CApiError {
msg: err.to_string(),
});
wasmer_result_t::WASMER_ERROR wasmer_result_t::WASMER_ERROR
} }
} }

View File

@@ -92,8 +92,10 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
let mut import_object = ImportObject::new(); let mut import_object = ImportObject::new();
let mut namespaces = HashMap::new(); let mut namespaces = HashMap::new();
for import in imports { for import in imports {
let module_name = let module_name = slice::from_raw_parts(
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize); import.module_name.bytes,
import.module_name.bytes_len as usize,
);
let module_name = if let Ok(s) = std::str::from_utf8(module_name) { let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
s s
} else { } else {
@@ -102,8 +104,10 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
}); });
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
}; };
let import_name = let import_name = slice::from_raw_parts(
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize); import.import_name.bytes,
import.import_name.bytes_len as usize,
);
let import_name = if let Ok(s) = std::str::from_utf8(import_name) { let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
s s
} else { } else {
@@ -149,7 +153,11 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
} }
}; };
let c_api_instance = CAPIInstance { instance: new_instance, imported_memories, ctx_data: None }; let c_api_instance = CAPIInstance {
instance: new_instance,
imported_memories,
ctx_data: None,
};
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t; *instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
wasmer_result_t::WASMER_OK wasmer_result_t::WASMER_OK
@@ -216,7 +224,9 @@ pub unsafe extern "C" fn wasmer_module_serialize(
wasmer_result_t::WASMER_OK wasmer_result_t::WASMER_OK
} }
Err(_) => { Err(_) => {
update_last_error(CApiError { msg: "Failed to serialize the module".to_string() }); update_last_error(CApiError {
msg: "Failed to serialize the module".to_string(),
});
wasmer_result_t::WASMER_ERROR wasmer_result_t::WASMER_ERROR
} }
} }
@@ -258,8 +268,10 @@ pub unsafe extern "C" fn wasmer_serialized_module_from_bytes(
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
let serialized_module_bytes: &[u8] = let serialized_module_bytes: &[u8] = slice::from_raw_parts(
slice::from_raw_parts(serialized_module_bytes, serialized_module_bytes_length as usize); serialized_module_bytes,
serialized_module_bytes_length as usize,
);
*serialized_module = Box::into_raw(Box::new(serialized_module_bytes)) as _; *serialized_module = Box::into_raw(Box::new(serialized_module_bytes)) as _;
wasmer_result_t::WASMER_OK wasmer_result_t::WASMER_OK
@@ -281,7 +293,9 @@ pub unsafe extern "C" fn wasmer_module_deserialize(
let serialized_module: &[u8] = if let Some(sm) = serialized_module { let serialized_module: &[u8] = if let Some(sm) = serialized_module {
&*(sm as *const wasmer_serialized_module_t as *const &[u8]) &*(sm as *const wasmer_serialized_module_t as *const &[u8])
} else { } else {
update_last_error(CApiError { msg: "`serialized_module` pointer is null".to_string() }); update_last_error(CApiError {
msg: "`serialized_module` pointer is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
}; };

View File

@@ -36,8 +36,16 @@ pub unsafe extern "C" fn wasmer_table_new(
table: *mut *mut wasmer_table_t, table: *mut *mut wasmer_table_t,
limits: wasmer_limits_t, limits: wasmer_limits_t,
) -> wasmer_result_t { ) -> wasmer_result_t {
let max = if limits.max.has_some { Some(limits.max.some) } else { None }; let max = if limits.max.has_some {
let desc = TableType { ty: ValType::FuncRef, minimum: limits.min, maximum: max }; Some(limits.max.some)
} else {
None
};
let desc = TableType {
ty: ValType::FuncRef,
minimum: limits.min,
maximum: max,
};
let store = get_global_store(); let store = get_global_store();
let result = Table::new(store, desc, get_default_table_value(ValType::FuncRef)); let result = Table::new(store, desc, get_default_table_value(ValType::FuncRef));
let new_table = match result { let new_table = match result {

View File

@@ -74,18 +74,22 @@ impl From<wasmer_value_t> for Val {
unsafe { unsafe {
#[allow(unreachable_patterns, non_snake_case)] #[allow(unreachable_patterns, non_snake_case)]
match v { match v {
wasmer_value_t { tag: wasmer_value_tag::WASM_I32, value: wasmer_value { I32 } } => { wasmer_value_t {
Val::I32(I32) tag: wasmer_value_tag::WASM_I32,
} value: wasmer_value { I32 },
wasmer_value_t { tag: wasmer_value_tag::WASM_I64, value: wasmer_value { I64 } } => { } => Val::I32(I32),
Val::I64(I64) wasmer_value_t {
} tag: wasmer_value_tag::WASM_I64,
wasmer_value_t { tag: wasmer_value_tag::WASM_F32, value: wasmer_value { F32 } } => { value: wasmer_value { I64 },
Val::F32(F32) } => Val::I64(I64),
} wasmer_value_t {
wasmer_value_t { tag: wasmer_value_tag::WASM_F64, value: wasmer_value { F64 } } => { tag: wasmer_value_tag::WASM_F32,
Val::F64(F64) value: wasmer_value { F32 },
} } => Val::F32(F32),
wasmer_value_t {
tag: wasmer_value_tag::WASM_F64,
value: wasmer_value { F64 },
} => Val::F64(F64),
_ => unreachable!("unknown Wasm type"), _ => unreachable!("unknown Wasm type"),
} }
} }
@@ -95,18 +99,22 @@ impl From<wasmer_value_t> for Val {
impl From<Val> for wasmer_value_t { impl From<Val> for wasmer_value_t {
fn from(val: Val) -> Self { fn from(val: Val) -> Self {
match val { match val {
Val::I32(x) => { Val::I32(x) => wasmer_value_t {
wasmer_value_t { tag: wasmer_value_tag::WASM_I32, value: wasmer_value { I32: x } } tag: wasmer_value_tag::WASM_I32,
} value: wasmer_value { I32: x },
Val::I64(x) => { },
wasmer_value_t { tag: wasmer_value_tag::WASM_I64, value: wasmer_value { I64: x } } Val::I64(x) => wasmer_value_t {
} tag: wasmer_value_tag::WASM_I64,
Val::F32(x) => { value: wasmer_value { I64: x },
wasmer_value_t { tag: wasmer_value_tag::WASM_F32, value: wasmer_value { F32: x } } },
} Val::F32(x) => wasmer_value_t {
Val::F64(x) => { tag: wasmer_value_tag::WASM_F32,
wasmer_value_t { tag: wasmer_value_tag::WASM_F64, value: wasmer_value { F64: x } } value: wasmer_value { F32: x },
} },
Val::F64(x) => wasmer_value_t {
tag: wasmer_value_tag::WASM_F64,
value: wasmer_value { F64: x },
},
Val::V128(_) => unimplemented!("V128 not supported in C API"), Val::V128(_) => unimplemented!("V128 not supported in C API"),
Val::ExternRef(_) => unimplemented!("ExternRef not supported in C API"), Val::ExternRef(_) => unimplemented!("ExternRef not supported in C API"),
Val::FuncRef(_) => unimplemented!("FuncRef not supported in C API"), Val::FuncRef(_) => unimplemented!("FuncRef not supported in C API"),

View File

@@ -144,7 +144,11 @@ pub unsafe extern "C" fn wasmer_last_error_message(
let buffer = slice::from_raw_parts_mut(buffer.cast::<u8>().as_ptr(), length); let buffer = slice::from_raw_parts_mut(buffer.cast::<u8>().as_ptr(), length);
ptr::copy_nonoverlapping(error_message.as_ptr(), buffer.as_mut_ptr(), error_message.len()); ptr::copy_nonoverlapping(
error_message.as_ptr(),
buffer.as_mut_ptr(),
error_message.len(),
);
// Add a trailing null so people using the string as a `char *` don't // Add a trailing null so people using the string as a `char *` don't
// accidentally read into garbage. // accidentally read into garbage.

View File

@@ -17,7 +17,9 @@ pub struct OrderedResolver {
impl Resolver for OrderedResolver { impl Resolver for OrderedResolver {
fn resolve(&self, index: u32, _module: &str, _name: &str) -> Option<Export> { fn resolve(&self, index: u32, _module: &str, _name: &str) -> Option<Export> {
self.externs.get(index as usize).map(|extern_| extern_.to_export()) self.externs
.get(index as usize)
.map(|extern_| extern_.to_export())
} }
} }

View File

@@ -435,7 +435,9 @@ pub extern "C" fn wasm_engine_new_with_config(
where where
M: ToString, M: ToString,
{ {
update_last_error(CApiError { msg: msg.to_string() }); update_last_error(CApiError {
msg: msg.to_string(),
});
return None; return None;
} }

View File

@@ -18,7 +18,10 @@ pub struct wasm_func_t {
impl wasm_func_t { impl wasm_func_t {
pub(crate) fn new(function: Function) -> Self { pub(crate) fn new(function: Function) -> Self {
Self { tag: CApiExternTag::Function, inner: Box::new(function) } Self {
tag: CApiExternTag::Function,
inner: Box::new(function),
}
} }
} }
@@ -168,7 +171,10 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
let function = Function::new_with_env( let function = Function::new_with_env(
&store.inner, &store.inner,
func_sig, func_sig,
WrapperEnv { env, env_finalizer: Arc::new(env_finalizer) }, WrapperEnv {
env,
env_finalizer: Arc::new(env_finalizer),
},
trampoline, trampoline,
); );

View File

@@ -16,7 +16,10 @@ pub struct wasm_global_t {
impl wasm_global_t { impl wasm_global_t {
pub(crate) fn new(global: Global) -> Self { pub(crate) fn new(global: Global) -> Self {
Self { tag: CApiExternTag::Global, inner: Box::new(global) } Self {
tag: CApiExternTag::Global,
inner: Box::new(global),
}
} }
} }

View File

@@ -14,7 +14,10 @@ pub struct wasm_memory_t {
impl wasm_memory_t { impl wasm_memory_t {
pub(crate) fn new(memory: Memory) -> Self { pub(crate) fn new(memory: Memory) -> Self {
Self { tag: CApiExternTag::Memory, inner: Box::new(memory) } Self {
tag: CApiExternTag::Memory,
inner: Box::new(memory),
}
} }
} }

View File

@@ -99,17 +99,25 @@ impl Clone for wasm_extern_t {
fn clone(&self) -> Self { fn clone(&self) -> Self {
match self.get_tag() { match self.get_tag() {
CApiExternTag::Function => Self { CApiExternTag::Function => Self {
inner: wasm_extern_inner { function: unsafe { self.inner.function.clone() } }, inner: wasm_extern_inner {
function: unsafe { self.inner.function.clone() },
},
},
CApiExternTag::Memory => Self {
inner: wasm_extern_inner {
memory: unsafe { self.inner.memory.clone() },
},
},
CApiExternTag::Global => Self {
inner: wasm_extern_inner {
global: unsafe { self.inner.global.clone() },
},
},
CApiExternTag::Table => Self {
inner: wasm_extern_inner {
table: unsafe { self.inner.table.clone() },
},
}, },
CApiExternTag::Memory => {
Self { inner: wasm_extern_inner { memory: unsafe { self.inner.memory.clone() } } }
}
CApiExternTag::Global => {
Self { inner: wasm_extern_inner { global: unsafe { self.inner.global.clone() } } }
}
CApiExternTag::Table => {
Self { inner: wasm_extern_inner { table: unsafe { self.inner.table.clone() } } }
}
} }
} }
} }

View File

@@ -13,7 +13,10 @@ pub struct wasm_table_t {
impl wasm_table_t { impl wasm_table_t {
pub(crate) fn new(table: Table) -> Self { pub(crate) fn new(table: Table) -> Self {
Self { tag: CApiExternTag::Table, inner: Box::new(table) } Self {
tag: CApiExternTag::Table,
inner: Box::new(table),
}
} }
} }

View File

@@ -39,7 +39,9 @@ pub unsafe extern "C" fn wasm_module_new(
let bytes = bytes.into_slice()?; let bytes = bytes.into_slice()?;
let module = c_try!(Module::from_binary(&store.inner, bytes)); let module = c_try!(Module::from_binary(&store.inner, bytes));
Some(Box::new(wasm_module_t { inner: Arc::new(module) })) Some(Box::new(wasm_module_t {
inner: Arc::new(module),
}))
} }
/// Deletes a WebAssembly module. /// Deletes a WebAssembly module.
@@ -486,7 +488,11 @@ pub unsafe extern "C" fn wasm_module_deserialize(
let module = c_try!(Module::deserialize(&store.inner, byte_slice)); let module = c_try!(Module::deserialize(&store.inner, byte_slice));
Some(NonNull::new_unchecked(Box::into_raw(Box::new(wasm_module_t { inner: Arc::new(module) })))) Some(NonNull::new_unchecked(Box::into_raw(Box::new(
wasm_module_t {
inner: Arc::new(module),
},
))))
} }
/// Serializes a module into a binary representation that the /// Serializes a module into a binary representation that the

View File

@@ -16,7 +16,10 @@ pub extern "C" fn wasm_exporttype_new(
extern_type: Option<Box<wasm_externtype_t>>, extern_type: Option<Box<wasm_externtype_t>>,
) -> Option<Box<wasm_exporttype_t>> { ) -> Option<Box<wasm_exporttype_t>> {
let name = unsafe { owned_wasm_name_t::new(name?) }; let name = unsafe { owned_wasm_name_t::new(name?) };
Some(Box::new(wasm_exporttype_t { name, extern_type: extern_type? })) Some(Box::new(wasm_exporttype_t {
name,
extern_type: extern_type?,
}))
} }
#[no_mangle] #[no_mangle]

View File

@@ -13,7 +13,11 @@ impl WasmFunctionType {
let params: Box<wasm_valtype_vec_t> = Box::new(function_type.params().into()); let params: Box<wasm_valtype_vec_t> = Box::new(function_type.params().into());
let results: Box<wasm_valtype_vec_t> = Box::new(function_type.results().into()); let results: Box<wasm_valtype_vec_t> = Box::new(function_type.results().into());
Self { function_type, params, results } Self {
function_type,
params,
results,
}
} }
} }
@@ -32,7 +36,9 @@ pub struct wasm_functype_t {
impl wasm_functype_t { impl wasm_functype_t {
pub(crate) fn new(function_type: FunctionType) -> Self { pub(crate) fn new(function_type: FunctionType) -> Self {
Self { extern_type: wasm_externtype_t::new(ExternType::Function(function_type)) } Self {
extern_type: wasm_externtype_t::new(ExternType::Function(function_type)),
}
} }
pub(crate) fn inner(&self) -> &WasmFunctionType { pub(crate) fn inner(&self) -> &WasmFunctionType {
@@ -55,15 +61,24 @@ pub unsafe extern "C" fn wasm_functype_new(
let params = params?; let params = params?;
let results = results?; let results = results?;
let params_as_valtype: Vec<ValType> = let params_as_valtype: Vec<ValType> = params
params.into_slice()?.into_iter().map(|val| val.as_ref().into()).collect::<Vec<_>>(); .into_slice()?
let results_as_valtype: Vec<ValType> = .into_iter()
results.into_slice()?.iter().map(|val| val.as_ref().into()).collect::<Vec<_>>(); .map(|val| val.as_ref().into())
.collect::<Vec<_>>();
let results_as_valtype: Vec<ValType> = results
.into_slice()?
.iter()
.map(|val| val.as_ref().into())
.collect::<Vec<_>>();
wasm_valtype_vec_delete(Some(params)); wasm_valtype_vec_delete(Some(params));
wasm_valtype_vec_delete(Some(results)); wasm_valtype_vec_delete(Some(results));
Some(Box::new(wasm_functype_t::new(FunctionType::new(params_as_valtype, results_as_valtype)))) Some(Box::new(wasm_functype_t::new(FunctionType::new(
params_as_valtype,
results_as_valtype,
))))
} }
#[no_mangle] #[no_mangle]

View File

@@ -15,7 +15,10 @@ impl WasmGlobalType {
pub(crate) fn new(global_type: GlobalType) -> Self { pub(crate) fn new(global_type: GlobalType) -> Self {
let content = Box::new(global_type.ty.into()); let content = Box::new(global_type.ty.into());
Self { global_type, content } Self {
global_type,
content,
}
} }
} }
@@ -28,7 +31,9 @@ pub struct wasm_globaltype_t {
impl wasm_globaltype_t { impl wasm_globaltype_t {
pub(crate) fn new(global_type: GlobalType) -> Self { pub(crate) fn new(global_type: GlobalType) -> Self {
Self { extern_type: wasm_externtype_t::new(ExternType::Global(global_type)) } Self {
extern_type: wasm_externtype_t::new(ExternType::Global(global_type)),
}
} }
pub(crate) fn inner(&self) -> &WasmGlobalType { pub(crate) fn inner(&self) -> &WasmGlobalType {
@@ -50,8 +55,10 @@ pub unsafe extern "C" fn wasm_globaltype_new(
) -> Option<Box<wasm_globaltype_t>> { ) -> Option<Box<wasm_globaltype_t>> {
let valtype = valtype?; let valtype = valtype?;
let mutability: wasm_mutability_enum = mutability.try_into().ok()?; let mutability: wasm_mutability_enum = mutability.try_into().ok()?;
let global_type = let global_type = Box::new(wasm_globaltype_t::new(GlobalType::new(
Box::new(wasm_globaltype_t::new(GlobalType::new((*valtype).into(), mutability.into()))); (*valtype).into(),
mutability.into(),
)));
wasm_valtype_delete(Some(valtype)); wasm_valtype_delete(Some(valtype));

View File

@@ -18,9 +18,17 @@ pub extern "C" fn wasm_importtype_new(
name: Option<&wasm_name_t>, name: Option<&wasm_name_t>,
extern_type: Option<Box<wasm_externtype_t>>, extern_type: Option<Box<wasm_externtype_t>>,
) -> Option<Box<wasm_importtype_t>> { ) -> Option<Box<wasm_importtype_t>> {
let (module, name) = let (module, name) = unsafe {
unsafe { (owned_wasm_name_t::new(module?), owned_wasm_name_t::new(name?)) }; (
Some(Box::new(wasm_importtype_t { name, module, extern_type: extern_type? })) owned_wasm_name_t::new(module?),
owned_wasm_name_t::new(name?),
)
};
Some(Box::new(wasm_importtype_t {
name,
module,
extern_type: extern_type?,
}))
} }
#[no_mangle] #[no_mangle]
@@ -53,6 +61,10 @@ impl From<&ImportType> for wasm_importtype_t {
let name: owned_wasm_name_t = other.name().to_string().into(); let name: owned_wasm_name_t = other.name().to_string().into();
let extern_type: Box<wasm_externtype_t> = Box::new(other.ty().into()); let extern_type: Box<wasm_externtype_t> = Box::new(other.ty().into());
wasm_importtype_t { module, name, extern_type } wasm_importtype_t {
module,
name,
extern_type,
}
} }
} }

View File

@@ -11,10 +11,16 @@ impl WasmMemoryType {
pub(crate) fn new(memory_type: MemoryType) -> Self { pub(crate) fn new(memory_type: MemoryType) -> Self {
let limits = Box::new(wasm_limits_t { let limits = Box::new(wasm_limits_t {
min: memory_type.minimum.0 as _, min: memory_type.minimum.0 as _,
max: memory_type.maximum.map(|max| max.0 as _).unwrap_or(LIMITS_MAX_SENTINEL), max: memory_type
.maximum
.map(|max| max.0 as _)
.unwrap_or(LIMITS_MAX_SENTINEL),
}); });
Self { memory_type, limits } Self {
memory_type,
limits,
}
} }
} }
@@ -27,7 +33,9 @@ pub struct wasm_memorytype_t {
impl wasm_memorytype_t { impl wasm_memorytype_t {
pub(crate) fn new(memory_type: MemoryType) -> Self { pub(crate) fn new(memory_type: MemoryType) -> Self {
Self { extern_type: wasm_externtype_t::new(ExternType::Memory(memory_type)) } Self {
extern_type: wasm_externtype_t::new(ExternType::Memory(memory_type)),
}
} }
pub(crate) fn inner(&self) -> &WasmMemoryType { pub(crate) fn inner(&self) -> &WasmMemoryType {
@@ -45,10 +53,15 @@ wasm_declare_boxed_vec!(memorytype);
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> { pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
let min_pages = Pages(limits.min as _); let min_pages = Pages(limits.min as _);
let max_pages = let max_pages = if limits.max == LIMITS_MAX_SENTINEL {
if limits.max == LIMITS_MAX_SENTINEL { None } else { Some(Pages(limits.max as _)) }; None
} else {
Some(Pages(limits.max as _))
};
Box::new(wasm_memorytype_t::new(MemoryType::new(min_pages, max_pages, false))) Box::new(wasm_memorytype_t::new(MemoryType::new(
min_pages, max_pages, false,
)))
} }
#[no_mangle] #[no_mangle]

View File

@@ -50,7 +50,10 @@ impl owned_wasm_name_t {
/// You must ensure that the data pointed to by `wasm_name_t` is valid and /// You must ensure that the data pointed to by `wasm_name_t` is valid and
/// that it is not owned by anyone else. /// that it is not owned by anyone else.
pub unsafe fn new(name: &wasm_name_t) -> Self { pub unsafe fn new(name: &wasm_name_t) -> Self {
Self(wasm_name_t { size: name.size, data: name.data }) Self(wasm_name_t {
size: name.size,
data: name.data,
})
} }
} }

View File

@@ -23,7 +23,11 @@ impl WasmTableType {
}); });
let content = Box::new(table_type.ty.into()); let content = Box::new(table_type.ty.into());
Self { table_type, limits, content } Self {
table_type,
limits,
content,
}
} }
} }
@@ -36,7 +40,9 @@ pub struct wasm_tabletype_t {
impl wasm_tabletype_t { impl wasm_tabletype_t {
pub(crate) fn new(table_type: TableType) -> Self { pub(crate) fn new(table_type: TableType) -> Self {
Self { extern_type: wasm_externtype_t::new(ExternType::Table(table_type)) } Self {
extern_type: wasm_externtype_t::new(ExternType::Table(table_type)),
}
} }
pub(crate) fn inner(&self) -> &WasmTableType { pub(crate) fn inner(&self) -> &WasmTableType {
@@ -55,7 +61,11 @@ pub unsafe extern "C" fn wasm_tabletype_new(
limits: &wasm_limits_t, limits: &wasm_limits_t,
) -> Option<Box<wasm_tabletype_t>> { ) -> Option<Box<wasm_tabletype_t>> {
let valtype = valtype?; let valtype = valtype?;
let max_elements = if limits.max == LIMITS_MAX_SENTINEL { None } else { Some(limits.max as _) }; let max_elements = if limits.max == LIMITS_MAX_SENTINEL {
None
} else {
Some(limits.max as _)
};
let table_type = Box::new(wasm_tabletype_t::new(TableType::new( let table_type = Box::new(wasm_tabletype_t::new(TableType::new(
(*valtype).into(), (*valtype).into(),
limits.min as _, limits.min as _,

View File

@@ -50,7 +50,9 @@ pub struct wasm_valtype_t {
impl Default for wasm_valtype_t { impl Default for wasm_valtype_t {
fn default() -> Self { fn default() -> Self {
Self { valkind: wasm_valkind_enum::WASM_I32 } Self {
valkind: wasm_valkind_enum::WASM_I32,
}
} }
} }
@@ -70,7 +72,9 @@ impl From<&wasm_valtype_t> for ValType {
impl From<ValType> for wasm_valtype_t { impl From<ValType> for wasm_valtype_t {
fn from(other: ValType) -> Self { fn from(other: ValType) -> Self {
Self { valkind: other.into() } Self {
valkind: other.into(),
}
} }
} }
@@ -87,5 +91,7 @@ pub unsafe extern "C" fn wasm_valtype_delete(_valtype: Option<Box<wasm_valtype_t
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn wasm_valtype_kind(valtype: Option<&wasm_valtype_t>) -> wasm_valkind_t { pub unsafe extern "C" fn wasm_valtype_kind(valtype: Option<&wasm_valtype_t>) -> wasm_valkind_t {
valtype.expect("`wasm_valtype_kind: argument is a null pointer").valkind as wasm_valkind_t valtype
.expect("`wasm_valtype_kind: argument is a null pointer")
.valkind as wasm_valkind_t
} }

View File

@@ -133,7 +133,10 @@ mod tests {
#[test] #[test]
fn test_wasmer_is_headless() { fn test_wasmer_is_headless() {
set_var("COMPILER", if cfg!(feature = "compiler") { "0" } else { "1" }); set_var(
"COMPILER",
if cfg!(feature = "compiler") { "0" } else { "1" },
);
(assert_c! { (assert_c! {
#include "tests/wasmer_wasm.h" #include "tests/wasmer_wasm.h"
@@ -152,9 +155,23 @@ mod tests {
#[test] #[test]
fn test_wasmer_is_compiler_available() { fn test_wasmer_is_compiler_available() {
set_var("CRANELIFT", if cfg!(feature = "cranelift") { "1" } else { "0" }); set_var(
"CRANELIFT",
if cfg!(feature = "cranelift") {
"1"
} else {
"0"
},
);
set_var("LLVM", if cfg!(feature = "llvm") { "1" } else { "0" }); set_var("LLVM", if cfg!(feature = "llvm") { "1" } else { "0" });
set_var("SINGLEPASS", if cfg!(feature = "singlepass") { "1" } else { "0" }); set_var(
"SINGLEPASS",
if cfg!(feature = "singlepass") {
"1"
} else {
"0"
},
);
(assert_c! { (assert_c! {
#include "tests/wasmer_wasm.h" #include "tests/wasmer_wasm.h"
@@ -179,7 +196,14 @@ mod tests {
fn test_wasmer_is_engine_available() { fn test_wasmer_is_engine_available() {
set_var("JIT", if cfg!(feature = "jit") { "1" } else { "0" }); set_var("JIT", if cfg!(feature = "jit") { "1" } else { "0" });
set_var("NATIVE", if cfg!(feature = "native") { "1" } else { "0" }); set_var("NATIVE", if cfg!(feature = "native") { "1" } else { "0" });
set_var("OBJECT_FILE", if cfg!(feature = "object-file") { "1" } else { "0" }); set_var(
"OBJECT_FILE",
if cfg!(feature = "object-file") {
"1"
} else {
"0"
},
);
(assert_c! { (assert_c! {
#include "tests/wasmer_wasm.h" #include "tests/wasmer_wasm.h"

View File

@@ -55,7 +55,9 @@ pub struct wasmer_features_t {
/// See the module's documentation. /// See the module's documentation.
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_features_new() -> Box<wasmer_features_t> { pub extern "C" fn wasmer_features_new() -> Box<wasmer_features_t> {
Box::new(wasmer_features_t { inner: Features::new() }) Box::new(wasmer_features_t {
inner: Features::new(),
})
} }
/// Delete a [`wasmer_features_t`]. /// Delete a [`wasmer_features_t`].

View File

@@ -215,7 +215,10 @@ pub extern "C" fn wasmer_metering_get_remaining_points(instance: &wasm_instance_
/// See module's documentation. /// See module's documentation.
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_t) -> bool { pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_t) -> bool {
matches!(get_remaining_points(&instance.inner), MeteringPoints::Exhausted,) matches!(
get_remaining_points(&instance.inner),
MeteringPoints::Exhausted,
)
} }
/// Set a new amount of points for the given metering middleware. /// Set a new amount of points for the given metering middleware.
@@ -310,5 +313,7 @@ pub extern "C" fn wasmer_metering_as_middleware(
) -> Option<Box<wasmer_middleware_t>> { ) -> Option<Box<wasmer_middleware_t>> {
let metering = metering?; let metering = metering?;
Some(Box::new(wasmer_middleware_t { inner: metering.inner })) Some(Box::new(wasmer_middleware_t {
inner: metering.inner,
}))
} }

View File

@@ -147,7 +147,10 @@ pub unsafe extern "C" fn wasmer_triple_new(
triple: Option<&wasm_name_t>, triple: Option<&wasm_name_t>,
) -> Option<Box<wasmer_triple_t>> { ) -> Option<Box<wasmer_triple_t>> {
let triple = triple?; let triple = triple?;
let triple = c_try!(str::from_utf8(slice::from_raw_parts(triple.data, triple.size))); let triple = c_try!(str::from_utf8(slice::from_raw_parts(
triple.data,
triple.size
)));
Some(Box::new(wasmer_triple_t { Some(Box::new(wasmer_triple_t {
inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })), inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })),
@@ -180,7 +183,9 @@ pub unsafe extern "C" fn wasmer_triple_new(
/// See also [`wasmer_triple_new`]. /// See also [`wasmer_triple_new`].
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_triple_new_from_host() -> Box<wasmer_triple_t> { pub extern "C" fn wasmer_triple_new_from_host() -> Box<wasmer_triple_t> {
Box::new(wasmer_triple_t { inner: Triple::host() }) Box::new(wasmer_triple_t {
inner: Triple::host(),
})
} }
/// Delete a [`wasmer_triple_t`]. /// Delete a [`wasmer_triple_t`].
@@ -260,7 +265,9 @@ pub struct wasmer_cpu_features_t {
/// See [`wasmer_cpu_features_t`]. /// See [`wasmer_cpu_features_t`].
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_cpu_features_new() -> Box<wasmer_cpu_features_t> { pub extern "C" fn wasmer_cpu_features_new() -> Box<wasmer_cpu_features_t> {
Box::new(wasmer_cpu_features_t { inner: CpuFeature::set() }) Box::new(wasmer_cpu_features_t {
inner: CpuFeature::set(),
})
} }
/// Delete a [`wasmer_cpu_features_t`]. /// Delete a [`wasmer_cpu_features_t`].

View File

@@ -171,9 +171,11 @@ fn wasi_get_unordered_imports_inner(
let store = &store.inner; let store = &store.inner;
let version = c_try!(get_wasi_version(&module.inner, false).ok_or_else(|| CApiError { let version = c_try!(
msg: "could not detect a WASI version on the given module".to_string(), get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
})); msg: "could not detect a WASI version on the given module".to_string(),
})
);
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version); let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);

View File

@@ -114,7 +114,10 @@ wasm_declare_vec!(val);
impl Clone for wasm_val_t { impl Clone for wasm_val_t {
fn clone(&self) -> Self { fn clone(&self) -> Self {
wasm_val_t { kind: self.kind, of: self.of.clone() } wasm_val_t {
kind: self.kind,
of: self.of.clone(),
}
} }
} }
@@ -127,10 +130,18 @@ pub unsafe extern "C" fn wasm_val_copy(
out.kind = val.kind; out.kind = val.kind;
out.of = match val.kind.try_into() { out.of = match val.kind.try_into() {
Ok(kind) => match kind { Ok(kind) => match kind {
wasm_valkind_enum::WASM_I32 => wasm_val_inner { int32_t: val.of.int32_t }, wasm_valkind_enum::WASM_I32 => wasm_val_inner {
wasm_valkind_enum::WASM_I64 => wasm_val_inner { int64_t: val.of.int64_t }, int32_t: val.of.int32_t,
wasm_valkind_enum::WASM_F32 => wasm_val_inner { float32_t: val.of.float32_t }, },
wasm_valkind_enum::WASM_F64 => wasm_val_inner { float64_t: val.of.float64_t }, wasm_valkind_enum::WASM_I64 => wasm_val_inner {
int64_t: val.of.int64_t,
},
wasm_valkind_enum::WASM_F32 => wasm_val_inner {
float32_t: val.of.float32_t,
},
wasm_valkind_enum::WASM_F64 => wasm_val_inner {
float64_t: val.of.float64_t,
},
wasm_valkind_enum::WASM_ANYREF => wasm_val_inner { wref: val.of.wref }, wasm_valkind_enum::WASM_ANYREF => wasm_val_inner { wref: val.of.wref },
wasm_valkind_enum::WASM_FUNCREF => wasm_val_inner { wref: val.of.wref }, wasm_valkind_enum::WASM_FUNCREF => wasm_val_inner { wref: val.of.wref },
}, },

View File

@@ -13,7 +13,9 @@ pub struct OutputCapturer {
impl OutputCapturer { impl OutputCapturer {
pub fn new() -> Self { pub fn new() -> Self {
Self { buffer: VecDeque::new() } Self {
buffer: VecDeque::new(),
}
} }
} }
@@ -46,21 +48,36 @@ impl WasiFile for OutputCapturer {
// fail when reading or Seeking // fail when reading or Seeking
impl Read for OutputCapturer { impl Read for OutputCapturer {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other, "can not read from capturing stdout")) Err(io::Error::new(
io::ErrorKind::Other,
"can not read from capturing stdout",
))
} }
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> std::io::Result<usize> { fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> std::io::Result<usize> {
Err(std::io::Error::new(std::io::ErrorKind::Other, "can not read from capturing stdout")) Err(std::io::Error::new(
std::io::ErrorKind::Other,
"can not read from capturing stdout",
))
} }
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> { fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other, "can not read from capturing stdout")) Err(io::Error::new(
io::ErrorKind::Other,
"can not read from capturing stdout",
))
} }
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> { fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
Err(io::Error::new(io::ErrorKind::Other, "can not read from capturing stdout")) Err(io::Error::new(
io::ErrorKind::Other,
"can not read from capturing stdout",
))
} }
} }
impl Seek for OutputCapturer { impl Seek for OutputCapturer {
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> { fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
Err(io::Error::new(io::ErrorKind::Other, "can not seek capturing stdout")) Err(io::Error::new(
io::ErrorKind::Other,
"can not seek capturing stdout",
))
} }
} }
impl Write for OutputCapturer { impl Write for OutputCapturer {

View File

@@ -175,18 +175,24 @@ pub struct wasi_env_t {
#[no_mangle] #[no_mangle]
pub extern "C" fn wasi_env_new(mut config: Box<wasi_config_t>) -> Option<Box<wasi_env_t>> { pub extern "C" fn wasi_env_new(mut config: Box<wasi_config_t>) -> Option<Box<wasi_env_t>> {
if !config.inherit_stdout { if !config.inherit_stdout {
config.state_builder.stdout(Box::new(capture_files::OutputCapturer::new())); config
.state_builder
.stdout(Box::new(capture_files::OutputCapturer::new()));
} }
if !config.inherit_stderr { if !config.inherit_stderr {
config.state_builder.stderr(Box::new(capture_files::OutputCapturer::new())); config
.state_builder
.stderr(Box::new(capture_files::OutputCapturer::new()));
} }
// TODO: impl capturer for stdin // TODO: impl capturer for stdin
let wasi_state = c_try!(config.state_builder.build()); let wasi_state = c_try!(config.state_builder.build());
Some(Box::new(wasi_env_t { inner: WasiEnv::new(wasi_state) })) Some(Box::new(wasi_env_t {
inner: WasiEnv::new(wasi_state),
}))
} }
/// Delete a [`wasi_env_t`]. /// Delete a [`wasi_env_t`].
@@ -266,7 +272,10 @@ fn read_inner(wasi_file: &mut Box<dyn WasiFile>, inner_buffer: &mut [u8]) -> isi
if let Some(oc) = wasi_file.downcast_mut::<capture_files::OutputCapturer>() { if let Some(oc) = wasi_file.downcast_mut::<capture_files::OutputCapturer>() {
let total_to_read = min(inner_buffer.len(), oc.buffer.len()); let total_to_read = min(inner_buffer.len(), oc.buffer.len());
for (address, value) in inner_buffer.iter_mut().zip(oc.buffer.drain(..total_to_read)) { for (address, value) in inner_buffer
.iter_mut()
.zip(oc.buffer.drain(..total_to_read))
{
*address = value; *address = value;
} }
@@ -358,9 +367,11 @@ fn wasi_get_imports_inner(
let store = &store.inner; let store = &store.inner;
let version = c_try!(get_wasi_version(&module.inner, false).ok_or_else(|| CApiError { let version = c_try!(
msg: "could not detect a WASI version on the given module".to_string(), get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
})); msg: "could not detect a WASI version on the given module".to_string(),
})
);
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version); let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);

View File

@@ -18,9 +18,11 @@ pub fn store_cache_jit(c: &mut Criterion) {
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
let compiler = Singlepass::default(); let compiler = Singlepass::default();
let store = Store::new(&JIT::new(compiler).engine()); let store = Store::new(&JIT::new(compiler).engine());
let module = let module = Module::new(
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap()) &store,
.unwrap(); std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
)
.unwrap();
c.bench_function("store jit module in filesystem cache", |b| { c.bench_function("store jit module in filesystem cache", |b| {
b.iter(|| { b.iter(|| {
@@ -35,9 +37,11 @@ pub fn load_cache_jit(c: &mut Criterion) {
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
let compiler = Singlepass::default(); let compiler = Singlepass::default();
let store = Store::new(&JIT::new(compiler).engine()); let store = Store::new(&JIT::new(compiler).engine());
let module = let module = Module::new(
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap()) &store,
.unwrap(); std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
)
.unwrap();
let key = Hash::new([0u8; 32]); let key = Hash::new([0u8; 32]);
fs_cache.store(key, &module).unwrap(); fs_cache.store(key, &module).unwrap();
@@ -51,9 +55,11 @@ pub fn store_cache_native(c: &mut Criterion) {
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
let compiler = Singlepass::default(); let compiler = Singlepass::default();
let store = Store::new(&Native::new(compiler).engine()); let store = Store::new(&Native::new(compiler).engine());
let module = let module = Module::new(
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap()) &store,
.unwrap(); std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
)
.unwrap();
c.bench_function("store native module in filesystem cache", |b| { c.bench_function("store native module in filesystem cache", |b| {
b.iter(|| { b.iter(|| {
@@ -68,9 +74,11 @@ pub fn load_cache_native(c: &mut Criterion) {
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
let compiler = Singlepass::default(); let compiler = Singlepass::default();
let store = Store::new(&Native::new(compiler).engine()); let store = Store::new(&Native::new(compiler).engine());
let module = let module = Module::new(
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap()) &store,
.unwrap(); std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
)
.unwrap();
let key = Hash::new([0u8; 32]); let key = Hash::new([0u8; 32]);
fs_cache.store(key, &module).unwrap(); fs_cache.store(key, &module).unwrap();

View File

@@ -55,7 +55,10 @@ impl FileSystemCache {
// This path points to a file. // This path points to a file.
Err(io::Error::new( Err(io::Error::new(
io::ErrorKind::PermissionDenied, io::ErrorKind::PermissionDenied,
format!("the supplied path already points to a file: {}", path.display()), format!(
"the supplied path already points to a file: {}",
path.display()
),
)) ))
} }
} else { } else {

View File

@@ -59,13 +59,19 @@ pub enum CType {
impl CType { impl CType {
/// Convenience function to get a mutable void pointer type. /// Convenience function to get a mutable void pointer type.
pub fn void_ptr() -> Self { pub fn void_ptr() -> Self {
CType::PointerTo { is_const: false, inner: Box::new(CType::Void) } CType::PointerTo {
is_const: false,
inner: Box::new(CType::Void),
}
} }
/// Convenience function to get a const void pointer type. /// Convenience function to get a const void pointer type.
#[allow(dead_code)] #[allow(dead_code)]
pub fn const_void_ptr() -> Self { pub fn const_void_ptr() -> Self {
CType::PointerTo { is_const: true, inner: Box::new(CType::Void) } CType::PointerTo {
is_const: true,
inner: Box::new(CType::Void),
}
} }
/// Generate the C source code for a type into the given `String`. /// Generate the C source code for a type into the given `String`.
@@ -111,10 +117,15 @@ impl CType {
Self::ISize => { Self::ISize => {
w.push_str("size_t"); w.push_str("size_t");
} }
Self::Function { arguments, return_value } => { Self::Function {
arguments,
return_value,
} => {
// function with no, name, assume it's a function pointer // function with no, name, assume it's a function pointer
let ret: CType = let ret: CType = return_value
return_value.as_ref().map(|i: &Box<CType>| (&**i).clone()).unwrap_or_default(); .as_ref()
.map(|i: &Box<CType>| (&**i).clone())
.unwrap_or_default();
ret.generate_c(w); ret.generate_c(w);
w.push(' '); w.push(' ');
w.push_str("(*)"); w.push_str("(*)");
@@ -160,9 +171,14 @@ impl CType {
w.push(' '); w.push(' ');
w.push_str(name); w.push_str(name);
} }
Self::Function { arguments, return_value } => { Self::Function {
let ret: CType = arguments,
return_value.as_ref().map(|i: &Box<CType>| (&**i).clone()).unwrap_or_default(); return_value,
} => {
let ret: CType = return_value
.as_ref()
.map(|i: &Box<CType>| (&**i).clone())
.unwrap_or_default();
ret.generate_c(w); ret.generate_c(w);
w.push(' '); w.push(' ');
w.push_str(&name); w.push_str(&name);
@@ -248,7 +264,13 @@ impl CStatement {
/// Generate C source code for the given CStatement. /// Generate C source code for the given CStatement.
fn generate_c(&self, w: &mut String) { fn generate_c(&self, w: &mut String) {
match &self { match &self {
Self::Declaration { name, is_extern, is_const, ctype, definition } => { Self::Declaration {
name,
is_extern,
is_const,
ctype,
definition,
} => {
if *is_const { if *is_const {
w.push_str("const "); w.push_str("const ");
} }
@@ -279,14 +301,20 @@ impl CStatement {
Self::LiteralConstant { value } => { Self::LiteralConstant { value } => {
w.push_str(&value); w.push_str(&value);
} }
Self::Cast { target_type, expression } => { Self::Cast {
target_type,
expression,
} => {
w.push('('); w.push('(');
target_type.generate_c(w); target_type.generate_c(w);
w.push(')'); w.push(')');
w.push(' '); w.push(' ');
expression.generate_c(w); expression.generate_c(w);
} }
Self::TypeDef { source_type, new_name } => { Self::TypeDef {
source_type,
new_name,
} => {
w.push_str("typedef "); w.push_str("typedef ");
// leaky abstraction / hack, doesn't fully solve the problem // leaky abstraction / hack, doesn't fully solve the problem
if let CType::Function { .. } = source_type { if let CType::Function { .. } = source_type {
@@ -343,17 +371,26 @@ mod test {
assert_c_type!(CType::ISize, "size_t"); assert_c_type!(CType::ISize, "size_t");
assert_c_type!(CType::TypeDef("my_type".to_string()), "my_type"); assert_c_type!(CType::TypeDef("my_type".to_string()), "my_type");
assert_c_type!( assert_c_type!(
CType::Function { arguments: vec![CType::U8, CType::ISize], return_value: None }, CType::Function {
arguments: vec![CType::U8, CType::ISize],
return_value: None
},
"void (*)(unsigned char, size_t)" "void (*)(unsigned char, size_t)"
); );
assert_c_type!( assert_c_type!(
CType::Function { arguments: vec![], return_value: Some(Box::new(CType::ISize)) }, CType::Function {
arguments: vec![],
return_value: Some(Box::new(CType::ISize))
},
"size_t (*)()" "size_t (*)()"
); );
assert_c_type!( assert_c_type!(
CType::PointerTo { CType::PointerTo {
is_const: true, is_const: true,
inner: Box::new(CType::PointerTo { is_const: false, inner: Box::new(CType::U32) }) inner: Box::new(CType::PointerTo {
is_const: false,
inner: Box::new(CType::U32)
})
}, },
"const unsigned int**" "const unsigned int**"
); );
@@ -384,21 +421,34 @@ mod test {
assert_c_type!(CType::I32, "data", "int data"); assert_c_type!(CType::I32, "data", "int data");
assert_c_type!(CType::I64, "data", "long long data"); assert_c_type!(CType::I64, "data", "long long data");
assert_c_type!(CType::ISize, "data", "size_t data"); assert_c_type!(CType::ISize, "data", "size_t data");
assert_c_type!(CType::TypeDef("my_type".to_string()), "data", "my_type data");
assert_c_type!( assert_c_type!(
CType::Function { arguments: vec![CType::U8, CType::ISize], return_value: None }, CType::TypeDef("my_type".to_string()),
"data",
"my_type data"
);
assert_c_type!(
CType::Function {
arguments: vec![CType::U8, CType::ISize],
return_value: None
},
"my_func", "my_func",
"void my_func(unsigned char, size_t)" "void my_func(unsigned char, size_t)"
); );
assert_c_type!( assert_c_type!(
CType::Function { arguments: vec![], return_value: Some(Box::new(CType::ISize)) }, CType::Function {
arguments: vec![],
return_value: Some(Box::new(CType::ISize))
},
"my_func", "my_func",
"size_t my_func()" "size_t my_func()"
); );
assert_c_type!( assert_c_type!(
CType::PointerTo { CType::PointerTo {
is_const: true, is_const: true,
inner: Box::new(CType::PointerTo { is_const: false, inner: Box::new(CType::U32) }) inner: Box::new(CType::PointerTo {
is_const: false,
inner: Box::new(CType::U32)
})
}, },
"data", "data",
"const unsigned int** data" "const unsigned int** data"
@@ -418,7 +468,9 @@ mod test {
} }
assert_c_expr!( assert_c_expr!(
CStatement::LiteralConstant { value: "\"Hello, world!\"".to_string() }, CStatement::LiteralConstant {
value: "\"Hello, world!\"".to_string()
},
"\"Hello, world!\"" "\"Hello, world!\""
); );
assert_c_expr!( assert_c_expr!(
@@ -434,9 +486,15 @@ mod test {
assert_c_expr!( assert_c_expr!(
CStatement::LiteralArray { CStatement::LiteralArray {
items: vec![ items: vec![
CStatement::LiteralConstant { value: "1".to_string() }, CStatement::LiteralConstant {
CStatement::LiteralConstant { value: "2".to_string() }, value: "1".to_string()
CStatement::LiteralConstant { value: "3".to_string() }, },
CStatement::LiteralConstant {
value: "2".to_string()
},
CStatement::LiteralConstant {
value: "3".to_string()
},
] ]
}, },
"{\n\t1,\n\t2,\n\t3,\n}" "{\n\t1,\n\t2,\n\t3,\n}"
@@ -447,12 +505,20 @@ mod test {
name: "my_array".to_string(), name: "my_array".to_string(),
is_extern: false, is_extern: false,
is_const: true, is_const: true,
ctype: CType::Array { inner: Box::new(CType::I32) }, ctype: CType::Array {
inner: Box::new(CType::I32)
},
definition: Some(Box::new(CStatement::LiteralArray { definition: Some(Box::new(CStatement::LiteralArray {
items: vec![ items: vec![
CStatement::LiteralConstant { value: "1".to_string() }, CStatement::LiteralConstant {
CStatement::LiteralConstant { value: "2".to_string() }, value: "1".to_string()
CStatement::LiteralConstant { value: "3".to_string() }, },
CStatement::LiteralConstant {
value: "2".to_string()
},
CStatement::LiteralConstant {
value: "3".to_string()
},
] ]
})) }))
}, },
@@ -463,7 +529,9 @@ mod test {
name: "my_array".to_string(), name: "my_array".to_string(),
is_extern: true, is_extern: true,
is_const: true, is_const: true,
ctype: CType::Array { inner: Box::new(CType::I32) }, ctype: CType::Array {
inner: Box::new(CType::I32)
},
definition: None, definition: None,
}, },
"const extern int my_array[];\n" "const extern int my_array[];\n"

View File

@@ -94,7 +94,9 @@ pub fn generate_header_file(
name: "WASMER_METADATA".to_string(), name: "WASMER_METADATA".to_string(),
is_extern: true, is_extern: true,
is_const: true, is_const: true,
ctype: CType::Array { inner: Box::new(CType::U8) }, ctype: CType::Array {
inner: Box::new(CType::U8),
},
definition: None, definition: None,
}); });
let function_declarations = module_info let function_declarations = module_info
@@ -111,7 +113,10 @@ pub fn generate_header_file(
name: function_name, name: function_name,
is_extern: false, is_extern: false,
is_const: false, is_const: false,
ctype: CType::Function { arguments: vec![CType::Void], return_value: None }, ctype: CType::Function {
arguments: vec![CType::Void],
return_value: None,
},
definition: None, definition: None,
} }
}); });
@@ -139,7 +144,9 @@ pub fn generate_header_file(
CStatement::Cast { CStatement::Cast {
target_type: CType::void_ptr(), target_type: CType::void_ptr(),
expression: Box::new(CStatement::LiteralConstant { value: function_name }), expression: Box::new(CStatement::LiteralConstant {
value: function_name,
}),
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -148,7 +155,9 @@ pub fn generate_header_file(
name: "function_pointers".to_string(), name: "function_pointers".to_string(),
is_extern: false, is_extern: false,
is_const: true, is_const: true,
ctype: CType::Array { inner: Box::new(CType::void_ptr()) }, ctype: CType::Array {
inner: Box::new(CType::void_ptr()),
},
definition: Some(Box::new(CStatement::LiteralArray { definition: Some(Box::new(CStatement::LiteralArray {
items: function_pointer_array_statements, items: function_pointer_array_statements,
})), })),
@@ -156,21 +165,24 @@ pub fn generate_header_file(
} }
let func_trampoline_declarations = let func_trampoline_declarations =
module_info.signatures.iter().map(|(sig_index, _func_type)| { module_info
let function_name = .signatures
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index)); .iter()
.map(|(sig_index, _func_type)| {
let function_name =
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
CStatement::Declaration { CStatement::Declaration {
name: function_name, name: function_name,
is_extern: false, is_extern: false,
is_const: false, is_const: false,
ctype: CType::Function { ctype: CType::Function {
arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()], arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
return_value: None, return_value: None,
}, },
definition: None, definition: None,
} }
}); });
c_statements.push(CStatement::LiteralConstant { c_statements.push(CStatement::LiteralConstant {
value: r#" value: r#"
// Trampolines (functions by which we can call into Wasm) ordered by signature. // Trampolines (functions by which we can call into Wasm) ordered by signature.
@@ -189,7 +201,9 @@ pub fn generate_header_file(
.map(|(sig_index, _vm_shared_index)| { .map(|(sig_index, _vm_shared_index)| {
let function_name = let function_name =
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index)); symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
CStatement::LiteralConstant { value: function_name } CStatement::LiteralConstant {
value: function_name,
}
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -197,15 +211,20 @@ pub fn generate_header_file(
name: "function_trampolines".to_string(), name: "function_trampolines".to_string(),
is_extern: false, is_extern: false,
is_const: true, is_const: true,
ctype: CType::Array { inner: Box::new(CType::void_ptr()) }, ctype: CType::Array {
inner: Box::new(CType::void_ptr()),
},
definition: Some(Box::new(CStatement::LiteralArray { definition: Some(Box::new(CStatement::LiteralArray {
items: function_trampoline_statements, items: function_trampoline_statements,
})), })),
}); });
} }
let dyn_func_declarations = let dyn_func_declarations = module_info
module_info.functions.keys().take(module_info.num_imported_functions).map(|func_index| { .functions
.keys()
.take(module_info.num_imported_functions)
.map(|func_index| {
let function_name = let function_name =
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index)); symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
// TODO: figure out the signature here // TODO: figure out the signature here
@@ -247,7 +266,9 @@ pub fn generate_header_file(
.map(|func_index| { .map(|func_index| {
let function_name = let function_name =
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index)); symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
CStatement::LiteralConstant { value: function_name } CStatement::LiteralConstant {
value: function_name,
}
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
c_statements.push(CStatement::Declaration { c_statements.push(CStatement::Declaration {
@@ -263,7 +284,9 @@ pub fn generate_header_file(
}); });
} }
c_statements.push(CStatement::LiteralConstant { value: HELPER_FUNCTIONS.to_string() }); c_statements.push(CStatement::LiteralConstant {
value: HELPER_FUNCTIONS.to_string(),
});
c_statements.push(CStatement::LiteralConstant { c_statements.push(CStatement::LiteralConstant {
value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(), value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(),

View File

@@ -19,7 +19,11 @@ use clap::{Clap, ErrorKind};
)] )]
#[cfg_attr( #[cfg_attr(
feature = "headless", feature = "headless",
clap(name = "wasmer-headless", about = "Headless WebAssembly standalone runtime.", author) clap(
name = "wasmer-headless",
about = "Headless WebAssembly standalone runtime.",
author
)
)] )]
/// The options for the wasmer Command Line Interface /// The options for the wasmer Command Line Interface
enum WasmerCLIOptions { enum WasmerCLIOptions {

View File

@@ -34,7 +34,8 @@ pub struct Compile {
impl Compile { impl Compile {
/// Runs logic for the `compile` subcommand /// Runs logic for the `compile` subcommand
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to compile `{}`", self.path.display())) self.inner_execute()
.context(format!("failed to compile `{}`", self.path.display()))
} }
pub(crate) fn get_recommend_extension( pub(crate) fn get_recommend_extension(
@@ -62,8 +63,11 @@ impl Compile {
.target_triple .target_triple
.as_ref() .as_ref()
.map(|target_triple| { .map(|target_triple| {
let mut features = let mut features = self
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b); .cpu_features
.clone()
.into_iter()
.fold(CpuFeature::set(), |a, b| a | b);
// Cranelift requires SSE2, so we have this "hack" for now to facilitate // Cranelift requires SSE2, so we have this "hack" for now to facilitate
// usage // usage
features |= CpuFeature::SSE2; features |= CpuFeature::SSE2;
@@ -94,7 +98,10 @@ impl Compile {
let module = Module::from_file(&store, &self.path)?; let module = Module::from_file(&store, &self.path)?;
let _ = module.serialize_to_file(&self.output)?; let _ = module.serialize_to_file(&self.output)?;
eprintln!("✔ File compiled successfully to `{}`.", self.output.display(),); eprintln!(
"✔ File compiled successfully to `{}`.",
self.output.display(),
);
#[cfg(feature = "object-file")] #[cfg(feature = "object-file")]
if engine_type == EngineType::ObjectFile { if engine_type == EngineType::ObjectFile {
@@ -128,7 +135,10 @@ impl Compile {
use std::io::Write; use std::io::Write;
header.write_all(header_file_src.as_bytes())?; header.write_all(header_file_src.as_bytes())?;
eprintln!("✔ Header file generated successfully at `{}`.", header_path.display(),); eprintln!(
"✔ Header file generated successfully at `{}`.",
header_path.display(),
);
} }
Ok(()) Ok(())
} }

View File

@@ -40,13 +40,21 @@ pub struct Config {
impl Config { impl Config {
/// Runs logic for the `config` subcommand /// Runs logic for the `config` subcommand
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
self.inner_execute().context("failed to retrieve the wasmer config".to_string()) self.inner_execute()
.context("failed to retrieve the wasmer config".to_string())
} }
fn inner_execute(&self) -> Result<()> { fn inner_execute(&self) -> Result<()> {
let key = "WASMER_DIR"; let key = "WASMER_DIR";
let wasmer_dir = env::var(key) let wasmer_dir = env::var(key)
.or_else(|e| option_env!("WASMER_INSTALL_PREFIX").map(str::to_string).ok_or(e)) .or_else(|e| {
.context(format!("failed to retrieve the {} environment variables", key))?; option_env!("WASMER_INSTALL_PREFIX")
.map(str::to_string)
.ok_or(e)
})
.context(format!(
"failed to retrieve the {} environment variables",
key
))?;
let prefix = PathBuf::from(wasmer_dir); let prefix = PathBuf::from(wasmer_dir);

View File

@@ -45,8 +45,11 @@ impl CreateExe {
.target_triple .target_triple
.as_ref() .as_ref()
.map(|target_triple| { .map(|target_triple| {
let mut features = let mut features = self
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b); .cpu_features
.clone()
.into_iter()
.fold(CpuFeature::set(), |a, b| a | b);
// Cranelift requires SSE2, so we have this "hack" for now to facilitate // Cranelift requires SSE2, so we have this "hack" for now to facilitate
// usage // usage
features |= CpuFeature::SSE2; features |= CpuFeature::SSE2;
@@ -54,8 +57,9 @@ impl CreateExe {
}) })
.unwrap_or_default(); .unwrap_or_default();
let engine_type = EngineType::ObjectFile; let engine_type = EngineType::ObjectFile;
let (store, compiler_type) = let (store, compiler_type) = self
self.compiler.get_store_for_target_and_engine(target.clone(), engine_type)?; .compiler
.get_store_for_target_and_engine(target.clone(), engine_type)?;
println!("Engine: {}", engine_type.to_string()); println!("Engine: {}", engine_type.to_string());
println!("Compiler: {}", compiler_type.to_string()); println!("Compiler: {}", compiler_type.to_string());
@@ -93,7 +97,10 @@ impl CreateExe {
generate_header(header_file_src.as_bytes())?; generate_header(header_file_src.as_bytes())?;
self.compile_c(wasm_object_path, output_path)?; self.compile_c(wasm_object_path, output_path)?;
eprintln!("✔ Native executable compiled successfully to `{}`.", self.output.display(),); eprintln!(
"✔ Native executable compiled successfully to `{}`.",
self.output.display(),
);
Ok(()) Ok(())
} }
@@ -149,7 +156,11 @@ fn generate_header(header_file_src: &[u8]) -> anyhow::Result<()> {
fn get_wasmer_dir() -> anyhow::Result<PathBuf> { fn get_wasmer_dir() -> anyhow::Result<PathBuf> {
Ok(PathBuf::from( Ok(PathBuf::from(
env::var("WASMER_DIR") env::var("WASMER_DIR")
.or_else(|e| option_env!("WASMER_INSTALL_PREFIX").map(str::to_string).ok_or(e)) .or_else(|e| {
option_env!("WASMER_INSTALL_PREFIX")
.map(str::to_string)
.ok_or(e)
})
.context("Trying to read env var `WASMER_DIR`")?, .context("Trying to read env var `WASMER_DIR`")?,
)) ))
} }
@@ -257,8 +268,17 @@ impl LinkCode {
let mut command = Command::new(&self.linker_path); let mut command = Command::new(&self.linker_path);
let command = command let command = command
.arg(&self.optimization_flag) .arg(&self.optimization_flag)
.args(self.object_paths.iter().map(|path| path.canonicalize().unwrap())) .args(
.arg(&self.libwasmer_path.canonicalize().context("Failed to find libwasmer")?); self.object_paths
.iter()
.map(|path| path.canonicalize().unwrap()),
)
.arg(
&self
.libwasmer_path
.canonicalize()
.context("Failed to find libwasmer")?,
);
let command = if let Some(target) = &self.target { let command = if let Some(target) = &self.target {
command.arg("-target").arg(format!("{}", target)) command.arg("-target").arg(format!("{}", target))
} else { } else {
@@ -267,12 +287,18 @@ impl LinkCode {
// Add libraries required per platform. // Add libraries required per platform.
// We need userenv, sockets (Ws2_32), advapi32 for some system calls and bcrypt for random numbers. // We need userenv, sockets (Ws2_32), advapi32 for some system calls and bcrypt for random numbers.
#[cfg(windows)] #[cfg(windows)]
let command = command.arg("-luserenv").arg("-lWs2_32").arg("-ladvapi32").arg("-lbcrypt"); let command = command
.arg("-luserenv")
.arg("-lWs2_32")
.arg("-ladvapi32")
.arg("-lbcrypt");
// On unix we need dlopen-related symbols, libmath for a few things, and pthreads. // On unix we need dlopen-related symbols, libmath for a few things, and pthreads.
#[cfg(not(windows))] #[cfg(not(windows))]
let command = command.arg("-ldl").arg("-lm").arg("-pthread"); let command = command.arg("-ldl").arg("-lm").arg("-pthread");
let link_aganist_extra_libs = let link_aganist_extra_libs = self
self.additional_libraries.iter().map(|lib| format!("-l{}", lib)); .additional_libraries
.iter()
.map(|lib| format!("-l{}", lib));
let command = command.args(link_aganist_extra_libs); let command = command.args(link_aganist_extra_libs);
let output = command.arg("-o").arg(&self.output_path).output()?; let output = command.arg("-o").arg(&self.output_path).output()?;

View File

@@ -19,13 +19,21 @@ pub struct Inspect {
impl Inspect { impl Inspect {
/// Runs logic for the `validate` subcommand /// Runs logic for the `validate` subcommand
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to inspect `{}`", self.path.display())) self.inner_execute()
.context(format!("failed to inspect `{}`", self.path.display()))
} }
fn inner_execute(&self) -> Result<()> { fn inner_execute(&self) -> Result<()> {
let (store, _engine_type, _compiler_type) = self.store.get_store()?; let (store, _engine_type, _compiler_type) = self.store.get_store()?;
let module_contents = std::fs::read(&self.path)?; let module_contents = std::fs::read(&self.path)?;
let module = Module::new(&store, &module_contents)?; let module = Module::new(&store, &module_contents)?;
println!("Type: {}", if !is_wasm(&module_contents) { "wat" } else { "wasm" }); println!(
"Type: {}",
if !is_wasm(&module_contents) {
"wat"
} else {
"wasm"
}
);
println!("Size: {}", ByteSize(module_contents.len() as _)); println!("Size: {}", ByteSize(module_contents.len() as _));
println!("Imports:"); println!("Imports:");
println!(" Functions:"); println!(" Functions:");

View File

@@ -80,7 +80,11 @@ impl Run {
format!( format!(
"failed to run `{}`{}", "failed to run `{}`{}",
self.path.display(), self.path.display(),
if CompilerType::enabled().is_empty() { " (no compilers enabled)" } else { "" } if CompilerType::enabled().is_empty() {
" (no compilers enabled)"
} else {
""
}
) )
}) })
} }
@@ -94,7 +98,11 @@ impl Run {
let result = self.invoke_function(&instance, &invoke, &self.args)?; let result = self.invoke_function(&instance, &invoke, &self.args)?;
println!( println!(
"{}", "{}",
result.iter().map(|val| val.to_string()).collect::<Vec<String>>().join(" ") result
.iter()
.map(|val| val.to_string())
.collect::<Vec<String>>()
.join(" ")
); );
return Ok(()); return Ok(());
} }
@@ -149,7 +157,11 @@ impl Run {
let program_name = self let program_name = self
.command_name .command_name
.clone() .clone()
.or_else(|| self.path.file_name().map(|f| f.to_string_lossy().to_string())) .or_else(|| {
self.path
.file_name()
.map(|f| f.to_string_lossy().to_string())
})
.unwrap_or_default(); .unwrap_or_default();
return self return self
.wasi .wasi
@@ -347,19 +359,31 @@ impl Run {
.iter() .iter()
.zip(func_ty.params().iter()) .zip(func_ty.params().iter())
.map(|(arg, param_type)| match param_type { .map(|(arg, param_type)| match param_type {
ValType::I32 => Ok(Val::I32( ValType::I32 => {
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a i32", arg))?, Ok(Val::I32(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a i32", arg)
})?))
}
ValType::I64 => {
Ok(Val::I64(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a i64", arg)
})?))
}
ValType::F32 => {
Ok(Val::F32(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a f32", arg)
})?))
}
ValType::F64 => {
Ok(Val::F64(arg.parse().map_err(|_| {
anyhow!("Can't convert `{}` into a f64", arg)
})?))
}
_ => Err(anyhow!(
"Don't know how to convert {} into {:?}",
arg,
param_type
)), )),
ValType::I64 => Ok(Val::I64(
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a i64", arg))?,
)),
ValType::F32 => Ok(Val::F32(
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a f32", arg))?,
)),
ValType::F64 => Ok(Val::F64(
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a f64", arg))?,
)),
_ => Err(anyhow!("Don't know how to convert {} into {:?}", arg, param_type)),
}) })
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
Ok(func.call(&invoke_args)?) Ok(func.call(&invoke_args)?)

View File

@@ -23,8 +23,10 @@ impl SelfUpdate {
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn()?; .spawn()?;
let mut process = let mut process = Command::new("sh")
Command::new("sh").stdin(cmd.stdout.unwrap()).stdout(Stdio::inherit()).spawn()?; .stdin(cmd.stdout.unwrap())
.stdout(Stdio::inherit())
.spawn()?;
process.wait().unwrap(); process.wait().unwrap();
Ok(()) Ok(())

View File

@@ -18,7 +18,8 @@ pub struct Validate {
impl Validate { impl Validate {
/// Runs logic for the `validate` subcommand /// Runs logic for the `validate` subcommand
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to validate `{}`", self.path.display())) self.inner_execute()
.context(format!("failed to validate `{}`", self.path.display()))
} }
fn inner_execute(&self) -> Result<()> { fn inner_execute(&self) -> Result<()> {
let (store, _engine_type, _compiler_type) = self.store.get_store()?; let (store, _engine_type, _compiler_type) = self.store.get_store()?;

View File

@@ -23,7 +23,8 @@ pub struct Wast {
impl Wast { impl Wast {
/// Runs logic for the `validate` subcommand /// Runs logic for the `validate` subcommand
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
self.inner_execute().context(format!("failed to test the wast `{}`", self.path.display())) self.inner_execute()
.context(format!("failed to test the wast `{}`", self.path.display()))
} }
fn inner_execute(&self) -> Result<()> { fn inner_execute(&self) -> Result<()> {
let (store, _engine_name, _compiler_name) = self.store.get_store()?; let (store, _engine_name, _compiler_name) = self.store.get_store()?;

View File

@@ -5,8 +5,10 @@ use std::time;
/// Subroutine to instantiate the loggers /// Subroutine to instantiate the loggers
pub fn set_up_logging() -> Result<(), String> { pub fn set_up_logging() -> Result<(), String> {
let colors_line = let colors_line = ColoredLevelConfig::new()
ColoredLevelConfig::new().error(Color::Red).warn(Color::Yellow).trace(Color::BrightBlack); .error(Color::Red)
.warn(Color::Yellow)
.trace(Color::BrightBlack);
let should_color = wasmer_should_print_color(); let should_color = wasmer_should_print_color();
let colors_level = colors_line.info(Color::Green); let colors_level = colors_line.info(Color::Green);

View File

@@ -73,7 +73,10 @@ impl CompilerOptions {
} else if self.singlepass { } else if self.singlepass {
Ok(CompilerType::Singlepass) Ok(CompilerType::Singlepass)
} else if let Some(backend) = self.backend.clone() { } else if let Some(backend) = self.backend.clone() {
warning!("the `--backend={0}` flag is deprecated, please use `--{0}` instead", backend); warning!(
"the `--backend={0}` flag is deprecated, please use `--{0}` instead",
backend
);
CompilerType::from_str(&backend) CompilerType::from_str(&backend)
} else { } else {
// Auto mode, we choose the best compiler for that platform // Auto mode, we choose the best compiler for that platform
@@ -155,7 +158,10 @@ impl CompilerOptions {
.engine(), .engine(),
), ),
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))] #[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
engine => bail!("The `{}` engine is not included in this binary.", engine.to_string()), engine => bail!(
"The `{}` engine is not included in this binary.",
engine.to_string()
),
}; };
Ok(engine) Ok(engine)
@@ -288,7 +294,10 @@ impl CompilerOptions {
} }
#[cfg(not(all(feature = "singlepass", feature = "cranelift", feature = "llvm",)))] #[cfg(not(all(feature = "singlepass", feature = "cranelift", feature = "llvm",)))]
compiler => { compiler => {
bail!("The `{}` compiler is not included in this binary.", compiler.to_string()) bail!(
"The `{}` compiler is not included in this binary.",
compiler.to_string()
)
} }
}; };
@@ -394,7 +403,9 @@ impl StoreOptions {
compiler_config: Box<dyn CompilerConfig>, compiler_config: Box<dyn CompilerConfig>,
) -> Result<(Box<dyn Engine + Send + Sync>, EngineType)> { ) -> Result<(Box<dyn Engine + Send + Sync>, EngineType)> {
let engine_type = self.get_engine()?; let engine_type = self.get_engine()?;
let engine = self.compiler.get_engine_by_type(target, compiler_config, engine_type)?; let engine = self
.compiler
.get_engine_by_type(target, compiler_config, engine_type)?;
Ok((engine, engine_type)) Ok((engine, engine_type))
} }
@@ -439,7 +450,10 @@ impl StoreOptions {
Arc::new(wasmer_engine_object_file::ObjectFile::headless().engine()) Arc::new(wasmer_engine_object_file::ObjectFile::headless().engine())
} }
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))] #[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
engine => bail!("The `{}` engine is not included in this binary.", engine.to_string()), engine => bail!(
"The `{}` engine is not included in this binary.",
engine.to_string()
),
}; };
Ok((engine, engine_type)) Ok((engine, engine_type))
} }

View File

@@ -84,6 +84,9 @@ mod tests {
); );
assert_eq!(parse_envvar("A=B").unwrap(), ("A".into(), "B".into())); assert_eq!(parse_envvar("A=B").unwrap(), ("A".into(), "B".into()));
assert_eq!(parse_envvar(" A=B\t").unwrap(), ("A".into(), "B".into())); assert_eq!(parse_envvar(" A=B\t").unwrap(), ("A".into(), "B".into()));
assert_eq!(parse_envvar("A=B=C=D").unwrap(), ("A".into(), "B=C=D".into())); assert_eq!(
parse_envvar("A=B=C=D").unwrap(),
("A".into(), "B=C=D".into())
);
} }
} }

View File

@@ -47,5 +47,11 @@ pub fn get_function_address_map<'data>(
let start_srcloc = SourceLoc::new(data.module_offset as u32); let start_srcloc = SourceLoc::new(data.module_offset as u32);
let end_srcloc = SourceLoc::new((data.module_offset + data.data.len()) as u32); let end_srcloc = SourceLoc::new((data.module_offset + data.data.len()) as u32);
FunctionAddressMap { instructions, start_srcloc, end_srcloc, body_offset: 0, body_len } FunctionAddressMap {
instructions,
start_srcloc,
end_srcloc,
body_offset: 0,
body_len,
}
} }

View File

@@ -178,10 +178,16 @@ impl Compiler for CraneliftCompiler {
let func_jt_offsets = transform_jump_table(context.func.jt_offsets); let func_jt_offsets = transform_jump_table(context.func.jt_offsets);
Ok(CompiledFunction { Ok(CompiledFunction {
body: FunctionBody { body: code_buf, unwind_info }, body: FunctionBody {
body: code_buf,
unwind_info,
},
jt_offsets: func_jt_offsets, jt_offsets: func_jt_offsets,
relocations: reloc_sink.func_relocs, relocations: reloc_sink.func_relocs,
frame_info: CompiledFunctionFrameInfo { address_map, traps: trap_sink.traps }, frame_info: CompiledFunctionFrameInfo {
address_map,
traps: trap_sink.traps,
},
}) })
}) })
.collect::<Result<Vec<_>, CompileError>>()? .collect::<Result<Vec<_>, CompileError>>()?
@@ -193,7 +199,11 @@ impl Compiler for CraneliftCompiler {
let mut custom_sections = PrimaryMap::new(); let mut custom_sections = PrimaryMap::new();
let dwarf = if let Some((dwarf_frametable, _cie_id)) = dwarf_frametable { let dwarf = if let Some((dwarf_frametable, _cie_id)) = dwarf_frametable {
let mut eh_frame = EhFrame(WriterRelocate::new(target.triple().endianness().ok())); let mut eh_frame = EhFrame(WriterRelocate::new(target.triple().endianness().ok()));
dwarf_frametable.lock().unwrap().write_eh_frame(&mut eh_frame).unwrap(); dwarf_frametable
.lock()
.unwrap()
.write_eh_frame(&mut eh_frame)
.unwrap();
let eh_frame_section = eh_frame.0.into_section(); let eh_frame_section = eh_frame.0.into_section();
custom_sections.push(eh_frame_section); custom_sections.push(eh_frame_section);

View File

@@ -113,10 +113,14 @@ impl Cranelift {
builder.enable("has_avx2").expect("should be valid flag"); builder.enable("has_avx2").expect("should be valid flag");
} }
if cpu_features.contains(CpuFeature::AVX512DQ) { if cpu_features.contains(CpuFeature::AVX512DQ) {
builder.enable("has_avx512dq").expect("should be valid flag"); builder
.enable("has_avx512dq")
.expect("should be valid flag");
} }
if cpu_features.contains(CpuFeature::AVX512VL) { if cpu_features.contains(CpuFeature::AVX512VL) {
builder.enable("has_avx512vl").expect("should be valid flag"); builder
.enable("has_avx512vl")
.expect("should be valid flag");
} }
if cpu_features.contains(CpuFeature::LZCNT) { if cpu_features.contains(CpuFeature::LZCNT) {
builder.enable("has_lzcnt").expect("should be valid flag"); builder.enable("has_lzcnt").expect("should be valid flag");
@@ -131,16 +135,26 @@ impl Cranelift {
// There are two possible traps for division, and this way // There are two possible traps for division, and this way
// we get the proper one if code traps. // we get the proper one if code traps.
flags.enable("avoid_div_traps").expect("should be valid flag"); flags
.enable("avoid_div_traps")
.expect("should be valid flag");
if self.enable_pic { if self.enable_pic {
flags.enable("is_pic").expect("should be a valid flag"); flags.enable("is_pic").expect("should be a valid flag");
} }
// Invert cranelift's default-on verification to instead default off. // Invert cranelift's default-on verification to instead default off.
let enable_verifier = if self.enable_verifier { "true" } else { "false" }; let enable_verifier = if self.enable_verifier {
flags.set("enable_verifier", enable_verifier).expect("should be valid flag"); "true"
flags.set("enable_safepoints", "true").expect("should be valid flag"); } else {
"false"
};
flags
.set("enable_verifier", enable_verifier)
.expect("should be valid flag");
flags
.set("enable_safepoints", "true")
.expect("should be valid flag");
let opt_level = if self.enable_simd { let opt_level = if self.enable_simd {
"none" "none"
@@ -152,13 +166,20 @@ impl Cranelift {
} }
}; };
flags.set("opt_level", opt_level).expect("should be valid flag"); flags
.set("opt_level", opt_level)
.expect("should be valid flag");
let enable_simd = if self.enable_simd { "true" } else { "false" }; let enable_simd = if self.enable_simd { "true" } else { "false" };
flags.set("enable_simd", enable_simd).expect("should be valid flag"); flags
.set("enable_simd", enable_simd)
.expect("should be valid flag");
let enable_nan_canonicalization = let enable_nan_canonicalization = if self.enable_nan_canonicalization {
if self.enable_nan_canonicalization { "true" } else { "false" }; "true"
} else {
"false"
};
flags flags
.set("enable_nan_canonicalization", enable_nan_canonicalization) .set("enable_nan_canonicalization", enable_nan_canonicalization)
.expect("should be valid flag"); .expect("should be valid flag");

View File

@@ -20,7 +20,10 @@ impl WriterRelocate {
// We autodetect it, based on the host // We autodetect it, based on the host
None => RunTimeEndian::default(), None => RunTimeEndian::default(),
}; };
WriterRelocate { relocs: Vec::new(), writer: EndianVec::new(endianness) } WriterRelocate {
relocs: Vec::new(),
writer: EndianVec::new(endianness),
}
} }
pub fn into_section(mut self) -> CustomSection { pub fn into_section(mut self) -> CustomSection {
@@ -69,7 +72,12 @@ impl Writer for WriterRelocate {
_ => unimplemented!("dwarf relocation size not yet supported: {}", size), _ => unimplemented!("dwarf relocation size not yet supported: {}", size),
}; };
let addend = 0; let addend = 0;
self.relocs.push(Relocation { kind, reloc_target, offset, addend }); self.relocs.push(Relocation {
kind,
reloc_target,
offset,
addend,
});
self.write_udata(addend as u64, size) self.write_udata(addend as u64, size)
} else { } else {
unreachable!("Symbol {} in DWARF not recognized", symbol); unreachable!("Symbol {} in DWARF not recognized", symbol);

View File

@@ -223,7 +223,10 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
&mut self, &mut self,
func: &mut Function, func: &mut Function,
) -> (ir::SigRef, VMBuiltinFunctionIndex) { ) -> (ir::SigRef, VMBuiltinFunctionIndex) {
(self.get_externref_inc_sig(func), VMBuiltinFunctionIndex::get_externref_inc_index()) (
self.get_externref_inc_sig(func),
VMBuiltinFunctionIndex::get_externref_inc_index(),
)
} }
fn get_externref_dec_sig(&mut self, func: &mut Function) -> ir::SigRef { fn get_externref_dec_sig(&mut self, func: &mut Function) -> ir::SigRef {
@@ -242,7 +245,10 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
&mut self, &mut self,
func: &mut Function, func: &mut Function,
) -> (ir::SigRef, VMBuiltinFunctionIndex) { ) -> (ir::SigRef, VMBuiltinFunctionIndex) {
(self.get_externref_dec_sig(func), VMBuiltinFunctionIndex::get_externref_dec_index()) (
self.get_externref_dec_sig(func),
VMBuiltinFunctionIndex::get_externref_dec_index(),
)
} }
fn get_func_ref_sig(&mut self, func: &mut Function) -> ir::SigRef { fn get_func_ref_sig(&mut self, func: &mut Function) -> ir::SigRef {
@@ -567,7 +573,11 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) { ) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
let sig = self.get_table_init_sig(func); let sig = self.get_table_init_sig(func);
let table_index = table_index.as_u32() as usize; let table_index = table_index.as_u32() as usize;
(sig, table_index, VMBuiltinFunctionIndex::get_table_init_index()) (
sig,
table_index,
VMBuiltinFunctionIndex::get_table_init_index(),
)
} }
fn get_elem_drop_sig(&mut self, func: &mut Function) -> ir::SigRef { fn get_elem_drop_sig(&mut self, func: &mut Function) -> ir::SigRef {
@@ -620,9 +630,17 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) { ) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
let sig = self.get_memory_copy_sig(func); let sig = self.get_memory_copy_sig(func);
if let Some(local_memory_index) = self.module.local_memory_index(memory_index) { if let Some(local_memory_index) = self.module.local_memory_index(memory_index) {
(sig, local_memory_index.index(), VMBuiltinFunctionIndex::get_memory_copy_index()) (
sig,
local_memory_index.index(),
VMBuiltinFunctionIndex::get_memory_copy_index(),
)
} else { } else {
(sig, memory_index.index(), VMBuiltinFunctionIndex::get_imported_memory_copy_index()) (
sig,
memory_index.index(),
VMBuiltinFunctionIndex::get_imported_memory_copy_index(),
)
} }
} }
@@ -655,9 +673,17 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) { ) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
let sig = self.get_memory_fill_sig(func); let sig = self.get_memory_fill_sig(func);
if let Some(local_memory_index) = self.module.local_memory_index(memory_index) { if let Some(local_memory_index) = self.module.local_memory_index(memory_index) {
(sig, local_memory_index.index(), VMBuiltinFunctionIndex::get_memory_fill_index()) (
sig,
local_memory_index.index(),
VMBuiltinFunctionIndex::get_memory_fill_index(),
)
} else { } else {
(sig, memory_index.index(), VMBuiltinFunctionIndex::get_imported_memory_fill_index()) (
sig,
memory_index.index(),
VMBuiltinFunctionIndex::get_imported_memory_fill_index(),
)
} }
} }
@@ -759,7 +785,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let base_offset = let base_offset =
i32::try_from(self.offsets.vmctx_vmtable_definition_base(def_index)).unwrap(); i32::try_from(self.offsets.vmctx_vmtable_definition_base(def_index)).unwrap();
let current_elements_offset = i32::try_from( let current_elements_offset = i32::try_from(
self.offsets.vmctx_vmtable_definition_current_elements(def_index), self.offsets
.vmctx_vmtable_definition_current_elements(def_index),
) )
.unwrap(); .unwrap();
(vmctx, base_offset, current_elements_offset) (vmctx, base_offset, current_elements_offset)
@@ -815,8 +842,11 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (func_sig, index_arg, func_idx) = self.get_table_grow_func(&mut pos.func, table_index); let (func_sig, index_arg, func_idx) = self.get_table_grow_func(&mut pos.func, table_index);
let table_index = pos.ins().iconst(I32, index_arg as i64); let table_index = pos.ins().iconst(I32, index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst = let call_inst = pos.ins().call_indirect(
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, init_value, delta, table_index]); func_sig,
func_addr,
&[vmctx, init_value, delta, table_index],
);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }
@@ -833,7 +863,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
self.get_table_get_func(&mut pos.func, table_index); self.get_table_get_func(&mut pos.func, table_index);
let table_index = pos.ins().iconst(I32, table_index_arg as i64); let table_index = pos.ins().iconst(I32, table_index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index, index]); let call_inst = pos
.ins()
.call_indirect(func_sig, func_addr, &[vmctx, table_index, index]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }
@@ -851,7 +883,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
self.get_table_set_func(&mut pos.func, table_index); self.get_table_set_func(&mut pos.func, table_index);
let table_index = pos.ins().iconst(I32, table_index_arg as i64); let table_index = pos.ins().iconst(I32, table_index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index, index, value]); pos.ins()
.call_indirect(func_sig, func_addr, &[vmctx, table_index, index, value]);
Ok(()) Ok(())
} }
@@ -868,7 +901,11 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let table_index_arg = pos.ins().iconst(I32, table_index_arg as i64); let table_index_arg = pos.ins().iconst(I32, table_index_arg as i64);
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index_arg, dst, val, len]); pos.ins().call_indirect(
func_sig,
func_addr,
&[vmctx, table_index_arg, dst, val, len],
);
Ok(()) Ok(())
} }
@@ -925,7 +962,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
ty if ty.is_ref() => pos.ins().is_null(value), ty if ty.is_ref() => pos.ins().is_null(value),
// `funcref` // `funcref`
ty if ty == self.pointer_type() => { ty if ty == self.pointer_type() => {
pos.ins().icmp_imm(cranelift_codegen::ir::condcodes::IntCC::Equal, value, 0) pos.ins()
.icmp_imm(cranelift_codegen::ir::condcodes::IntCC::Equal, value, 0)
} }
_ => unreachable!(), _ => unreachable!(),
}; };
@@ -951,7 +989,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let func_index_arg = pos.ins().iconst(I32, func_index_arg as i64); let func_index_arg = pos.ins().iconst(I32, func_index_arg as i64);
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, func_index_arg]); let call_inst = pos
.ins()
.call_indirect(func_sig, func_addr, &[vmctx, func_index_arg]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }
@@ -981,9 +1021,11 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
if let Some(def_index) = self.module.local_memory_index(index) { if let Some(def_index) = self.module.local_memory_index(index) {
let base_offset = let base_offset =
i32::try_from(self.offsets.vmctx_vmmemory_definition_base(def_index)).unwrap(); i32::try_from(self.offsets.vmctx_vmmemory_definition_base(def_index)).unwrap();
let current_length_offset = let current_length_offset = i32::try_from(
i32::try_from(self.offsets.vmctx_vmmemory_definition_current_length(def_index)) self.offsets
.unwrap(); .vmctx_vmmemory_definition_current_length(def_index),
)
.unwrap();
(vmctx, base_offset, current_length_offset) (vmctx, base_offset, current_length_offset)
} else { } else {
let from_offset = self.offsets.vmctx_vmmemory_import_definition(index); let from_offset = self.offsets.vmctx_vmmemory_import_definition(index);
@@ -1012,13 +1054,20 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
}); });
( (
Uimm64::new(offset_guard_size), Uimm64::new(offset_guard_size),
ir::HeapStyle::Dynamic { bound_gv: heap_bound }, ir::HeapStyle::Dynamic {
bound_gv: heap_bound,
},
false, false,
) )
} }
MemoryStyle::Static { bound, offset_guard_size } => ( MemoryStyle::Static {
bound,
offset_guard_size,
} => (
Uimm64::new(offset_guard_size), Uimm64::new(offset_guard_size),
ir::HeapStyle::Static { bound: Uimm64::new(bound.bytes().0 as u64) }, ir::HeapStyle::Static {
bound: Uimm64::new(bound.bytes().0 as u64),
},
true, true,
), ),
}; };
@@ -1118,7 +1167,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
); );
// check if the funcref is null // check if the funcref is null
pos.ins().trapz(table_entry_addr, ir::TrapCode::IndirectCallToNull); pos.ins()
.trapz(table_entry_addr, ir::TrapCode::IndirectCallToNull);
let func_addr = pos.ins().load( let func_addr = pos.ins().load(
pointer_type, pointer_type,
@@ -1233,7 +1283,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (func_sig, index_arg, func_idx) = self.get_memory_grow_func(&mut pos.func, index); let (func_sig, index_arg, func_idx) = self.get_memory_grow_func(&mut pos.func, index);
let memory_index = pos.ins().iconst(I32, index_arg as i64); let memory_index = pos.ins().iconst(I32, index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, val, memory_index]); let call_inst = pos
.ins()
.call_indirect(func_sig, func_addr, &[vmctx, val, memory_index]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }
@@ -1246,7 +1298,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (func_sig, index_arg, func_idx) = self.get_memory_size_func(&mut pos.func, index); let (func_sig, index_arg, func_idx) = self.get_memory_size_func(&mut pos.func, index);
let memory_index = pos.ins().iconst(I32, index_arg as i64); let memory_index = pos.ins().iconst(I32, index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, memory_index]); let call_inst = pos
.ins()
.call_indirect(func_sig, func_addr, &[vmctx, memory_index]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }
@@ -1267,7 +1321,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, src_index_arg, dst, src, len]); pos.ins()
.call_indirect(func_sig, func_addr, &[vmctx, src_index_arg, dst, src, len]);
Ok(()) Ok(())
} }
@@ -1288,7 +1343,11 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, memory_index_arg, dst, val, len]); pos.ins().call_indirect(
func_sig,
func_addr,
&[vmctx, memory_index_arg, dst, val, len],
);
Ok(()) Ok(())
} }
@@ -1323,7 +1382,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (func_sig, func_idx) = self.get_data_drop_func(&mut pos.func); let (func_sig, func_idx) = self.get_data_drop_func(&mut pos.func);
let seg_index_arg = pos.ins().iconst(I32, seg_index as i64); let seg_index_arg = pos.ins().iconst(I32, seg_index as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, seg_index_arg]); pos.ins()
.call_indirect(func_sig, func_addr, &[vmctx, seg_index_arg]);
Ok(()) Ok(())
} }
@@ -1336,7 +1396,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (func_sig, index_arg, func_idx) = self.get_table_size_func(&mut pos.func, table_index); let (func_sig, index_arg, func_idx) = self.get_table_size_func(&mut pos.func, table_index);
let table_index = pos.ins().iconst(I32, index_arg as i64); let table_index = pos.ins().iconst(I32, index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index]); let call_inst = pos
.ins()
.call_indirect(func_sig, func_addr, &[vmctx, table_index]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }
@@ -1362,7 +1424,14 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
pos.ins().call_indirect( pos.ins().call_indirect(
func_sig, func_sig,
func_addr, func_addr,
&[vmctx, dst_table_index_arg, src_table_index_arg, dst, src, len], &[
vmctx,
dst_table_index_arg,
src_table_index_arg,
dst,
src,
len,
],
); );
Ok(()) Ok(())
@@ -1402,7 +1471,8 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx); let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, elem_index_arg]); pos.ins()
.call_indirect(func_sig, func_addr, &[vmctx, elem_index_arg]);
Ok(()) Ok(())
} }
@@ -1416,7 +1486,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
_expected: ir::Value, _expected: ir::Value,
_timeout: ir::Value, _timeout: ir::Value,
) -> WasmResult<ir::Value> { ) -> WasmResult<ir::Value> {
Err(WasmError::Unsupported("wasm atomics (fn translate_atomic_wait)".to_string())) Err(WasmError::Unsupported(
"wasm atomics (fn translate_atomic_wait)".to_string(),
))
} }
fn translate_atomic_notify( fn translate_atomic_notify(
@@ -1427,7 +1499,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
_addr: ir::Value, _addr: ir::Value,
_count: ir::Value, _count: ir::Value,
) -> WasmResult<ir::Value> { ) -> WasmResult<ir::Value> {
Err(WasmError::Unsupported("wasm atomics (fn translate_atomic_notify)".to_string())) Err(WasmError::Unsupported(
"wasm atomics (fn translate_atomic_notify)".to_string(),
))
} }
fn get_global_type(&self, global_index: GlobalIndex) -> Option<WasmerType> { fn get_global_type(&self, global_index: GlobalIndex) -> Option<WasmerType> {

View File

@@ -75,9 +75,14 @@ impl<'a> binemit::RelocSink for RelocSink<'a> {
impl<'a> RelocSink<'a> { impl<'a> RelocSink<'a> {
/// Return a new `RelocSink` instance. /// Return a new `RelocSink` instance.
pub fn new(module: &'a ModuleInfo, func_index: FunctionIndex) -> Self { pub fn new(module: &'a ModuleInfo, func_index: FunctionIndex) -> Self {
let local_func_index = let local_func_index = module
module.local_func_index(func_index).expect("The provided function should be local"); .local_func_index(func_index)
Self { module, local_func_index, func_relocs: Vec::new() } .expect("The provided function should be local");
Self {
module,
local_func_index,
func_relocs: Vec::new(),
}
} }
} }

View File

@@ -32,7 +32,10 @@ pub fn make_trampoline_dynamic_function(
let signature = signature_to_cranelift_ir(func_type, frontend_config); let signature = signature_to_cranelift_ir(func_type, frontend_config);
let mut stub_sig = ir::Signature::new(frontend_config.default_call_conv); let mut stub_sig = ir::Signature::new(frontend_config.default_call_conv);
// Add the caller `vmctx` parameter. // Add the caller `vmctx` parameter.
stub_sig.params.push(ir::AbiParam::special(pointer_type, ir::ArgumentPurpose::VMContext)); stub_sig.params.push(ir::AbiParam::special(
pointer_type,
ir::ArgumentPurpose::VMContext,
));
// Add the `values_vec` parameter. // Add the `values_vec` parameter.
stub_sig.params.push(ir::AbiParam::new(pointer_type)); stub_sig.params.push(ir::AbiParam::new(pointer_type));
@@ -45,9 +48,10 @@ pub fn make_trampoline_dynamic_function(
let mut context = Context::new(); let mut context = Context::new();
context.func = Function::with_name_signature(ExternalName::user(0, 0), signature.clone()); context.func = Function::with_name_signature(ExternalName::user(0, 0), signature.clone());
let ss = context let ss = context.func.create_stack_slot(StackSlotData::new(
.func StackSlotKind::ExplicitSlot,
.create_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, values_vec_len)); values_vec_len,
));
{ {
let mut builder = FunctionBuilder::new(&mut context.func, fn_builder_ctx); let mut builder = FunctionBuilder::new(&mut context.func, fn_builder_ctx);
@@ -62,7 +66,12 @@ pub fn make_trampoline_dynamic_function(
// We only get the non-vmctx arguments // We only get the non-vmctx arguments
for i in 1..signature.params.len() { for i in 1..signature.params.len() {
let val = builder.func.dfg.block_params(block0)[i]; let val = builder.func.dfg.block_params(block0)[i];
builder.ins().store(mflags, val, values_vec_ptr_val, ((i - 1) * value_size) as i32); builder.ins().store(
mflags,
val,
values_vec_ptr_val,
((i - 1) * value_size) as i32,
);
} }
let block_params = builder.func.dfg.block_params(block0); let block_params = builder.func.dfg.block_params(block0);
@@ -79,7 +88,9 @@ pub fn make_trampoline_dynamic_function(
offsets.vmdynamicfunction_import_context_address() as i32, offsets.vmdynamicfunction_import_context_address() as i32,
); );
builder.ins().call_indirect(new_sig, callee_value, &callee_args); builder
.ins()
.call_indirect(new_sig, callee_value, &callee_args);
let mflags = MemFlags::trusted(); let mflags = MemFlags::trusted();
let mut results = Vec::new(); let mut results = Vec::new();
@@ -101,10 +112,19 @@ pub fn make_trampoline_dynamic_function(
let mut trap_sink = binemit::NullTrapSink {}; let mut trap_sink = binemit::NullTrapSink {};
let mut stackmap_sink = binemit::NullStackMapSink {}; let mut stackmap_sink = binemit::NullStackMapSink {};
context context
.compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink, &mut stackmap_sink) .compile_and_emit(
isa,
&mut code_buf,
&mut reloc_sink,
&mut trap_sink,
&mut stackmap_sink,
)
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?; .map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind(); let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
Ok(FunctionBody { body: code_buf, unwind_info }) Ok(FunctionBody {
body: code_buf,
unwind_info,
})
} }

View File

@@ -34,7 +34,10 @@ pub fn make_trampoline_function_call(
let mut wrapper_sig = ir::Signature::new(frontend_config.default_call_conv); let mut wrapper_sig = ir::Signature::new(frontend_config.default_call_conv);
// Add the callee `vmctx` parameter. // Add the callee `vmctx` parameter.
wrapper_sig.params.push(ir::AbiParam::special(pointer_type, ir::ArgumentPurpose::VMContext)); wrapper_sig.params.push(ir::AbiParam::special(
pointer_type,
ir::ArgumentPurpose::VMContext,
));
// Add the `callee_address` parameter. // Add the `callee_address` parameter.
wrapper_sig.params.push(ir::AbiParam::new(pointer_type)); wrapper_sig.params.push(ir::AbiParam::new(pointer_type));
@@ -84,14 +87,18 @@ pub fn make_trampoline_function_call(
let new_sig = builder.import_signature(signature); let new_sig = builder.import_signature(signature);
let call = builder.ins().call_indirect(new_sig, callee_value, &callee_args); let call = builder
.ins()
.call_indirect(new_sig, callee_value, &callee_args);
let results = builder.func.dfg.inst_results(call).to_vec(); let results = builder.func.dfg.inst_results(call).to_vec();
// Store the return values into `values_vec`. // Store the return values into `values_vec`.
let mflags = ir::MemFlags::trusted(); let mflags = ir::MemFlags::trusted();
for (i, r) in results.iter().enumerate() { for (i, r) in results.iter().enumerate() {
builder.ins().store(mflags, *r, values_vec_ptr_val, (i * value_size) as i32); builder
.ins()
.store(mflags, *r, values_vec_ptr_val, (i * value_size) as i32);
} }
builder.ins().return_(&[]); builder.ins().return_(&[]);
@@ -104,7 +111,13 @@ pub fn make_trampoline_function_call(
let mut stackmap_sink = binemit::NullStackMapSink {}; let mut stackmap_sink = binemit::NullStackMapSink {};
context context
.compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink, &mut stackmap_sink) .compile_and_emit(
isa,
&mut code_buf,
&mut reloc_sink,
&mut trap_sink,
&mut stackmap_sink,
)
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?; .map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind(); let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();

View File

@@ -80,7 +80,13 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let val = builder.use_var(Variable::with_u32(*local_index)); let val = builder.use_var(Variable::with_u32(*local_index));
let local_type = environ.get_local_type(*local_index).unwrap(); let local_type = environ.get_local_type(*local_index).unwrap();
let ref_counted = local_type == WasmerType::ExternRef; let ref_counted = local_type == WasmerType::ExternRef;
state.push1_extra((val, ValueExtraInfo { ref_counted, ..Default::default() })); state.push1_extra((
val,
ValueExtraInfo {
ref_counted,
..Default::default()
},
));
let label = ValueLabel::from_u32(*local_index); let label = ValueLabel::from_u32(*local_index);
builder.set_val_label(val, label); builder.set_val_label(val, label);
@@ -145,7 +151,13 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
environ.translate_externref_inc(builder.cursor(), value)?; environ.translate_externref_inc(builder.cursor(), value)?;
} }
(value, ValueExtraInfo { ref_counted, ..Default::default() }) (
value,
ValueExtraInfo {
ref_counted,
..Default::default()
},
)
} }
GlobalVariable::Custom => ( GlobalVariable::Custom => (
environ.translate_custom_global_get(builder.cursor(), global_index)?, environ.translate_custom_global_get(builder.cursor(), global_index)?,
@@ -204,7 +216,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let not_selected_ref = builder.ins().select(cond, arg2, arg1); let not_selected_ref = builder.ins().select(cond, arg2, arg1);
state.push1_extra(( state.push1_extra((
selected_ref, selected_ref,
ValueExtraInfo { ref_counted, ..Default::default() }, ValueExtraInfo {
ref_counted,
..Default::default()
},
)); ));
environ.translate_externref_dec(builder.cursor(), not_selected_ref)?; environ.translate_externref_dec(builder.cursor(), not_selected_ref)?;
} else { } else {
@@ -247,7 +262,9 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
// Pop the initial `Block` actuals and replace them with the `Block`'s // Pop the initial `Block` actuals and replace them with the `Block`'s
// params since control flow joins at the top of the loop. // params since control flow joins at the top of the loop.
state.popn(params.len()); state.popn(params.len());
state.stack.extend_from_slice(builder.block_params(loop_body)); state
.stack
.extend_from_slice(builder.block_params(loop_body));
builder.switch_to_block(loop_body); builder.switch_to_block(loop_body);
environ.translate_loop_header(builder.cursor())?; environ.translate_loop_header(builder.cursor())?;
@@ -385,7 +402,9 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
} }
frame.truncate_value_stack_to_original_size(&mut state.stack); frame.truncate_value_stack_to_original_size(&mut state.stack);
state.stack.extend_from_slice(builder.block_params(next_block)); state
.stack
.extend_from_slice(builder.block_params(next_block));
} }
/**************************** Branch instructions ********************************* /**************************** Branch instructions *********************************
* The branch instructions all have as arguments a target nesting level, which * The branch instructions all have as arguments a target nesting level, which
@@ -567,7 +586,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let mut results_metadata = Vec::with_capacity(func_type.results().len()); let mut results_metadata = Vec::with_capacity(func_type.results().len());
for result in func_type.results() { for result in func_type.results() {
results_metadata.push(if *result == WasmerType::ExternRef { results_metadata.push(if *result == WasmerType::ExternRef {
ValueExtraInfo { ref_counted: true, ..Default::default() } ValueExtraInfo {
ref_counted: true,
..Default::default()
}
} else { } else {
Default::default() Default::default()
}); });
@@ -612,7 +634,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let mut results_metadata = Vec::with_capacity(func_type.results().len()); let mut results_metadata = Vec::with_capacity(func_type.results().len());
for result in func_type.results() { for result in func_type.results() {
results_metadata.push(if *result == WasmerType::ExternRef { results_metadata.push(if *result == WasmerType::ExternRef {
ValueExtraInfo { ref_counted: true, ..Default::default() } ValueExtraInfo {
ref_counted: true,
..Default::default()
}
} else { } else {
Default::default() Default::default()
}); });
@@ -1361,7 +1386,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let (index, _) = state.pop1(); let (index, _) = state.pop1();
environ.translate_table_set(builder, table_index, table, value, index)?; environ.translate_table_set(builder, table_index, table, value, index)?;
} }
Operator::TableCopy { dst_table: dst_table_index, src_table: src_table_index } => { Operator::TableCopy {
dst_table: dst_table_index,
src_table: src_table_index,
} => {
let dst_table = state.get_or_create_table(builder.func, *dst_table_index, environ)?; let dst_table = state.get_or_create_table(builder.func, *dst_table_index, environ)?;
let src_table = state.get_or_create_table(builder.func, *src_table_index, environ)?; let src_table = state.get_or_create_table(builder.func, *src_table_index, environ)?;
let (len, _) = state.pop1(); let (len, _) = state.pop1();
@@ -1385,7 +1413,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let (dest, _) = state.pop1(); let (dest, _) = state.pop1();
environ.translate_table_fill(builder.cursor(), table_index, dest, val, len)?; environ.translate_table_fill(builder.cursor(), table_index, dest, val, len)?;
} }
Operator::TableInit { segment, table: table_index } => { Operator::TableInit {
segment,
table: table_index,
} => {
let table = state.get_or_create_table(builder.func, *table_index, environ)?; let table = state.get_or_create_table(builder.func, *table_index, environ)?;
let (len, _) = state.pop1(); let (len, _) = state.pop1();
let (src, _) = state.pop1(); let (src, _) = state.pop1();
@@ -1412,7 +1443,9 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
state.push1(value) state.push1(value)
} }
Operator::I8x16Splat | Operator::I16x8Splat => { Operator::I8x16Splat | Operator::I16x8Splat => {
let reduced = builder.ins().ireduce(type_of(op).lane_type(), state.pop1().0); let reduced = builder
.ins()
.ireduce(type_of(op).lane_type(), state.pop1().0);
let splatted = builder.ins().splat(type_of(op), reduced); let splatted = builder.ins().splat(type_of(op), reduced);
state.push1(splatted) state.push1(splatted)
} }
@@ -1653,9 +1686,12 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
Operator::I8x16LeS | Operator::I16x8LeS | Operator::I32x4LeS => { Operator::I8x16LeS | Operator::I16x8LeS | Operator::I32x4LeS => {
translate_vector_icmp(IntCC::SignedLessThanOrEqual, type_of(op), builder, state) translate_vector_icmp(IntCC::SignedLessThanOrEqual, type_of(op), builder, state)
} }
Operator::I8x16GeU | Operator::I16x8GeU | Operator::I32x4GeU => { Operator::I8x16GeU | Operator::I16x8GeU | Operator::I32x4GeU => translate_vector_icmp(
translate_vector_icmp(IntCC::UnsignedGreaterThanOrEqual, type_of(op), builder, state) IntCC::UnsignedGreaterThanOrEqual,
} type_of(op),
builder,
state,
),
Operator::I8x16LeU | Operator::I16x8LeU | Operator::I32x4LeU => { Operator::I8x16LeU | Operator::I16x8LeU | Operator::I32x4LeU => {
translate_vector_icmp(IntCC::UnsignedLessThanOrEqual, type_of(op), builder, state) translate_vector_icmp(IntCC::UnsignedLessThanOrEqual, type_of(op), builder, state)
} }
@@ -1885,7 +1921,9 @@ fn translate_unreachable_operator<FE: FuncEnvironment + ?Sized>(
// so we don't have any branches anywhere. // so we don't have any branches anywhere.
state.push_if( state.push_if(
ir::Block::reserved_value(), ir::Block::reserved_value(),
ElseData::NoElse { branch_inst: ir::Inst::reserved_value() }, ElseData::NoElse {
branch_inst: ir::Inst::reserved_value(),
},
0, 0,
0, 0,
ty, ty,
@@ -2090,8 +2128,14 @@ fn prepare_load<FE: FuncEnvironment + ?Sized>(
let (addr32, _) = state.pop1(); let (addr32, _) = state.pop1();
let heap = state.get_heap(builder.func, memarg.memory, environ)?; let heap = state.get_heap(builder.func, memarg.memory, environ)?;
let (base, offset) = let (base, offset) = get_heap_addr(
get_heap_addr(heap, addr32, memarg.offset, loaded_bytes, environ.pointer_type(), builder); heap,
addr32,
memarg.offset,
loaded_bytes,
environ.pointer_type(),
builder,
);
// Note that we don't set `is_aligned` here, even if the load instruction's // Note that we don't set `is_aligned` here, even if the load instruction's
// alignment immediate says it's aligned, because WebAssembly's immediate // alignment immediate says it's aligned, because WebAssembly's immediate
@@ -2110,8 +2154,13 @@ fn translate_load<FE: FuncEnvironment + ?Sized>(
state: &mut FuncTranslationState, state: &mut FuncTranslationState,
environ: &mut FE, environ: &mut FE,
) -> WasmResult<()> { ) -> WasmResult<()> {
let (flags, base, offset) = let (flags, base, offset) = prepare_load(
prepare_load(memarg, mem_op_size(opcode, result_ty), builder, state, environ)?; memarg,
mem_op_size(opcode, result_ty),
builder,
state,
environ,
)?;
let (load, dfg) = builder.ins().Load(opcode, result_ty, flags, offset, base); let (load, dfg) = builder.ins().Load(opcode, result_ty, flags, offset, base);
state.push1(dfg.first_result(load)); state.push1(dfg.first_result(load));
Ok(()) Ok(())
@@ -2139,7 +2188,9 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
); );
// See the comments in `prepare_load` about the flags. // See the comments in `prepare_load` about the flags.
let flags = MemFlags::new(); let flags = MemFlags::new();
builder.ins().Store(opcode, val_ty, flags, offset.into(), val, base); builder
.ins()
.Store(opcode, val_ty, flags, offset.into(), val, base);
Ok(()) Ok(())
} }
@@ -2171,13 +2222,20 @@ fn finalise_atomic_mem_addr<FE: FuncEnvironment + ?Sized>(
) -> WasmResult<Value> { ) -> WasmResult<Value> {
// Check the alignment of `linear_mem_addr`. // Check the alignment of `linear_mem_addr`.
let access_ty_bytes = access_ty.bytes(); let access_ty_bytes = access_ty.bytes();
let final_lma = builder.ins().iadd_imm(linear_mem_addr, i64::from(memarg.offset)); let final_lma = builder
.ins()
.iadd_imm(linear_mem_addr, i64::from(memarg.offset));
if access_ty_bytes != 1 { if access_ty_bytes != 1 {
assert!(access_ty_bytes == 2 || access_ty_bytes == 4 || access_ty_bytes == 8); assert!(access_ty_bytes == 2 || access_ty_bytes == 4 || access_ty_bytes == 8);
let final_lma_misalignment = let final_lma_misalignment = builder
builder.ins().band_imm(final_lma, i64::from(access_ty_bytes - 1)); .ins()
let f = builder.ins().ifcmp_imm(final_lma_misalignment, i64::from(0)); .band_imm(final_lma, i64::from(access_ty_bytes - 1));
builder.ins().trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned); let f = builder
.ins()
.ifcmp_imm(final_lma_misalignment, i64::from(0));
builder
.ins()
.trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned);
} }
// Compute the final effective address. // Compute the final effective address.
@@ -2211,7 +2269,12 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
// to type `widened_ty`. // to type `widened_ty`.
match access_ty { match access_ty {
I8 | I16 | I32 | I64 => {} I8 | I16 | I32 | I64 => {}
_ => return Err(wasm_unsupported!("atomic_rmw: unsupported access type {:?}", access_ty)), _ => {
return Err(wasm_unsupported!(
"atomic_rmw: unsupported access type {:?}",
access_ty
))
}
}; };
let w_ty_ok = match widened_ty { let w_ty_ok = match widened_ty {
I32 | I64 => true, I32 | I64 => true,
@@ -2229,7 +2292,9 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
// See the comments in `prepare_load` about the flags. // See the comments in `prepare_load` about the flags.
let flags = MemFlags::new(); let flags = MemFlags::new();
let mut res = builder.ins().atomic_rmw(access_ty, flags, op, final_effective_address, arg2); let mut res = builder
.ins()
.atomic_rmw(access_ty, flags, op, final_effective_address, arg2);
if access_ty != widened_ty { if access_ty != widened_ty {
res = builder.ins().uextend(widened_ty, res); res = builder.ins().uextend(widened_ty, res);
} }
@@ -2253,7 +2318,12 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
// to type `widened_ty`. // to type `widened_ty`.
match access_ty { match access_ty {
I8 | I16 | I32 | I64 => {} I8 | I16 | I32 | I64 => {}
_ => return Err(wasm_unsupported!("atomic_cas: unsupported access type {:?}", access_ty)), _ => {
return Err(wasm_unsupported!(
"atomic_cas: unsupported access type {:?}",
access_ty
))
}
}; };
let w_ty_ok = match widened_ty { let w_ty_ok = match widened_ty {
I32 | I64 => true, I32 | I64 => true,
@@ -2275,7 +2345,9 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
// See the comments in `prepare_load` about the flags. // See the comments in `prepare_load` about the flags.
let flags = MemFlags::new(); let flags = MemFlags::new();
let mut res = builder.ins().atomic_cas(flags, final_effective_address, expected, replacement); let mut res = builder
.ins()
.atomic_cas(flags, final_effective_address, expected, replacement);
if access_ty != widened_ty { if access_ty != widened_ty {
res = builder.ins().uextend(widened_ty, res); res = builder.ins().uextend(widened_ty, res);
} }
@@ -2297,7 +2369,12 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
// to `widened_ty`. // to `widened_ty`.
match access_ty { match access_ty {
I8 | I16 | I32 | I64 => {} I8 | I16 | I32 | I64 => {}
_ => return Err(wasm_unsupported!("atomic_load: unsupported access type {:?}", access_ty)), _ => {
return Err(wasm_unsupported!(
"atomic_load: unsupported access type {:?}",
access_ty
))
}
}; };
let w_ty_ok = match widened_ty { let w_ty_ok = match widened_ty {
I32 | I64 => true, I32 | I64 => true,
@@ -2310,7 +2387,9 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
// See the comments in `prepare_load` about the flags. // See the comments in `prepare_load` about the flags.
let flags = MemFlags::new(); let flags = MemFlags::new();
let mut res = builder.ins().atomic_load(access_ty, flags, final_effective_address); let mut res = builder
.ins()
.atomic_load(access_ty, flags, final_effective_address);
if access_ty != widened_ty { if access_ty != widened_ty {
res = builder.ins().uextend(widened_ty, res); res = builder.ins().uextend(widened_ty, res);
} }
@@ -2333,7 +2412,10 @@ fn translate_atomic_store<FE: FuncEnvironment + ?Sized>(
match access_ty { match access_ty {
I8 | I16 | I32 | I64 => {} I8 | I16 | I32 | I64 => {}
_ => { _ => {
return Err(wasm_unsupported!("atomic_store: unsupported access type {:?}", access_ty)) return Err(wasm_unsupported!(
"atomic_store: unsupported access type {:?}",
access_ty
))
} }
}; };
let d_ty_ok = match data_ty { let d_ty_ok = match data_ty {
@@ -2351,7 +2433,9 @@ fn translate_atomic_store<FE: FuncEnvironment + ?Sized>(
// See the comments in `prepare_load` about the flags. // See the comments in `prepare_load` about the flags.
let flags = MemFlags::new(); let flags = MemFlags::new();
builder.ins().atomic_store(flags, data, final_effective_address); builder
.ins()
.atomic_store(flags, data, final_effective_address);
Ok(()) Ok(())
} }
@@ -2411,8 +2495,11 @@ fn translate_br_if_args(
// The values returned by the branch are still available for the reachable // The values returned by the branch are still available for the reachable
// code that comes after it // code that comes after it
frame.set_branched_to_exit(); frame.set_branched_to_exit();
let return_count = let return_count = if frame.is_loop() {
if frame.is_loop() { frame.num_param_values() } else { frame.num_return_values() }; frame.num_param_values()
} else {
frame.num_return_values()
};
(return_count, frame.br_destination()) (return_count, frame.br_destination())
}; };
let inputs = state.peekn_mut(return_count); let inputs = state.peekn_mut(return_count);
@@ -2621,7 +2708,10 @@ fn optionally_bitcast_vector(
#[inline(always)] #[inline(always)]
fn is_non_canonical_v128(ty: ir::Type) -> bool { fn is_non_canonical_v128(ty: ir::Type) -> bool {
matches!(ty, B8X16 | B16X8 | B32X4 | B64X2 | I64X2 | I32X4 | I16X8 | F32X4 | F64X2) matches!(
ty,
B8X16 | B16X8 | B32X4 | B64X2 | I64X2 | I32X4 | I16X8 | F32X4 | F64X2
)
} }
/// Cast to I8X16, any vector values in `values` that are of "non-canonical" type (meaning, not /// Cast to I8X16, any vector values in `values` that are of "non-canonical" type (meaning, not
@@ -2635,8 +2725,9 @@ fn canonicalise_v128_values<'a>(
) -> &'a [ir::Value] { ) -> &'a [ir::Value] {
debug_assert!(tmp_canonicalised.is_empty()); debug_assert!(tmp_canonicalised.is_empty());
// First figure out if any of the parameters need to be cast. Mostly they don't need to be. // First figure out if any of the parameters need to be cast. Mostly they don't need to be.
let any_non_canonical = let any_non_canonical = values
values.iter().any(|v| is_non_canonical_v128(builder.func.dfg.value_type(*v))); .iter()
.any(|v| is_non_canonical_v128(builder.func.dfg.value_type(*v)));
// Hopefully we take this exit most of the time, hence doing no heap allocation. // Hopefully we take this exit most of the time, hence doing no heap allocation.
if !any_non_canonical { if !any_non_canonical {
return values; return values;

View File

@@ -95,16 +95,28 @@ pub enum ControlStackFrame {
impl ControlStackFrame { impl ControlStackFrame {
pub fn num_return_values(&self) -> usize { pub fn num_return_values(&self) -> usize {
match *self { match *self {
Self::If { num_return_values, .. } Self::If {
| Self::Block { num_return_values, .. } num_return_values, ..
| Self::Loop { num_return_values, .. } => num_return_values, }
| Self::Block {
num_return_values, ..
}
| Self::Loop {
num_return_values, ..
} => num_return_values,
} }
} }
pub fn num_param_values(&self) -> usize { pub fn num_param_values(&self) -> usize {
match *self { match *self {
Self::If { num_param_values, .. } Self::If {
| Self::Block { num_param_values, .. } num_param_values, ..
| Self::Loop { num_param_values, .. } => num_param_values, }
| Self::Block {
num_param_values, ..
}
| Self::Loop {
num_param_values, ..
} => num_param_values,
} }
} }
pub fn following_code(&self) -> Block { pub fn following_code(&self) -> Block {
@@ -124,9 +136,18 @@ impl ControlStackFrame {
/// `truncate_value_stack_to_original_size()` to restore value-stack state. /// `truncate_value_stack_to_original_size()` to restore value-stack state.
fn original_stack_size(&self) -> usize { fn original_stack_size(&self) -> usize {
match *self { match *self {
Self::If { original_stack_size, .. } Self::If {
| Self::Block { original_stack_size, .. } original_stack_size,
| Self::Loop { original_stack_size, .. } => original_stack_size, ..
}
| Self::Block {
original_stack_size,
..
}
| Self::Loop {
original_stack_size,
..
} => original_stack_size,
} }
} }
pub fn is_loop(&self) -> bool { pub fn is_loop(&self) -> bool {
@@ -138,17 +159,28 @@ impl ControlStackFrame {
pub fn exit_is_branched_to(&self) -> bool { pub fn exit_is_branched_to(&self) -> bool {
match *self { match *self {
Self::If { exit_is_branched_to, .. } | Self::Block { exit_is_branched_to, .. } => { Self::If {
exit_is_branched_to exit_is_branched_to,
..
} }
| Self::Block {
exit_is_branched_to,
..
} => exit_is_branched_to,
Self::Loop { .. } => false, Self::Loop { .. } => false,
} }
} }
pub fn set_branched_to_exit(&mut self) { pub fn set_branched_to_exit(&mut self) {
match *self { match *self {
Self::If { ref mut exit_is_branched_to, .. } Self::If {
| Self::Block { ref mut exit_is_branched_to, .. } => *exit_is_branched_to = true, ref mut exit_is_branched_to,
..
}
| Self::Block {
ref mut exit_is_branched_to,
..
} => *exit_is_branched_to = true,
Self::Loop { .. } => {} Self::Loop { .. } => {}
} }
} }
@@ -169,7 +201,9 @@ impl ControlStackFrame {
// block can see the same number of parameters as the consequent block. As a matter of // block can see the same number of parameters as the consequent block. As a matter of
// fact, we need to substract an extra number of parameter values for if blocks. // fact, we need to substract an extra number of parameter values for if blocks.
let num_duplicated_params = match self { let num_duplicated_params = match self {
&ControlStackFrame::If { num_param_values, .. } => { &ControlStackFrame::If {
num_param_values, ..
} => {
debug_assert!(num_param_values <= self.original_stack_size()); debug_assert!(num_param_values <= self.original_stack_size());
num_param_values num_param_values
} }
@@ -268,7 +302,10 @@ impl FuncTranslationState {
self.push_block( self.push_block(
exit_block, exit_block,
0, 0,
sig.returns.iter().filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal).count(), sig.returns
.iter()
.filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
.count(),
); );
} }
@@ -296,14 +333,20 @@ impl FuncTranslationState {
/// Pop one value. /// Pop one value.
pub(crate) fn pop1(&mut self) -> (Value, ValueExtraInfo) { pub(crate) fn pop1(&mut self) -> (Value, ValueExtraInfo) {
let val = self.stack.pop().expect("attempted to pop a value from an empty stack"); let val = self
.stack
.pop()
.expect("attempted to pop a value from an empty stack");
let val_metadata = Default::default(); let val_metadata = Default::default();
(val, val_metadata) (val, val_metadata)
} }
/// Peek at the top of the stack without popping it. /// Peek at the top of the stack without popping it.
pub(crate) fn peek1(&self) -> (Value, ValueExtraInfo) { pub(crate) fn peek1(&self) -> (Value, ValueExtraInfo) {
let val = *self.stack.last().expect("attempted to peek at a value on an empty stack"); let val = *self
.stack
.last()
.expect("attempted to peek at a value on an empty stack");
let val_metadata = Default::default(); let val_metadata = Default::default();
(val, val_metadata) (val, val_metadata)
} }
@@ -318,7 +361,11 @@ impl FuncTranslationState {
/// Pop three values. Return them in the order they were pushed. /// Pop three values. Return them in the order they were pushed.
pub(crate) fn pop3( pub(crate) fn pop3(
&mut self, &mut self,
) -> ((Value, ValueExtraInfo), (Value, ValueExtraInfo), (Value, ValueExtraInfo)) { ) -> (
(Value, ValueExtraInfo),
(Value, ValueExtraInfo),
(Value, ValueExtraInfo),
) {
let v3 = self.pop1(); let v3 = self.pop1();
let v2 = self.pop1(); let v2 = self.pop1();
let v1 = self.pop1(); let v1 = self.pop1();
@@ -530,7 +577,10 @@ impl FuncTranslationState {
Vacant(entry) => { Vacant(entry) => {
let fref = environ.make_direct_func(func, index)?; let fref = environ.make_direct_func(func, index)?;
let sig = func.dfg.ext_funcs[fref].signature; let sig = func.dfg.ext_funcs[fref].signature;
Ok(*entry.insert((fref, num_wasm_parameters(environ, &func.dfg.signatures[sig])))) Ok(*entry.insert((
fref,
num_wasm_parameters(environ, &func.dfg.signatures[sig]),
)))
} }
} }
} }
@@ -540,5 +590,7 @@ fn num_wasm_parameters<FE: FuncEnvironment + ?Sized>(
environ: &FE, environ: &FE,
signature: &ir::Signature, signature: &ir::Signature,
) -> usize { ) -> usize {
(0..signature.params.len()).filter(|index| environ.is_wasm_parameter(signature, *index)).count() (0..signature.params.len())
.filter(|index| environ.is_wasm_parameter(signature, *index))
.count()
} }

View File

@@ -37,7 +37,10 @@ pub struct FuncTranslator {
impl FuncTranslator { impl FuncTranslator {
/// Create a new translator. /// Create a new translator.
pub fn new() -> Self { pub fn new() -> Self {
Self { func_ctx: FunctionBuilderContext::new(), state: FuncTranslationState::new() } Self {
func_ctx: FunctionBuilderContext::new(),
state: FuncTranslationState::new(),
}
} }
/// Translate a binary WebAssembly function. /// Translate a binary WebAssembly function.
@@ -70,7 +73,9 @@ impl FuncTranslator {
) -> WasmResult<()> { ) -> WasmResult<()> {
let mut reader = MiddlewareBinaryReader::new_with_offset(code, code_offset); let mut reader = MiddlewareBinaryReader::new_with_offset(code, code_offset);
reader.set_middleware_chain( reader.set_middleware_chain(
config.middlewares.generate_function_middleware_chain(local_function_index), config
.middlewares
.generate_function_middleware_chain(local_function_index),
); );
environ.push_params_on_stack(local_function_index); environ.push_params_on_stack(local_function_index);
self.translate_from_reader(module_translation_state, reader, func, environ) self.translate_from_reader(module_translation_state, reader, func, environ)
@@ -85,7 +90,12 @@ impl FuncTranslator {
environ: &mut FE, environ: &mut FE,
) -> WasmResult<()> { ) -> WasmResult<()> {
let _tt = timing::wasm_translate_function(); let _tt = timing::wasm_translate_function();
info!("translate({} bytes, {}{})", reader.bytes_remaining(), func.name, func.signature); info!(
"translate({} bytes, {}{})",
reader.bytes_remaining(),
func.name,
func.signature
);
debug_assert_eq!(func.dfg.num_blocks(), 0, "Function must be empty"); debug_assert_eq!(func.dfg.num_blocks(), 0, "Function must be empty");
debug_assert_eq!(func.dfg.num_insts(), 0, "Function must be empty"); debug_assert_eq!(func.dfg.num_insts(), 0, "Function must be empty");

View File

@@ -33,8 +33,10 @@ pub fn signature_to_cranelift_ir(
AbiParam::new(cret_arg) AbiParam::new(cret_arg)
})); }));
// The Vmctx signature // The Vmctx signature
sig.params sig.params.insert(
.insert(0, AbiParam::special(target_config.pointer_type(), ir::ArgumentPurpose::VMContext)); 0,
AbiParam::special(target_config.pointer_type(), ir::ArgumentPurpose::VMContext),
);
sig sig
} }
@@ -43,7 +45,9 @@ pub fn reference_type(target_config: TargetFrontendConfig) -> WasmResult<ir::Typ
match target_config.pointer_type() { match target_config.pointer_type() {
ir::types::I32 => Ok(ir::types::R32), ir::types::I32 => Ok(ir::types::R32),
ir::types::I64 => Ok(ir::types::R64), ir::types::I64 => Ok(ir::types::R64),
_ => Err(WasmError::Unsupported("unsupported pointer type".to_string())), _ => Err(WasmError::Unsupported(
"unsupported pointer type".to_string(),
)),
} }
} }

View File

@@ -72,7 +72,9 @@ impl Abi for Aarch64SystemV {
( (
context.create_enum_attribute( context.create_enum_attribute(
Attribute::get_named_enum_kind_id("align"), Attribute::get_named_enum_kind_id("align"),
std::mem::align_of::<wasmer_vm::VMContext>().try_into().unwrap(), std::mem::align_of::<wasmer_vm::VMContext>()
.try_into()
.unwrap(),
), ),
AttributeLoc::Param(i), AttributeLoc::Param(i),
), ),
@@ -81,7 +83,9 @@ impl Abi for Aarch64SystemV {
Ok(match sig.results() { Ok(match sig.results() {
[] => ( [] => (
intrinsics.void_ty.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false), intrinsics
.void_ty
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
vmctx_attributes(0), vmctx_attributes(0),
), ),
[_] => { [_] => {
@@ -221,7 +225,9 @@ impl Abi for Aarch64SystemV {
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied()); let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
if let Some(sret) = sret { if let Some(sret) = sret {
std::iter::once(sret.as_basic_value_enum()).chain(values).collect() std::iter::once(sret.as_basic_value_enum())
.chain(values)
.collect()
} else { } else {
values.collect() values.collect()
} }
@@ -302,9 +308,14 @@ impl Abi for Aarch64SystemV {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
} }
let array_value = basic_value.into_array_value(); let array_value = basic_value.into_array_value();
let low = builder.build_extract_value(array_value, 0, "").unwrap().into_int_value(); let low = builder
let high = .build_extract_value(array_value, 0, "")
builder.build_extract_value(array_value, 1, "").unwrap().into_int_value(); .unwrap()
.into_int_value();
let high = builder
.build_extract_value(array_value, 1, "")
.unwrap()
.into_int_value();
let func_sig_returns_bitwidths = func_sig let func_sig_returns_bitwidths = func_sig
.results() .results()
.iter() .iter()
@@ -462,7 +473,9 @@ impl Abi for Aarch64SystemV {
if v.is_float_value() { if v.is_float_value() {
let v = v.into_float_value(); let v = v.into_float_value();
if v.get_type() == intrinsics.f32_ty { if v.get_type() == intrinsics.f32_ty {
let v = builder.build_bitcast(v, intrinsics.i32_ty, "").into_int_value(); let v = builder
.build_bitcast(v, intrinsics.i32_ty, "")
.into_int_value();
let v = builder.build_int_z_extend(v, intrinsics.i64_ty, ""); let v = builder.build_int_z_extend(v, intrinsics.i64_ty, "");
v.as_basic_value_enum() v.as_basic_value_enum()
} else { } else {
@@ -509,7 +522,10 @@ impl Abi for Aarch64SystemV {
&& v2.is_float_value() && v2.is_float_value()
&& v1.into_float_value().get_type() == v2.into_float_value().get_type() => && v1.into_float_value().get_type() == v2.into_float_value().get_type() =>
{ {
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2]) build_struct(
func_type.get_return_type().unwrap().into_struct_type(),
&[v1, v2],
)
} }
[v1, v2] if is_32(v1) && is_32(v2) => { [v1, v2] if is_32(v1) && is_32(v2) => {
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, ""); let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
@@ -525,7 +541,10 @@ impl Abi for Aarch64SystemV {
&& v2.is_float_value() && v2.is_float_value()
&& v3.is_float_value() => && v3.is_float_value() =>
{ {
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2, v3]) build_struct(
func_type.get_return_type().unwrap().into_struct_type(),
&[v1, v2, v3],
)
} }
[v1, v2, v3] if is_32(v1) && is_32(v2) => { [v1, v2, v3] if is_32(v1) && is_32(v2) => {
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, ""); let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");

View File

@@ -25,7 +25,12 @@ use aarch64_systemv::Aarch64SystemV;
use x86_64_systemv::X86_64SystemV; use x86_64_systemv::X86_64SystemV;
pub fn get_abi(target_machine: &TargetMachine) -> Box<dyn Abi> { pub fn get_abi(target_machine: &TargetMachine) -> Box<dyn Abi> {
if target_machine.get_triple().as_str().to_string_lossy().starts_with("aarch64") { if target_machine
.get_triple()
.as_str()
.to_string_lossy()
.starts_with("aarch64")
{
Box::new(Aarch64SystemV {}) Box::new(Aarch64SystemV {})
} else { } else {
Box::new(X86_64SystemV {}) Box::new(X86_64SystemV {})

View File

@@ -76,7 +76,9 @@ impl Abi for X86_64SystemV {
( (
context.create_enum_attribute( context.create_enum_attribute(
Attribute::get_named_enum_kind_id("align"), Attribute::get_named_enum_kind_id("align"),
std::mem::align_of::<wasmer_vm::VMContext>().try_into().unwrap(), std::mem::align_of::<wasmer_vm::VMContext>()
.try_into()
.unwrap(),
), ),
AttributeLoc::Param(i), AttributeLoc::Param(i),
), ),
@@ -96,7 +98,9 @@ impl Abi for X86_64SystemV {
Ok(match sig_returns_bitwidths.as_slice() { Ok(match sig_returns_bitwidths.as_slice() {
[] => ( [] => (
intrinsics.void_ty.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false), intrinsics
.void_ty
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
vmctx_attributes(0), vmctx_attributes(0),
), ),
[_] => { [_] => {
@@ -129,7 +133,9 @@ impl Abi for X86_64SystemV {
vmctx_attributes(0), vmctx_attributes(0),
), ),
[32, 32] => ( [32, 32] => (
intrinsics.i64_ty.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false), intrinsics
.i64_ty
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
vmctx_attributes(0), vmctx_attributes(0),
), ),
[32, 32, _] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => ( [32, 32, _] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => (
@@ -207,7 +213,9 @@ impl Abi for X86_64SystemV {
.map(|&ty| type_to_llvm(intrinsics, ty)) .map(|&ty| type_to_llvm(intrinsics, ty))
.collect::<Result<_, _>>()?; .collect::<Result<_, _>>()?;
let sret = context.struct_type(&basic_types, false).ptr_type(AddressSpace::Generic); let sret = context
.struct_type(&basic_types, false)
.ptr_type(AddressSpace::Generic);
let param_types = std::iter::once(Ok(sret.as_basic_type_enum())).chain(param_types); let param_types = std::iter::once(Ok(sret.as_basic_type_enum())).chain(param_types);
@@ -218,7 +226,9 @@ impl Abi for X86_64SystemV {
attributes.append(&mut vmctx_attributes(1)); attributes.append(&mut vmctx_attributes(1));
( (
intrinsics.void_ty.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false), intrinsics
.void_ty
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
attributes, attributes,
) )
} }
@@ -252,7 +262,9 @@ impl Abi for X86_64SystemV {
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied()); let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
if let Some(sret) = sret { if let Some(sret) = sret {
std::iter::once(sret.as_basic_value_enum()).chain(values).collect() std::iter::once(sret.as_basic_value_enum())
.chain(values)
.collect()
} else { } else {
values.collect() values.collect()
} }
@@ -529,7 +541,10 @@ impl Abi for X86_64SystemV {
} }
[v1, v2] => { [v1, v2] => {
assert!(!(is_32(v1) && is_32(v2))); assert!(!(is_32(v1) && is_32(v2)));
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2]) build_struct(
func_type.get_return_type().unwrap().into_struct_type(),
&[v1, v2],
)
} }
[v1, v2, v3] if is_f32(v1) && is_f32(v2) => build_struct( [v1, v2, v3] if is_f32(v1) && is_f32(v2) => build_struct(
func_type.get_return_type().unwrap().into_struct_type(), func_type.get_return_type().unwrap().into_struct_type(),

Some files were not shown because too many files have changed in this diff Show More