mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 12:48:20 +00:00
cargo fmt
This commit is contained in:
@@ -75,21 +75,16 @@ pub fn run_basic_static_function(store: &Store, compiler_name: &str, c: &mut Cri
|
||||
),
|
||||
i32,
|
||||
> = dyn_f_many.native().unwrap();
|
||||
c.bench_function(
|
||||
&format!("basic static func with many args {}", compiler_name),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
let result = black_box(
|
||||
f_many
|
||||
.call(
|
||||
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);
|
||||
})
|
||||
},
|
||||
);
|
||||
c.bench_function(&format!("basic static func with many args {}", compiler_name), |b| {
|
||||
b.iter(|| {
|
||||
let result = black_box(
|
||||
f_many
|
||||
.call(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) {
|
||||
@@ -110,40 +105,37 @@ pub fn run_basic_dynamic_function(store: &Store, compiler_name: &str, c: &mut Cr
|
||||
});
|
||||
|
||||
let dyn_f_many: &Function = instance.exports.get("add20").unwrap();
|
||||
c.bench_function(
|
||||
&format!("basic dynfunc with many args {}", compiler_name),
|
||||
|b| {
|
||||
b.iter(|| {
|
||||
let dyn_result = black_box(
|
||||
dyn_f_many
|
||||
.call(&[
|
||||
Val::I32(1),
|
||||
Val::I32(2),
|
||||
Val::I32(3),
|
||||
Val::I32(4),
|
||||
Val::I32(5),
|
||||
Val::I32(6),
|
||||
Val::I32(7),
|
||||
Val::I32(8),
|
||||
Val::I32(9),
|
||||
Val::I32(10),
|
||||
Val::I32(11),
|
||||
Val::I32(12),
|
||||
Val::I32(13),
|
||||
Val::I32(14),
|
||||
Val::I32(15),
|
||||
Val::I32(16),
|
||||
Val::I32(17),
|
||||
Val::I32(18),
|
||||
Val::I32(19),
|
||||
Val::I32(20),
|
||||
])
|
||||
.unwrap(),
|
||||
);
|
||||
assert_eq!(dyn_result[0], Val::I32(210));
|
||||
})
|
||||
},
|
||||
);
|
||||
c.bench_function(&format!("basic dynfunc with many args {}", compiler_name), |b| {
|
||||
b.iter(|| {
|
||||
let dyn_result = black_box(
|
||||
dyn_f_many
|
||||
.call(&[
|
||||
Val::I32(1),
|
||||
Val::I32(2),
|
||||
Val::I32(3),
|
||||
Val::I32(4),
|
||||
Val::I32(5),
|
||||
Val::I32(6),
|
||||
Val::I32(7),
|
||||
Val::I32(8),
|
||||
Val::I32(9),
|
||||
Val::I32(10),
|
||||
Val::I32(11),
|
||||
Val::I32(12),
|
||||
Val::I32(13),
|
||||
Val::I32(14),
|
||||
Val::I32(15),
|
||||
Val::I32(16),
|
||||
Val::I32(17),
|
||||
Val::I32(18),
|
||||
Val::I32(19),
|
||||
Val::I32(20),
|
||||
])
|
||||
.unwrap(),
|
||||
);
|
||||
assert_eq!(dyn_result[0], Val::I32(210));
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn run_static_benchmarks(_c: &mut Criterion) {
|
||||
|
||||
13
build.rs
13
build.rs
@@ -30,11 +30,8 @@ fn main() -> anyhow::Result<()> {
|
||||
|
||||
// Spectests test generation
|
||||
{
|
||||
let mut spectests = Testsuite {
|
||||
buffer: String::new(),
|
||||
path: vec![],
|
||||
ignores: ignores.clone(),
|
||||
};
|
||||
let mut spectests =
|
||||
Testsuite { buffer: String::new(), path: vec![], ignores: ignores.clone() };
|
||||
|
||||
with_features(&mut spectests, &compilers, |mut spectests| {
|
||||
with_test_module(&mut spectests, "spec", |spectests| {
|
||||
@@ -67,11 +64,7 @@ fn main() -> anyhow::Result<()> {
|
||||
|
||||
// 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"];
|
||||
with_features(&mut wasitests, &compilers, |mut wasitests| {
|
||||
with_test_module(&mut wasitests, "wasitests", |wasitests| {
|
||||
|
||||
@@ -87,10 +87,7 @@ fn main() -> anyhow::Result<()> {
|
||||
// When we call a function it can either succeed or fail. We expect it to fail.
|
||||
match run_func.call(1, 7) {
|
||||
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
|
||||
// type that we were expecting.
|
||||
|
||||
@@ -59,10 +59,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// produce an error.
|
||||
//
|
||||
// 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...");
|
||||
// Let's call the `div_by_zero` exported function.
|
||||
|
||||
@@ -88,10 +88,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//
|
||||
// We will use an exported function for the `one` global
|
||||
// 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 some_value = some.get();
|
||||
@@ -120,10 +117,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// 2. Using the Global API directly.
|
||||
//
|
||||
// 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)?;
|
||||
let some_result = some.get();
|
||||
println!("`some` value after `set_some`: {:?}", some_result);
|
||||
|
||||
@@ -50,9 +50,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Let's instantiate the Wasm module.
|
||||
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.
|
||||
//
|
||||
|
||||
@@ -59,9 +59,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// covered in more detail in other examples.
|
||||
println!("Creating the imported function...");
|
||||
let host_function_signature = FunctionType::new(vec![], vec![Type::I32]);
|
||||
let host_function = Function::new(&store, &host_function_signature, |_args| {
|
||||
Ok(vec![Value::I32(42)])
|
||||
});
|
||||
let host_function =
|
||||
Function::new(&store, &host_function_signature, |_args| Ok(vec![Value::I32(42)]));
|
||||
|
||||
println!("Creating the imported global...");
|
||||
let host_global = Global::new(&store, Value::I32(42));
|
||||
|
||||
@@ -85,10 +85,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Here we go.
|
||||
//
|
||||
// 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...");
|
||||
// Let's call the `sum` exported function. It will call each
|
||||
|
||||
@@ -100,10 +100,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Here we go.
|
||||
//
|
||||
// The Wasm module exports a function called `increment_counter_loop`. Let's get it.
|
||||
let increment_counter_loop = instance
|
||||
.exports
|
||||
.get_function("increment_counter_loop")?
|
||||
.native::<i32, i32>()?;
|
||||
let increment_counter_loop =
|
||||
instance.exports.get_function("increment_counter_loop")?.native::<i32, i32>()?;
|
||||
|
||||
let counter_value: i32 = *shared_counter.lock().unwrap();
|
||||
println!("Initial ounter value: {:?}", counter_value);
|
||||
|
||||
@@ -65,14 +65,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//
|
||||
// The Wasm module only imports some globals. We'll have to interact
|
||||
// with them either using the Global API or exported functions.
|
||||
let get_some = instance
|
||||
.exports
|
||||
.get_function("get_some")?
|
||||
.native::<(), f32>()?;
|
||||
let get_other = instance
|
||||
.exports
|
||||
.get_function("get_other")?
|
||||
.native::<(), f32>()?;
|
||||
let get_some = instance.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 other_result = get_other.call()?;
|
||||
@@ -102,10 +96,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Altering global values through exported functions...");
|
||||
// Changes made to global through exported functions will
|
||||
// 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)?;
|
||||
|
||||
println!("other value (via Global API): {:?}", other.get());
|
||||
|
||||
@@ -60,10 +60,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// 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
|
||||
// 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...");
|
||||
let result = add_one.call(1)?;
|
||||
|
||||
@@ -87,10 +87,7 @@ fn main() -> anyhow::Result<()> {
|
||||
//
|
||||
// Our module exports a single `add_one` function. We want to
|
||||
// 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...");
|
||||
add_one.call(1)?;
|
||||
@@ -102,15 +99,9 @@ fn main() -> anyhow::Result<()> {
|
||||
// * `i32.const` is a `Operator::I32Const` which costs 1 point;
|
||||
// * `i32.add` is a `Operator::I32Add` which costs 2 points.
|
||||
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...");
|
||||
add_one.call(1)?;
|
||||
@@ -118,15 +109,9 @@ fn main() -> anyhow::Result<()> {
|
||||
// We spent 4 more points with the second call.
|
||||
// We have 2 remaining points.
|
||||
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,
|
||||
// calling it a third time will fail: we already consume 8
|
||||
@@ -134,10 +119,7 @@ fn main() -> anyhow::Result<()> {
|
||||
println!("Calling `add_one` function a third time...");
|
||||
match add_one.call(1) {
|
||||
Ok(result) => {
|
||||
bail!(
|
||||
"Expected failure while calling `add_one`, found: {}",
|
||||
result
|
||||
);
|
||||
bail!("Expected failure while calling `add_one`, found: {}", result);
|
||||
}
|
||||
Err(_) => {
|
||||
println!("Calling `add_one` failed.");
|
||||
|
||||
@@ -74,14 +74,7 @@ fn main() -> anyhow::Result<()> {
|
||||
let guest_table = instance.exports.get_table("__indirect_function_table")?;
|
||||
// And demonstrate that it has the properties that we set in the Wasm.
|
||||
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 ==
|
||||
|
||||
@@ -108,14 +101,7 @@ fn main() -> anyhow::Result<()> {
|
||||
assert_eq!(previous_size, 3);
|
||||
|
||||
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.
|
||||
for table_index in 3..6 {
|
||||
if let Value::FuncRef(Some(f)) = guest_table.get(table_index as _).unwrap() {
|
||||
|
||||
@@ -105,8 +105,7 @@ impl<T: Tunables> Tunables for LimitingTunables<T> {
|
||||
) -> Result<Arc<dyn vm::Memory>, MemoryError> {
|
||||
let adjusted = self.adjust_memory(ty);
|
||||
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`].
|
||||
@@ -164,12 +163,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let instance = Instance::new(&module, &import_object)?;
|
||||
|
||||
// Check what happened
|
||||
let mut memories: Vec<Memory> = instance
|
||||
.exports
|
||||
.iter()
|
||||
.memories()
|
||||
.map(|pair| pair.1.clone())
|
||||
.collect();
|
||||
let mut memories: Vec<Memory> =
|
||||
instance.exports.iter().memories().map(|pair| pair.1.clone()).collect();
|
||||
assert_eq!(memories.len(), 1);
|
||||
|
||||
let first_memory = memories.pop().unwrap();
|
||||
|
||||
@@ -21,10 +21,8 @@ use wasmer_engine_jit::JIT;
|
||||
use wasmer_wasi::WasiState;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let wasm_path = concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/tests/wasi-wast/wasi/unstable/hello.wasm"
|
||||
);
|
||||
let wasm_path =
|
||||
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/wasi-wast/wasi/unstable/hello.wasm");
|
||||
// Let's declare the Wasm module with the text representation.
|
||||
let wasm_bytes = std::fs::read(wasm_path)?;
|
||||
|
||||
|
||||
@@ -17,10 +17,8 @@ use wasmer_engine_jit::JIT;
|
||||
use wasmer_wasi::{Pipe, WasiState};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let wasm_path = concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/tests/wasi-wast/wasi/unstable/pipe_reverse.wasm"
|
||||
);
|
||||
let wasm_path =
|
||||
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/wasi-wast/wasi/unstable/pipe_reverse.wasm");
|
||||
// Let's declare the Wasm module with the text representation.
|
||||
let wasm_bytes = std::fs::read(wasm_path)?;
|
||||
|
||||
@@ -38,10 +36,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// First, we create the `WasiEnv` with the stdio pipes
|
||||
let input = Pipe::new();
|
||||
let output = Pipe::new();
|
||||
let mut wasi_env = WasiState::new("hello")
|
||||
.stdin(Box::new(input))
|
||||
.stdout(Box::new(output))
|
||||
.finalize()?;
|
||||
let mut wasi_env =
|
||||
WasiState::new("hello").stdin(Box::new(input)).stdout(Box::new(output)).finalize()?;
|
||||
|
||||
println!("Instantiating module with WASI imports...");
|
||||
// Then, we get the import object related to our WASI
|
||||
|
||||
@@ -140,10 +140,7 @@ pub struct LazyInit<T: Sized> {
|
||||
impl<T> LazyInit<T> {
|
||||
/// Creates an unitialized value.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
data: std::mem::MaybeUninit::uninit(),
|
||||
initialized: false,
|
||||
}
|
||||
Self { data: std::mem::MaybeUninit::uninit(), initialized: false }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
@@ -176,24 +173,16 @@ impl<T> LazyInit<T> {
|
||||
|
||||
impl<T: std::fmt::Debug> std::fmt::Debug for LazyInit<T> {
|
||||
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> {
|
||||
fn clone(&self) -> Self {
|
||||
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 {
|
||||
Self {
|
||||
data: std::mem::MaybeUninit::uninit(),
|
||||
initialized: false,
|
||||
}
|
||||
Self { data: std::mem::MaybeUninit::uninit(), initialized: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,9 +75,7 @@ impl Exports {
|
||||
|
||||
/// Creates a new `Exports` with capacity `n`.
|
||||
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.
|
||||
@@ -96,9 +94,7 @@ impl Exports {
|
||||
S: Into<String>,
|
||||
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`.
|
||||
@@ -148,9 +144,7 @@ impl Exports {
|
||||
Args: 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
|
||||
@@ -181,9 +175,7 @@ impl Exports {
|
||||
|
||||
/// Get an iterator over the exports.
|
||||
pub fn iter(&self) -> ExportsIterator<impl Iterator<Item = (&String, &Extern)>> {
|
||||
ExportsIterator {
|
||||
iter: self.map.iter(),
|
||||
}
|
||||
ExportsIterator { iter: self.map.iter() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,9 +252,7 @@ where
|
||||
|
||||
impl FromIterator<(String, Extern)> for Exports {
|
||||
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)) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,10 +262,7 @@ impl LikeNamespace for Exports {
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
lib/api/src/externals/function.rs
vendored
45
lib/api/src/externals/function.rs
vendored
@@ -109,9 +109,7 @@ where
|
||||
});
|
||||
let host_env_clone_fn = |ptr: *mut c_void| -> *mut c_void {
|
||||
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 _
|
||||
};
|
||||
@@ -352,9 +350,7 @@ impl Function {
|
||||
}
|
||||
let function = inner::Function::<Args, Rets>::new(func);
|
||||
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();
|
||||
|
||||
Self {
|
||||
@@ -517,11 +513,7 @@ impl Function {
|
||||
results: &mut [Val],
|
||||
) -> Result<(), RuntimeError> {
|
||||
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();
|
||||
if signature.params().len() != params.len() {
|
||||
@@ -798,11 +790,7 @@ 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]
|
||||
@@ -826,10 +814,7 @@ impl<'a> Exportable<'a> for Function {
|
||||
|
||||
impl fmt::Debug for Function {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -905,10 +890,7 @@ trait VMDynamicFunctionCall<T: VMDynamicFunction> {
|
||||
|
||||
impl<T: VMDynamicFunction> VMDynamicFunctionCall<T> for VMDynamicFunctionContext<T> {
|
||||
fn from_context(ctx: T) -> Self {
|
||||
Self {
|
||||
address: Self::address_ptr(),
|
||||
ctx,
|
||||
}
|
||||
Self { address: Self::address_ptr(), ctx }
|
||||
}
|
||||
|
||||
fn address_ptr() -> *const VMFunctionBody {
|
||||
@@ -1312,10 +1294,7 @@ mod inner {
|
||||
T: HostFunctionKind,
|
||||
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`.
|
||||
@@ -1734,14 +1713,8 @@ mod inner {
|
||||
#[test]
|
||||
fn test_function_types() {
|
||||
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!(
|
||||
Function::new(func_i32).ty(),
|
||||
FunctionType::new(vec![Type::I32], vec![])
|
||||
);
|
||||
assert_eq!(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!(
|
||||
Function::new(func_i32__i32).ty(),
|
||||
FunctionType::new(vec![Type::I32], vec![Type::I32])
|
||||
|
||||
28
lib/api/src/externals/global.rs
vendored
28
lib/api/src/externals/global.rs
vendored
@@ -63,20 +63,14 @@ impl Global {
|
||||
if !val.comes_from_same_store(store) {
|
||||
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 {
|
||||
global
|
||||
.set_unchecked(val.clone())
|
||||
.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`.
|
||||
@@ -175,18 +169,13 @@ impl Global {
|
||||
return Err(RuntimeError::new("cross-`Store` values are not supported"));
|
||||
}
|
||||
unsafe {
|
||||
self.global
|
||||
.set(val)
|
||||
.map_err(|e| RuntimeError::new(format!("{}", e)))?;
|
||||
self.global.set(val).map_err(|e| RuntimeError::new(format!("{}", e)))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -218,13 +207,8 @@ impl fmt::Debug for Global {
|
||||
|
||||
impl<'a> Exportable<'a> for Global {
|
||||
fn to_export(&self) -> Export {
|
||||
ExportGlobal {
|
||||
vm_global: VMExportGlobal {
|
||||
from: self.global.clone(),
|
||||
instance_ref: None,
|
||||
},
|
||||
}
|
||||
.into()
|
||||
ExportGlobal { vm_global: VMExportGlobal { from: self.global.clone(), instance_ref: None } }
|
||||
.into()
|
||||
}
|
||||
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
|
||||
19
lib/api/src/externals/memory.rs
vendored
19
lib/api/src/externals/memory.rs
vendored
@@ -49,10 +49,7 @@ impl Memory {
|
||||
let style = tunables.memory_style(&ty);
|
||||
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`.
|
||||
@@ -222,10 +219,7 @@ impl Memory {
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -247,13 +241,8 @@ impl Memory {
|
||||
|
||||
impl<'a> Exportable<'a> for Memory {
|
||||
fn to_export(&self) -> Export {
|
||||
ExportMemory {
|
||||
vm_memory: VMExportMemory {
|
||||
from: self.memory.clone(),
|
||||
instance_ref: None,
|
||||
},
|
||||
}
|
||||
.into()
|
||||
ExportMemory { vm_memory: VMExportMemory { from: self.memory.clone(), instance_ref: None } }
|
||||
.into()
|
||||
}
|
||||
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
|
||||
27
lib/api/src/externals/table.rs
vendored
27
lib/api/src/externals/table.rs
vendored
@@ -43,19 +43,14 @@ impl Table {
|
||||
let item = init.into_table_reference(store)?;
|
||||
let tunables = store.tunables();
|
||||
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();
|
||||
for i in 0..num_elements {
|
||||
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`.
|
||||
@@ -116,9 +111,7 @@ impl Table {
|
||||
len: u32,
|
||||
) -> Result<(), RuntimeError> {
|
||||
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(
|
||||
dst_table.table.as_ref(),
|
||||
@@ -132,10 +125,7 @@ impl Table {
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -146,13 +136,8 @@ impl Table {
|
||||
|
||||
impl<'a> Exportable<'a> for Table {
|
||||
fn to_export(&self) -> Export {
|
||||
ExportTable {
|
||||
vm_table: VMExportTable {
|
||||
from: self.table.clone(),
|
||||
instance_ref: None,
|
||||
},
|
||||
}
|
||||
.into()
|
||||
ExportTable { vm_table: VMExportTable { from: self.table.clone(), instance_ref: None } }
|
||||
.into()
|
||||
}
|
||||
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
|
||||
@@ -137,9 +137,7 @@ impl IntoIterator for ImportObject {
|
||||
type Item = ((String, String), Export);
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
ImportObjectIterator {
|
||||
elements: self.get_objects(),
|
||||
}
|
||||
ImportObjectIterator { elements: self.get_objects() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,10 +168,7 @@ impl fmt::Debug for 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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,11 +125,8 @@ impl Instance {
|
||||
})
|
||||
.collect::<Exports>();
|
||||
|
||||
let instance = Self {
|
||||
handle: Arc::new(Mutex::new(handle)),
|
||||
module: module.clone(),
|
||||
exports,
|
||||
};
|
||||
let instance =
|
||||
Self { handle: Arc::new(Mutex::new(handle)), module: module.clone(), exports };
|
||||
|
||||
// # Safety
|
||||
// `initialize_host_envs` should be called after instantiation but before
|
||||
@@ -168,8 +165,6 @@ impl Instance {
|
||||
|
||||
impl fmt::Debug for Instance {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
html_logo_url = "https://github.com/wasmerio.png?size=200",
|
||||
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)]
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
|
||||
@@ -101,10 +101,7 @@ impl Module {
|
||||
pub fn new(store: &Store, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> {
|
||||
#[cfg(feature = "wat")]
|
||||
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())
|
||||
@@ -253,10 +250,7 @@ impl Module {
|
||||
}
|
||||
|
||||
fn from_artifact(store: &Store, artifact: Arc<dyn Artifact>) -> Self {
|
||||
Self {
|
||||
store: store.clone(),
|
||||
artifact,
|
||||
}
|
||||
Self { store: store.clone(), artifact }
|
||||
}
|
||||
|
||||
pub(crate) fn instantiate(
|
||||
@@ -265,8 +259,7 @@ impl Module {
|
||||
) -> Result<InstanceHandle, InstantiationError> {
|
||||
unsafe {
|
||||
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
|
||||
// the data, call the start function and so. However, if any
|
||||
@@ -425,8 +418,6 @@ impl Module {
|
||||
|
||||
impl fmt::Debug for Module {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +41,7 @@ where
|
||||
exported: ExportFunction,
|
||||
definition: FunctionDefinition,
|
||||
) -> Self {
|
||||
Self {
|
||||
definition,
|
||||
store,
|
||||
exported,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
Self { definition, store, exported, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
pub(crate) fn vmctx(&self) -> VMFunctionEnvironment {
|
||||
@@ -97,11 +92,7 @@ where
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,7 @@ impl<T: Copy, Ty> WasmPtr<T, Ty> {
|
||||
/// Create a new `WasmPtr` at the given offset.
|
||||
#[inline]
|
||||
pub fn new(offset: u32) -> Self {
|
||||
Self {
|
||||
offset,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
Self { offset, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
/// Get the offset into Wasm linear memory for this `WasmPtr`.
|
||||
@@ -270,10 +267,7 @@ unsafe impl<T: Copy, Ty> FromToNativeWasmType for WasmPtr<T, Ty> {
|
||||
self.offset as i32
|
||||
}
|
||||
fn from_native(n: Self::Native) -> Self {
|
||||
Self {
|
||||
offset: n as u32,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
Self { offset: n as u32, _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,10 +275,7 @@ unsafe impl<T: Copy, Ty> ValueType for WasmPtr<T, Ty> {}
|
||||
|
||||
impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
offset: self.offset,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
Self { offset: self.offset, _phantom: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,10 +39,7 @@ impl Store {
|
||||
where
|
||||
E: Engine + ?Sized,
|
||||
{
|
||||
Self {
|
||||
engine: engine.cloned(),
|
||||
tunables: Arc::new(tunables),
|
||||
}
|
||||
Self { engine: engine.cloned(), tunables: Arc::new(tunables) }
|
||||
}
|
||||
|
||||
/// Returns the [`Tunables`].
|
||||
@@ -109,10 +106,7 @@ impl Default for Store {
|
||||
let config = get_config();
|
||||
let engine = get_engine(config);
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,9 +84,7 @@ impl Tunables for BaseTunables {
|
||||
offset_guard_size: self.static_memory_offset_guard_size,
|
||||
}
|
||||
} else {
|
||||
MemoryStyle::Dynamic {
|
||||
offset_guard_size: self.dynamic_memory_offset_guard_size,
|
||||
}
|
||||
MemoryStyle::Dynamic { offset_guard_size: self.dynamic_memory_offset_guard_size }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,11 +113,7 @@ impl Tunables for BaseTunables {
|
||||
style: &MemoryStyle,
|
||||
vm_definition_location: NonNull<VMMemoryDefinition>,
|
||||
) -> 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`].
|
||||
@@ -142,11 +136,7 @@ impl Tunables for BaseTunables {
|
||||
style: &TableStyle,
|
||||
vm_definition_location: NonNull<VMTableDefinition>,
|
||||
) -> 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)?))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,10 +172,7 @@ mod tests {
|
||||
let requested = MemoryType::new(3, Some(16), true);
|
||||
let style = tunables.memory_style(&requested);
|
||||
match style {
|
||||
MemoryStyle::Static {
|
||||
bound,
|
||||
offset_guard_size,
|
||||
} => {
|
||||
MemoryStyle::Static { bound, offset_guard_size } => {
|
||||
assert_eq!(bound, Pages(2048));
|
||||
assert_eq!(offset_guard_size, 128);
|
||||
}
|
||||
|
||||
@@ -66,10 +66,8 @@ impl ValFuncRef for Val {
|
||||
let anyfunc: *const wasmer_vm::VMCallerCheckedAnyfunc = *func_ref;
|
||||
&*anyfunc
|
||||
};
|
||||
let signature = store
|
||||
.engine()
|
||||
.lookup_signature(item.type_index)
|
||||
.expect("Signature not found in store");
|
||||
let signature =
|
||||
store.engine().lookup_signature(item.type_index).expect("Signature not found in store");
|
||||
let export = wasmer_engine::ExportFunction {
|
||||
// TODO:
|
||||
// figure out if we ever need a value here: need testing with complicated import patterns
|
||||
|
||||
@@ -5,22 +5,10 @@ use wasmer::*;
|
||||
fn global_new() -> Result<()> {
|
||||
let store = Store::default();
|
||||
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));
|
||||
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(())
|
||||
}
|
||||
@@ -61,11 +49,7 @@ fn global_set() -> Result<()> {
|
||||
#[test]
|
||||
fn table_new() -> Result<()> {
|
||||
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 table = Table::new(&store, table_type, Value::FuncRef(Some(f)))?;
|
||||
assert_eq!(*table.ty(), table_type);
|
||||
@@ -86,11 +70,7 @@ fn table_new() -> Result<()> {
|
||||
#[ignore]
|
||||
fn table_get() -> Result<()> {
|
||||
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 table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
|
||||
assert_eq!(*table.ty(), table_type);
|
||||
@@ -109,11 +89,7 @@ fn table_set() -> Result<()> {
|
||||
#[test]
|
||||
fn table_grow() -> Result<()> {
|
||||
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 table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
|
||||
// Growing to a bigger maximum should return None
|
||||
@@ -137,11 +113,7 @@ fn table_copy() -> Result<()> {
|
||||
#[test]
|
||||
fn memory_new() -> Result<()> {
|
||||
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)?;
|
||||
assert_eq!(memory.size(), Pages(0));
|
||||
assert_eq!(*memory.ty(), memory_type);
|
||||
@@ -163,10 +135,7 @@ fn memory_grow() -> Result<()> {
|
||||
let result = memory.grow(Pages(10));
|
||||
assert_eq!(
|
||||
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);
|
||||
@@ -183,20 +152,14 @@ fn function_new() -> Result<()> {
|
||||
let function = Function::new_native(&store, || {});
|
||||
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
|
||||
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| {});
|
||||
assert_eq!(
|
||||
function.ty().clone(),
|
||||
FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![])
|
||||
);
|
||||
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) });
|
||||
assert_eq!(
|
||||
function.ty().clone(),
|
||||
@@ -216,10 +179,7 @@ fn function_new_env() -> Result<()> {
|
||||
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
|
||||
let function =
|
||||
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(
|
||||
&store,
|
||||
my_env.clone(),
|
||||
@@ -231,10 +191,7 @@ fn function_new_env() -> Result<()> {
|
||||
);
|
||||
let function =
|
||||
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(
|
||||
&store,
|
||||
my_env.clone(),
|
||||
@@ -413,10 +370,7 @@ fn manually_generate_wasmer_env() -> Result<()> {
|
||||
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);
|
||||
assert_eq!(result, 21);
|
||||
|
||||
@@ -30,10 +30,7 @@ fn exports_work_after_multiple_instances_have_been_freed() -> Result<()> {
|
||||
drop(instance3);
|
||||
|
||||
// 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(())
|
||||
}
|
||||
|
||||
@@ -63,35 +63,19 @@ fn imports() -> Result<()> {
|
||||
// Now we test the iterators
|
||||
assert_eq!(
|
||||
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!(
|
||||
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!(
|
||||
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!(
|
||||
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(())
|
||||
}
|
||||
@@ -109,18 +93,9 @@ fn exports() -> Result<()> {
|
||||
assert_eq!(
|
||||
module.exports().collect::<Vec<_>>(),
|
||||
vec![
|
||||
ExportType::new(
|
||||
"func",
|
||||
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("func", 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(
|
||||
"global",
|
||||
ExternType::Global(GlobalType::new(Type::I32, Mutability::Const))
|
||||
@@ -135,24 +110,15 @@ fn exports() -> Result<()> {
|
||||
);
|
||||
assert_eq!(
|
||||
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!(
|
||||
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!(
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -112,9 +112,8 @@ fn func_ref_passed_and_called() -> Result<()> {
|
||||
}
|
||||
|
||||
{
|
||||
let f: NativeFunc<(), i32> = instance
|
||||
.exports
|
||||
.get_native_function("call_host_func_with_wasm_func")?;
|
||||
let f: NativeFunc<(), i32> =
|
||||
instance.exports.get_native_function("call_host_func_with_wasm_func")?;
|
||||
let result = f.call()?;
|
||||
assert_eq!(result, 63);
|
||||
}
|
||||
@@ -415,12 +414,10 @@ fn extern_ref_ref_counting_table_instructions() -> Result<()> {
|
||||
let module = Module::new(&store, wat)?;
|
||||
let instance = Instance::new(&module, &imports! {})?;
|
||||
|
||||
let grow_table_with_ref: NativeFunc<(ExternRef, i32), i32> = instance
|
||||
.exports
|
||||
.get_native_function("grow_table_with_ref")?;
|
||||
let fill_table_with_ref: NativeFunc<(ExternRef, i32, i32), ()> = instance
|
||||
.exports
|
||||
.get_native_function("fill_table_with_ref")?;
|
||||
let grow_table_with_ref: NativeFunc<(ExternRef, i32), i32> =
|
||||
instance.exports.get_native_function("grow_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<(), ()> =
|
||||
instance.exports.get_native_function("copy_into_table2")?;
|
||||
let table1: &Table = instance.exports.get_table("table1")?;
|
||||
|
||||
@@ -142,9 +142,8 @@ pub unsafe extern "C" fn wasmer_export_descriptors(
|
||||
) {
|
||||
let module = &*(module as *const Module);
|
||||
|
||||
let named_export_descriptors: Box<NamedExportDescriptors> = Box::new(NamedExportDescriptors(
|
||||
module.exports().into_iter().map(|e| e.into()).collect(),
|
||||
));
|
||||
let named_export_descriptors: Box<NamedExportDescriptors> =
|
||||
Box::new(NamedExportDescriptors(module.exports().into_iter().map(|e| e.into()).collect()));
|
||||
*export_descriptors =
|
||||
Box::into_raw(named_export_descriptors) as *mut wasmer_export_descriptors_t;
|
||||
}
|
||||
@@ -403,10 +402,8 @@ pub unsafe extern "C" fn wasmer_export_to_memory(
|
||||
let named_export = &*(export as *const NamedExport);
|
||||
let instance = named_export.instance.as_ref();
|
||||
|
||||
if let Ok(exported_memory) = instance
|
||||
.instance
|
||||
.exports
|
||||
.get::<Memory>(&named_export.export_type.name())
|
||||
if let Ok(exported_memory) =
|
||||
instance.instance.exports.get::<Memory>(&named_export.export_type.name())
|
||||
{
|
||||
let mem = Box::new(exported_memory.clone());
|
||||
*memory = Box::into_raw(mem) as *mut wasmer_memory_t;
|
||||
@@ -449,16 +446,12 @@ pub unsafe extern "C" fn wasmer_export_func_call(
|
||||
results_len: c_uint,
|
||||
) -> wasmer_result_t {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -479,11 +472,7 @@ 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 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,
|
||||
Err(err) => {
|
||||
update_last_error(err);
|
||||
@@ -530,10 +519,7 @@ pub unsafe extern "C" fn wasmer_export_func_call(
|
||||
|
||||
impl From<ExportType> for NamedExportDescriptor {
|
||||
fn from(et: ExportType) -> Self {
|
||||
NamedExportDescriptor {
|
||||
name: et.name().to_string(),
|
||||
kind: et.into(),
|
||||
}
|
||||
NamedExportDescriptor { name: et.name().to_string(), kind: et.into() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,7 @@ pub unsafe extern "C" fn wasmer_global_get_descriptor(
|
||||
) -> wasmer_global_descriptor_t {
|
||||
let global = &*(global as *mut Global);
|
||||
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
|
||||
|
||||
@@ -343,9 +343,7 @@ 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 {
|
||||
import_object_iter.cast::<WasmerImportObjectIterator>()
|
||||
} 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;
|
||||
};
|
||||
let iter = import_object_iter.as_mut();
|
||||
@@ -359,11 +357,7 @@ pub unsafe extern "C" fn wasmer_import_object_iter_destroy(
|
||||
import_object_iter: Option<NonNull<wasmer_import_object_iter_t>>,
|
||||
) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,10 +420,8 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
||||
let mut import_data: HashMap<String, Exports> = HashMap::new();
|
||||
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
||||
for import in imports {
|
||||
let module_name = slice::from_raw_parts(
|
||||
import.module_name.bytes,
|
||||
import.module_name.bytes_len as usize,
|
||||
);
|
||||
let module_name =
|
||||
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize);
|
||||
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
||||
s
|
||||
} else {
|
||||
@@ -438,10 +430,8 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
||||
});
|
||||
return wasmer_result_t::WASMER_ERROR;
|
||||
};
|
||||
let import_name = slice::from_raw_parts(
|
||||
import.import_name.bytes,
|
||||
import.import_name.bytes_len as usize,
|
||||
);
|
||||
let import_name =
|
||||
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize);
|
||||
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
||||
s
|
||||
} else {
|
||||
@@ -461,9 +451,7 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
||||
// TODO: investigate consistent usage of `FunctionWrapper` in this context
|
||||
let func_wrapper = import.value.func as *mut FunctionWrapper;
|
||||
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())
|
||||
}
|
||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||
@@ -476,9 +464,7 @@ 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);
|
||||
}
|
||||
|
||||
@@ -646,9 +632,7 @@ unsafe impl Sync for LegacyEnv {}
|
||||
|
||||
impl LegacyEnv {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,9 +750,7 @@ pub unsafe extern "C" fn wasmer_trap(
|
||||
error_message: *const c_char,
|
||||
) -> wasmer_result_t {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -213,9 +213,8 @@ 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 wasi_state = wasi_state_builder.build().unwrap();
|
||||
let wasi_env = wasi::WasiEnv::new(wasi_state);
|
||||
let import_object_inner: Box<dyn NamedResolver> = Box::new(
|
||||
wasi::generate_import_object_from_env(store, wasi_env, wasi::WasiVersion::Latest),
|
||||
);
|
||||
let import_object_inner: Box<dyn NamedResolver> =
|
||||
Box::new(wasi::generate_import_object_from_env(store, wasi_env, wasi::WasiVersion::Latest));
|
||||
let import_object: Box<CAPIImportObject> = Box::new(CAPIImportObject {
|
||||
import_object: import_object_inner,
|
||||
imported_memories: vec![],
|
||||
|
||||
@@ -124,34 +124,25 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
||||
let wasm_bytes = if let Some(wasm_bytes_inner) = wasm_bytes {
|
||||
wasm_bytes_inner
|
||||
} 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;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let mut imported_memories = vec![];
|
||||
let mut instance_pointers_to_update = vec![];
|
||||
let imports: &[wasmer_import_t] = if imports_len == 0 {
|
||||
&[]
|
||||
} else {
|
||||
slice::from_raw_parts(imports, imports_len as usize)
|
||||
};
|
||||
let imports: &[wasmer_import_t] =
|
||||
if imports_len == 0 { &[] } else { slice::from_raw_parts(imports, imports_len as usize) };
|
||||
|
||||
let mut import_object = ImportObject::new();
|
||||
let mut namespaces = HashMap::new();
|
||||
for import in imports {
|
||||
let module_name = slice::from_raw_parts(
|
||||
import.module_name.bytes,
|
||||
import.module_name.bytes_len as usize,
|
||||
);
|
||||
let module_name =
|
||||
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize);
|
||||
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
||||
s
|
||||
} else {
|
||||
@@ -160,10 +151,8 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
||||
});
|
||||
return wasmer_result_t::WASMER_ERROR;
|
||||
};
|
||||
let import_name = slice::from_raw_parts(
|
||||
import.import_name.bytes,
|
||||
import.import_name.bytes_len as usize,
|
||||
);
|
||||
let import_name =
|
||||
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize);
|
||||
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
||||
s
|
||||
} else {
|
||||
@@ -223,11 +212,7 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
||||
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));
|
||||
for to_update in instance_pointers_to_update {
|
||||
let mut to_update_guard = to_update.lock().unwrap();
|
||||
@@ -322,25 +307,19 @@ pub unsafe extern "C" fn wasmer_instance_call(
|
||||
results_len: u32,
|
||||
) -> wasmer_result_t {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -469,10 +448,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
||||
.instance
|
||||
.module()
|
||||
.exports()
|
||||
.map(|export_type| NamedExport {
|
||||
export_type,
|
||||
instance,
|
||||
})
|
||||
.map(|export_type| NamedExport { export_type, instance })
|
||||
.collect();
|
||||
|
||||
let named_exports: Box<NamedExports> = Box::new(NamedExports(exports_vec));
|
||||
@@ -578,19 +554,13 @@ pub unsafe extern "C" fn wasmer_instance_context_memory(
|
||||
{
|
||||
name
|
||||
} 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;
|
||||
};
|
||||
let memory = instance
|
||||
.instance
|
||||
.exports
|
||||
.get_memory(exported_memory_name)
|
||||
.expect(&format!(
|
||||
"Module exports memory named `{}` but it's inaccessible",
|
||||
&exported_memory_name
|
||||
));
|
||||
let memory = instance.instance.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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +60,7 @@ pub unsafe extern "C" fn wasmer_memory_new(
|
||||
memory: *mut *mut wasmer_memory_t,
|
||||
limits: wasmer_limits_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 desc = MemoryType::new(Pages(limits.min), max, false);
|
||||
match Memory::new(store, desc) {
|
||||
@@ -73,9 +69,7 @@ pub unsafe extern "C" fn wasmer_memory_new(
|
||||
wasmer_result_t::WASMER_OK
|
||||
}
|
||||
Err(err) => {
|
||||
update_last_error(CApiError {
|
||||
msg: err.to_string(),
|
||||
});
|
||||
update_last_error(CApiError { msg: err.to_string() });
|
||||
wasmer_result_t::WASMER_ERROR
|
||||
}
|
||||
}
|
||||
@@ -101,9 +95,7 @@ pub unsafe extern "C" fn wasmer_memory_new(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -> wasmer_result_t {
|
||||
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;
|
||||
}
|
||||
@@ -114,9 +106,7 @@ pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -
|
||||
match grow_result {
|
||||
Ok(_) => wasmer_result_t::WASMER_OK,
|
||||
Err(err) => {
|
||||
update_last_error(CApiError {
|
||||
msg: err.to_string(),
|
||||
});
|
||||
update_last_error(CApiError { msg: err.to_string() });
|
||||
wasmer_result_t::WASMER_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,10 +92,8 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
||||
let mut import_object = ImportObject::new();
|
||||
let mut namespaces = HashMap::new();
|
||||
for import in imports {
|
||||
let module_name = slice::from_raw_parts(
|
||||
import.module_name.bytes,
|
||||
import.module_name.bytes_len as usize,
|
||||
);
|
||||
let module_name =
|
||||
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize);
|
||||
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
||||
s
|
||||
} else {
|
||||
@@ -104,10 +102,8 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
||||
});
|
||||
return wasmer_result_t::WASMER_ERROR;
|
||||
};
|
||||
let import_name = slice::from_raw_parts(
|
||||
import.import_name.bytes,
|
||||
import.import_name.bytes_len as usize,
|
||||
);
|
||||
let import_name =
|
||||
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize);
|
||||
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
||||
s
|
||||
} else {
|
||||
@@ -153,11 +149,7 @@ 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;
|
||||
wasmer_result_t::WASMER_OK
|
||||
@@ -224,9 +216,7 @@ pub unsafe extern "C" fn wasmer_module_serialize(
|
||||
wasmer_result_t::WASMER_OK
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -268,10 +258,8 @@ pub unsafe extern "C" fn wasmer_serialized_module_from_bytes(
|
||||
return wasmer_result_t::WASMER_ERROR;
|
||||
}
|
||||
|
||||
let serialized_module_bytes: &[u8] = slice::from_raw_parts(
|
||||
serialized_module_bytes,
|
||||
serialized_module_bytes_length as usize,
|
||||
);
|
||||
let serialized_module_bytes: &[u8] =
|
||||
slice::from_raw_parts(serialized_module_bytes, serialized_module_bytes_length as usize);
|
||||
|
||||
*serialized_module = Box::into_raw(Box::new(serialized_module_bytes)) as _;
|
||||
wasmer_result_t::WASMER_OK
|
||||
@@ -293,9 +281,7 @@ pub unsafe extern "C" fn wasmer_module_deserialize(
|
||||
let serialized_module: &[u8] = if let Some(sm) = serialized_module {
|
||||
&*(sm as *const wasmer_serialized_module_t as *const &[u8])
|
||||
} 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -36,16 +36,8 @@ pub unsafe extern "C" fn wasmer_table_new(
|
||||
table: *mut *mut wasmer_table_t,
|
||||
limits: wasmer_limits_t,
|
||||
) -> wasmer_result_t {
|
||||
let max = if limits.max.has_some {
|
||||
Some(limits.max.some)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let desc = TableType {
|
||||
ty: ValType::FuncRef,
|
||||
minimum: limits.min,
|
||||
maximum: max,
|
||||
};
|
||||
let max = if limits.max.has_some { Some(limits.max.some) } else { None };
|
||||
let desc = TableType { ty: ValType::FuncRef, minimum: limits.min, maximum: max };
|
||||
let store = get_global_store();
|
||||
let result = Table::new(store, desc, get_default_table_value(ValType::FuncRef));
|
||||
let new_table = match result {
|
||||
|
||||
@@ -74,22 +74,18 @@ impl From<wasmer_value_t> for Val {
|
||||
unsafe {
|
||||
#[allow(unreachable_patterns, non_snake_case)]
|
||||
match v {
|
||||
wasmer_value_t {
|
||||
tag: wasmer_value_tag::WASM_I32,
|
||||
value: wasmer_value { I32 },
|
||||
} => Val::I32(I32),
|
||||
wasmer_value_t {
|
||||
tag: wasmer_value_tag::WASM_I64,
|
||||
value: wasmer_value { I64 },
|
||||
} => Val::I64(I64),
|
||||
wasmer_value_t {
|
||||
tag: wasmer_value_tag::WASM_F32,
|
||||
value: wasmer_value { F32 },
|
||||
} => Val::F32(F32),
|
||||
wasmer_value_t {
|
||||
tag: wasmer_value_tag::WASM_F64,
|
||||
value: wasmer_value { F64 },
|
||||
} => Val::F64(F64),
|
||||
wasmer_value_t { tag: wasmer_value_tag::WASM_I32, value: wasmer_value { I32 } } => {
|
||||
Val::I32(I32)
|
||||
}
|
||||
wasmer_value_t { tag: wasmer_value_tag::WASM_I64, value: wasmer_value { I64 } } => {
|
||||
Val::I64(I64)
|
||||
}
|
||||
wasmer_value_t { tag: wasmer_value_tag::WASM_F32, 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"),
|
||||
}
|
||||
}
|
||||
@@ -99,22 +95,18 @@ impl From<wasmer_value_t> for Val {
|
||||
impl From<Val> for wasmer_value_t {
|
||||
fn from(val: Val) -> Self {
|
||||
match val {
|
||||
Val::I32(x) => wasmer_value_t {
|
||||
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::F32(x) => wasmer_value_t {
|
||||
tag: wasmer_value_tag::WASM_F32,
|
||||
value: wasmer_value { F32: x },
|
||||
},
|
||||
Val::F64(x) => wasmer_value_t {
|
||||
tag: wasmer_value_tag::WASM_F64,
|
||||
value: wasmer_value { F64: x },
|
||||
},
|
||||
Val::I32(x) => {
|
||||
wasmer_value_t { 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::F32(x) => {
|
||||
wasmer_value_t { tag: wasmer_value_tag::WASM_F32, 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::ExternRef(_) => unimplemented!("ExternRef not supported in C API"),
|
||||
Val::FuncRef(_) => unimplemented!("FuncRef not supported in C API"),
|
||||
|
||||
@@ -144,11 +144,7 @@ pub unsafe extern "C" fn wasmer_last_error_message(
|
||||
|
||||
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
|
||||
// accidentally read into garbage.
|
||||
|
||||
@@ -17,9 +17,7 @@ pub struct OrderedResolver {
|
||||
|
||||
impl Resolver for OrderedResolver {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -435,9 +435,7 @@ pub extern "C" fn wasm_engine_new_with_config(
|
||||
where
|
||||
M: ToString,
|
||||
{
|
||||
update_last_error(CApiError {
|
||||
msg: msg.to_string(),
|
||||
});
|
||||
update_last_error(CApiError { msg: msg.to_string() });
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
10
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
10
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
@@ -18,10 +18,7 @@ pub struct wasm_func_t {
|
||||
|
||||
impl wasm_func_t {
|
||||
pub(crate) fn new(function: Function) -> Self {
|
||||
Self {
|
||||
tag: CApiExternTag::Function,
|
||||
inner: Box::new(function),
|
||||
}
|
||||
Self { tag: CApiExternTag::Function, inner: Box::new(function) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,10 +168,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
||||
let function = Function::new_with_env(
|
||||
&store.inner,
|
||||
func_sig,
|
||||
WrapperEnv {
|
||||
env,
|
||||
env_finalizer: Arc::new(env_finalizer),
|
||||
},
|
||||
WrapperEnv { env, env_finalizer: Arc::new(env_finalizer) },
|
||||
trampoline,
|
||||
);
|
||||
|
||||
|
||||
5
lib/c-api/src/wasm_c_api/externals/global.rs
vendored
5
lib/c-api/src/wasm_c_api/externals/global.rs
vendored
@@ -16,10 +16,7 @@ pub struct wasm_global_t {
|
||||
|
||||
impl wasm_global_t {
|
||||
pub(crate) fn new(global: Global) -> Self {
|
||||
Self {
|
||||
tag: CApiExternTag::Global,
|
||||
inner: Box::new(global),
|
||||
}
|
||||
Self { tag: CApiExternTag::Global, inner: Box::new(global) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
5
lib/c-api/src/wasm_c_api/externals/memory.rs
vendored
5
lib/c-api/src/wasm_c_api/externals/memory.rs
vendored
@@ -14,10 +14,7 @@ pub struct wasm_memory_t {
|
||||
|
||||
impl wasm_memory_t {
|
||||
pub(crate) fn new(memory: Memory) -> Self {
|
||||
Self {
|
||||
tag: CApiExternTag::Memory,
|
||||
inner: Box::new(memory),
|
||||
}
|
||||
Self { tag: CApiExternTag::Memory, inner: Box::new(memory) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
28
lib/c-api/src/wasm_c_api/externals/mod.rs
vendored
28
lib/c-api/src/wasm_c_api/externals/mod.rs
vendored
@@ -99,25 +99,17 @@ impl Clone for wasm_extern_t {
|
||||
fn clone(&self) -> Self {
|
||||
match self.get_tag() {
|
||||
CApiExternTag::Function => Self {
|
||||
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() },
|
||||
},
|
||||
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() } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
lib/c-api/src/wasm_c_api/externals/table.rs
vendored
5
lib/c-api/src/wasm_c_api/externals/table.rs
vendored
@@ -13,10 +13,7 @@ pub struct wasm_table_t {
|
||||
|
||||
impl wasm_table_t {
|
||||
pub(crate) fn new(table: Table) -> Self {
|
||||
Self {
|
||||
tag: CApiExternTag::Table,
|
||||
inner: Box::new(table),
|
||||
}
|
||||
Self { tag: CApiExternTag::Table, inner: Box::new(table) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ pub unsafe extern "C" fn wasm_module_new(
|
||||
let bytes = bytes.into_slice()?;
|
||||
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.
|
||||
@@ -488,11 +486,7 @@ pub unsafe extern "C" fn wasm_module_deserialize(
|
||||
|
||||
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
|
||||
|
||||
@@ -16,10 +16,7 @@ pub extern "C" fn wasm_exporttype_new(
|
||||
extern_type: Option<Box<wasm_externtype_t>>,
|
||||
) -> Option<Box<wasm_exporttype_t>> {
|
||||
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]
|
||||
|
||||
@@ -13,11 +13,7 @@ impl WasmFunctionType {
|
||||
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());
|
||||
|
||||
Self {
|
||||
function_type,
|
||||
params,
|
||||
results,
|
||||
}
|
||||
Self { function_type, params, results }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +32,7 @@ pub struct wasm_functype_t {
|
||||
|
||||
impl wasm_functype_t {
|
||||
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 {
|
||||
@@ -61,24 +55,15 @@ pub unsafe extern "C" fn wasm_functype_new(
|
||||
let params = params?;
|
||||
let results = results?;
|
||||
|
||||
let params_as_valtype: Vec<ValType> = params
|
||||
.into_slice()?
|
||||
.into_iter()
|
||||
.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<_>>();
|
||||
let params_as_valtype: Vec<ValType> =
|
||||
params.into_slice()?.into_iter().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(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]
|
||||
|
||||
@@ -15,10 +15,7 @@ impl WasmGlobalType {
|
||||
pub(crate) fn new(global_type: GlobalType) -> Self {
|
||||
let content = Box::new(global_type.ty.into());
|
||||
|
||||
Self {
|
||||
global_type,
|
||||
content,
|
||||
}
|
||||
Self { global_type, content }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +28,7 @@ pub struct wasm_globaltype_t {
|
||||
|
||||
impl wasm_globaltype_t {
|
||||
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 {
|
||||
@@ -55,10 +50,8 @@ pub unsafe extern "C" fn wasm_globaltype_new(
|
||||
) -> Option<Box<wasm_globaltype_t>> {
|
||||
let valtype = valtype?;
|
||||
let mutability: wasm_mutability_enum = mutability.try_into().ok()?;
|
||||
let global_type = Box::new(wasm_globaltype_t::new(GlobalType::new(
|
||||
(*valtype).into(),
|
||||
mutability.into(),
|
||||
)));
|
||||
let global_type =
|
||||
Box::new(wasm_globaltype_t::new(GlobalType::new((*valtype).into(), mutability.into())));
|
||||
|
||||
wasm_valtype_delete(Some(valtype));
|
||||
|
||||
|
||||
@@ -18,17 +18,9 @@ pub extern "C" fn wasm_importtype_new(
|
||||
name: Option<&wasm_name_t>,
|
||||
extern_type: Option<Box<wasm_externtype_t>>,
|
||||
) -> Option<Box<wasm_importtype_t>> {
|
||||
let (module, name) = 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?,
|
||||
}))
|
||||
let (module, name) =
|
||||
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? }))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -61,10 +53,6 @@ impl From<&ImportType> for wasm_importtype_t {
|
||||
let name: owned_wasm_name_t = other.name().to_string().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 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,16 +11,10 @@ impl WasmMemoryType {
|
||||
pub(crate) fn new(memory_type: MemoryType) -> Self {
|
||||
let limits = Box::new(wasm_limits_t {
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +27,7 @@ pub struct wasm_memorytype_t {
|
||||
|
||||
impl wasm_memorytype_t {
|
||||
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 {
|
||||
@@ -53,15 +45,10 @@ wasm_declare_boxed_vec!(memorytype);
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
|
||||
let min_pages = Pages(limits.min as _);
|
||||
let max_pages = if limits.max == LIMITS_MAX_SENTINEL {
|
||||
None
|
||||
} else {
|
||||
Some(Pages(limits.max as _))
|
||||
};
|
||||
let max_pages =
|
||||
if limits.max == LIMITS_MAX_SENTINEL { 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]
|
||||
|
||||
@@ -50,10 +50,7 @@ impl owned_wasm_name_t {
|
||||
/// You must ensure that the data pointed to by `wasm_name_t` is valid and
|
||||
/// that it is not owned by anyone else.
|
||||
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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,11 +23,7 @@ impl WasmTableType {
|
||||
});
|
||||
let content = Box::new(table_type.ty.into());
|
||||
|
||||
Self {
|
||||
table_type,
|
||||
limits,
|
||||
content,
|
||||
}
|
||||
Self { table_type, limits, content }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +36,7 @@ pub struct wasm_tabletype_t {
|
||||
|
||||
impl wasm_tabletype_t {
|
||||
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 {
|
||||
@@ -61,11 +55,7 @@ pub unsafe extern "C" fn wasm_tabletype_new(
|
||||
limits: &wasm_limits_t,
|
||||
) -> Option<Box<wasm_tabletype_t>> {
|
||||
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(
|
||||
(*valtype).into(),
|
||||
limits.min as _,
|
||||
|
||||
@@ -50,9 +50,7 @@ pub struct wasm_valtype_t {
|
||||
|
||||
impl Default for wasm_valtype_t {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
valkind: wasm_valkind_enum::WASM_I32,
|
||||
}
|
||||
Self { valkind: wasm_valkind_enum::WASM_I32 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,9 +70,7 @@ impl From<&wasm_valtype_t> for ValType {
|
||||
|
||||
impl From<ValType> for wasm_valtype_t {
|
||||
fn from(other: ValType) -> Self {
|
||||
Self {
|
||||
valkind: other.into(),
|
||||
}
|
||||
Self { valkind: other.into() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +87,5 @@ pub unsafe extern "C" fn wasm_valtype_delete(_valtype: Option<Box<wasm_valtype_t
|
||||
|
||||
#[no_mangle]
|
||||
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
|
||||
}
|
||||
|
||||
@@ -133,10 +133,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
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! {
|
||||
#include "tests/wasmer_wasm.h"
|
||||
@@ -155,23 +152,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
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(
|
||||
"SINGLEPASS",
|
||||
if cfg!(feature = "singlepass") {
|
||||
"1"
|
||||
} else {
|
||||
"0"
|
||||
},
|
||||
);
|
||||
set_var("SINGLEPASS", if cfg!(feature = "singlepass") { "1" } else { "0" });
|
||||
|
||||
(assert_c! {
|
||||
#include "tests/wasmer_wasm.h"
|
||||
@@ -196,14 +179,7 @@ mod tests {
|
||||
fn test_wasmer_is_engine_available() {
|
||||
set_var("JIT", if cfg!(feature = "jit") { "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! {
|
||||
#include "tests/wasmer_wasm.h"
|
||||
|
||||
@@ -55,9 +55,7 @@ pub struct wasmer_features_t {
|
||||
/// See the module's documentation.
|
||||
#[no_mangle]
|
||||
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`].
|
||||
|
||||
@@ -215,10 +215,7 @@ pub extern "C" fn wasmer_metering_get_remaining_points(instance: &wasm_instance_
|
||||
/// See module's documentation.
|
||||
#[no_mangle]
|
||||
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.
|
||||
@@ -313,7 +310,5 @@ pub extern "C" fn wasmer_metering_as_middleware(
|
||||
) -> Option<Box<wasmer_middleware_t>> {
|
||||
let metering = metering?;
|
||||
|
||||
Some(Box::new(wasmer_middleware_t {
|
||||
inner: metering.inner,
|
||||
}))
|
||||
Some(Box::new(wasmer_middleware_t { inner: metering.inner }))
|
||||
}
|
||||
|
||||
@@ -147,10 +147,7 @@ pub unsafe extern "C" fn wasmer_triple_new(
|
||||
triple: Option<&wasm_name_t>,
|
||||
) -> Option<Box<wasmer_triple_t>> {
|
||||
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 {
|
||||
inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })),
|
||||
@@ -183,9 +180,7 @@ pub unsafe extern "C" fn wasmer_triple_new(
|
||||
/// See also [`wasmer_triple_new`].
|
||||
#[no_mangle]
|
||||
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`].
|
||||
@@ -265,9 +260,7 @@ pub struct wasmer_cpu_features_t {
|
||||
/// See [`wasmer_cpu_features_t`].
|
||||
#[no_mangle]
|
||||
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`].
|
||||
|
||||
@@ -171,11 +171,9 @@ fn wasi_get_unordered_imports_inner(
|
||||
|
||||
let store = &store.inner;
|
||||
|
||||
let version = c_try!(
|
||||
get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
|
||||
msg: "could not detect a WASI version on the given module".to_string(),
|
||||
})
|
||||
);
|
||||
let version = c_try!(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);
|
||||
|
||||
|
||||
@@ -114,10 +114,7 @@ wasm_declare_vec!(val);
|
||||
|
||||
impl Clone for wasm_val_t {
|
||||
fn clone(&self) -> Self {
|
||||
wasm_val_t {
|
||||
kind: self.kind,
|
||||
of: self.of.clone(),
|
||||
}
|
||||
wasm_val_t { kind: self.kind, of: self.of.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,18 +127,10 @@ pub unsafe extern "C" fn wasm_val_copy(
|
||||
out.kind = val.kind;
|
||||
out.of = match val.kind.try_into() {
|
||||
Ok(kind) => match kind {
|
||||
wasm_valkind_enum::WASM_I32 => wasm_val_inner {
|
||||
int32_t: val.of.int32_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_I32 => wasm_val_inner { int32_t: val.of.int32_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_FUNCREF => wasm_val_inner { wref: val.of.wref },
|
||||
},
|
||||
|
||||
@@ -13,9 +13,7 @@ pub struct OutputCapturer {
|
||||
|
||||
impl OutputCapturer {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
buffer: VecDeque::new(),
|
||||
}
|
||||
Self { buffer: VecDeque::new() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,36 +46,21 @@ impl WasiFile for OutputCapturer {
|
||||
// fail when reading or Seeking
|
||||
impl Read for OutputCapturer {
|
||||
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> {
|
||||
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> {
|
||||
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<()> {
|
||||
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 {
|
||||
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 {
|
||||
|
||||
@@ -175,24 +175,18 @@ pub struct wasi_env_t {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasi_env_new(mut config: Box<wasi_config_t>) -> Option<Box<wasi_env_t>> {
|
||||
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 {
|
||||
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
|
||||
|
||||
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`].
|
||||
@@ -272,10 +266,7 @@ 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>() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -367,11 +358,9 @@ fn wasi_get_imports_inner(
|
||||
|
||||
let store = &store.inner;
|
||||
|
||||
let version = c_try!(
|
||||
get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
|
||||
msg: "could not detect a WASI version on the given module".to_string(),
|
||||
})
|
||||
);
|
||||
let version = c_try!(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);
|
||||
|
||||
|
||||
32
lib/cache/benches/bench_filesystem_cache.rs
vendored
32
lib/cache/benches/bench_filesystem_cache.rs
vendored
@@ -18,11 +18,9 @@ pub fn store_cache_jit(c: &mut Criterion) {
|
||||
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||
let compiler = Singlepass::default();
|
||||
let store = Store::new(&JIT::new(compiler).engine());
|
||||
let module = Module::new(
|
||||
&store,
|
||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let module =
|
||||
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||
.unwrap();
|
||||
|
||||
c.bench_function("store jit module in filesystem cache", |b| {
|
||||
b.iter(|| {
|
||||
@@ -37,11 +35,9 @@ pub fn load_cache_jit(c: &mut Criterion) {
|
||||
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||
let compiler = Singlepass::default();
|
||||
let store = Store::new(&JIT::new(compiler).engine());
|
||||
let module = Module::new(
|
||||
&store,
|
||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let module =
|
||||
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||
.unwrap();
|
||||
let key = Hash::new([0u8; 32]);
|
||||
fs_cache.store(key, &module).unwrap();
|
||||
|
||||
@@ -55,11 +51,9 @@ pub fn store_cache_native(c: &mut Criterion) {
|
||||
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||
let compiler = Singlepass::default();
|
||||
let store = Store::new(&Native::new(compiler).engine());
|
||||
let module = Module::new(
|
||||
&store,
|
||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let module =
|
||||
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||
.unwrap();
|
||||
|
||||
c.bench_function("store native module in filesystem cache", |b| {
|
||||
b.iter(|| {
|
||||
@@ -74,11 +68,9 @@ pub fn load_cache_native(c: &mut Criterion) {
|
||||
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||
let compiler = Singlepass::default();
|
||||
let store = Store::new(&Native::new(compiler).engine());
|
||||
let module = Module::new(
|
||||
&store,
|
||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let module =
|
||||
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||
.unwrap();
|
||||
let key = Hash::new([0u8; 32]);
|
||||
fs_cache.store(key, &module).unwrap();
|
||||
|
||||
|
||||
5
lib/cache/src/filesystem.rs
vendored
5
lib/cache/src/filesystem.rs
vendored
@@ -55,10 +55,7 @@ impl FileSystemCache {
|
||||
// This path points to a file.
|
||||
Err(io::Error::new(
|
||||
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 {
|
||||
|
||||
@@ -59,19 +59,13 @@ pub enum CType {
|
||||
impl CType {
|
||||
/// Convenience function to get a mutable void pointer type.
|
||||
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.
|
||||
#[allow(dead_code)]
|
||||
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`.
|
||||
@@ -117,15 +111,10 @@ impl CType {
|
||||
Self::ISize => {
|
||||
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
|
||||
let ret: CType = return_value
|
||||
.as_ref()
|
||||
.map(|i: &Box<CType>| (&**i).clone())
|
||||
.unwrap_or_default();
|
||||
let ret: CType =
|
||||
return_value.as_ref().map(|i: &Box<CType>| (&**i).clone()).unwrap_or_default();
|
||||
ret.generate_c(w);
|
||||
w.push(' ');
|
||||
w.push_str("(*)");
|
||||
@@ -171,14 +160,9 @@ impl CType {
|
||||
w.push(' ');
|
||||
w.push_str(name);
|
||||
}
|
||||
Self::Function {
|
||||
arguments,
|
||||
return_value,
|
||||
} => {
|
||||
let ret: CType = return_value
|
||||
.as_ref()
|
||||
.map(|i: &Box<CType>| (&**i).clone())
|
||||
.unwrap_or_default();
|
||||
Self::Function { arguments, return_value } => {
|
||||
let ret: CType =
|
||||
return_value.as_ref().map(|i: &Box<CType>| (&**i).clone()).unwrap_or_default();
|
||||
ret.generate_c(w);
|
||||
w.push(' ');
|
||||
w.push_str(&name);
|
||||
@@ -264,13 +248,7 @@ impl CStatement {
|
||||
/// Generate C source code for the given CStatement.
|
||||
fn generate_c(&self, w: &mut String) {
|
||||
match &self {
|
||||
Self::Declaration {
|
||||
name,
|
||||
is_extern,
|
||||
is_const,
|
||||
ctype,
|
||||
definition,
|
||||
} => {
|
||||
Self::Declaration { name, is_extern, is_const, ctype, definition } => {
|
||||
if *is_const {
|
||||
w.push_str("const ");
|
||||
}
|
||||
@@ -301,20 +279,14 @@ impl CStatement {
|
||||
Self::LiteralConstant { value } => {
|
||||
w.push_str(&value);
|
||||
}
|
||||
Self::Cast {
|
||||
target_type,
|
||||
expression,
|
||||
} => {
|
||||
Self::Cast { target_type, expression } => {
|
||||
w.push('(');
|
||||
target_type.generate_c(w);
|
||||
w.push(')');
|
||||
w.push(' ');
|
||||
expression.generate_c(w);
|
||||
}
|
||||
Self::TypeDef {
|
||||
source_type,
|
||||
new_name,
|
||||
} => {
|
||||
Self::TypeDef { source_type, new_name } => {
|
||||
w.push_str("typedef ");
|
||||
// leaky abstraction / hack, doesn't fully solve the problem
|
||||
if let CType::Function { .. } = source_type {
|
||||
@@ -371,26 +343,17 @@ mod test {
|
||||
assert_c_type!(CType::ISize, "size_t");
|
||||
assert_c_type!(CType::TypeDef("my_type".to_string()), "my_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)"
|
||||
);
|
||||
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 (*)()"
|
||||
);
|
||||
assert_c_type!(
|
||||
CType::PointerTo {
|
||||
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**"
|
||||
);
|
||||
@@ -421,34 +384,21 @@ mod test {
|
||||
assert_c_type!(CType::I32, "data", "int data");
|
||||
assert_c_type!(CType::I64, "data", "long long 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!(
|
||||
CType::TypeDef("my_type".to_string()),
|
||||
"data",
|
||||
"my_type data"
|
||||
);
|
||||
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 },
|
||||
"my_func",
|
||||
"void my_func(unsigned char, size_t)"
|
||||
);
|
||||
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",
|
||||
"size_t my_func()"
|
||||
);
|
||||
assert_c_type!(
|
||||
CType::PointerTo {
|
||||
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",
|
||||
"const unsigned int** data"
|
||||
@@ -468,9 +418,7 @@ mod test {
|
||||
}
|
||||
|
||||
assert_c_expr!(
|
||||
CStatement::LiteralConstant {
|
||||
value: "\"Hello, world!\"".to_string(),
|
||||
},
|
||||
CStatement::LiteralConstant { value: "\"Hello, world!\"".to_string() },
|
||||
"\"Hello, world!\""
|
||||
);
|
||||
assert_c_expr!(
|
||||
@@ -486,15 +434,9 @@ mod test {
|
||||
assert_c_expr!(
|
||||
CStatement::LiteralArray {
|
||||
items: vec![
|
||||
CStatement::LiteralConstant {
|
||||
value: "1".to_string()
|
||||
},
|
||||
CStatement::LiteralConstant {
|
||||
value: "2".to_string()
|
||||
},
|
||||
CStatement::LiteralConstant {
|
||||
value: "3".to_string()
|
||||
},
|
||||
CStatement::LiteralConstant { value: "1".to_string() },
|
||||
CStatement::LiteralConstant { value: "2".to_string() },
|
||||
CStatement::LiteralConstant { value: "3".to_string() },
|
||||
]
|
||||
},
|
||||
"{\n\t1,\n\t2,\n\t3,\n}"
|
||||
@@ -505,20 +447,12 @@ mod test {
|
||||
name: "my_array".to_string(),
|
||||
is_extern: false,
|
||||
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 {
|
||||
items: vec![
|
||||
CStatement::LiteralConstant {
|
||||
value: "1".to_string()
|
||||
},
|
||||
CStatement::LiteralConstant {
|
||||
value: "2".to_string()
|
||||
},
|
||||
CStatement::LiteralConstant {
|
||||
value: "3".to_string()
|
||||
},
|
||||
CStatement::LiteralConstant { value: "1".to_string() },
|
||||
CStatement::LiteralConstant { value: "2".to_string() },
|
||||
CStatement::LiteralConstant { value: "3".to_string() },
|
||||
]
|
||||
}))
|
||||
},
|
||||
@@ -529,9 +463,7 @@ mod test {
|
||||
name: "my_array".to_string(),
|
||||
is_extern: true,
|
||||
is_const: true,
|
||||
ctype: CType::Array {
|
||||
inner: Box::new(CType::I32),
|
||||
},
|
||||
ctype: CType::Array { inner: Box::new(CType::I32) },
|
||||
definition: None,
|
||||
},
|
||||
"const extern int my_array[];\n"
|
||||
|
||||
@@ -94,9 +94,7 @@ pub fn generate_header_file(
|
||||
name: "WASMER_METADATA".to_string(),
|
||||
is_extern: true,
|
||||
is_const: true,
|
||||
ctype: CType::Array {
|
||||
inner: Box::new(CType::U8),
|
||||
},
|
||||
ctype: CType::Array { inner: Box::new(CType::U8) },
|
||||
definition: None,
|
||||
});
|
||||
let function_declarations = module_info
|
||||
@@ -113,10 +111,7 @@ pub fn generate_header_file(
|
||||
name: function_name,
|
||||
is_extern: 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,
|
||||
}
|
||||
});
|
||||
@@ -144,9 +139,7 @@ pub fn generate_header_file(
|
||||
|
||||
CStatement::Cast {
|
||||
target_type: CType::void_ptr(),
|
||||
expression: Box::new(CStatement::LiteralConstant {
|
||||
value: function_name,
|
||||
}),
|
||||
expression: Box::new(CStatement::LiteralConstant { value: function_name }),
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -155,9 +148,7 @@ pub fn generate_header_file(
|
||||
name: "function_pointers".to_string(),
|
||||
is_extern: false,
|
||||
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 {
|
||||
items: function_pointer_array_statements,
|
||||
})),
|
||||
@@ -165,24 +156,21 @@ pub fn generate_header_file(
|
||||
}
|
||||
|
||||
let func_trampoline_declarations =
|
||||
module_info
|
||||
.signatures
|
||||
.iter()
|
||||
.map(|(sig_index, _func_type)| {
|
||||
let function_name =
|
||||
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
|
||||
module_info.signatures.iter().map(|(sig_index, _func_type)| {
|
||||
let function_name =
|
||||
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
|
||||
|
||||
CStatement::Declaration {
|
||||
name: function_name,
|
||||
is_extern: false,
|
||||
is_const: false,
|
||||
ctype: CType::Function {
|
||||
arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
|
||||
return_value: None,
|
||||
},
|
||||
definition: None,
|
||||
}
|
||||
});
|
||||
CStatement::Declaration {
|
||||
name: function_name,
|
||||
is_extern: false,
|
||||
is_const: false,
|
||||
ctype: CType::Function {
|
||||
arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
|
||||
return_value: None,
|
||||
},
|
||||
definition: None,
|
||||
}
|
||||
});
|
||||
c_statements.push(CStatement::LiteralConstant {
|
||||
value: r#"
|
||||
// Trampolines (functions by which we can call into Wasm) ordered by signature.
|
||||
@@ -201,9 +189,7 @@ pub fn generate_header_file(
|
||||
.map(|(sig_index, _vm_shared_index)| {
|
||||
let function_name =
|
||||
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
|
||||
CStatement::LiteralConstant {
|
||||
value: function_name,
|
||||
}
|
||||
CStatement::LiteralConstant { value: function_name }
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -211,20 +197,15 @@ pub fn generate_header_file(
|
||||
name: "function_trampolines".to_string(),
|
||||
is_extern: false,
|
||||
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 {
|
||||
items: function_trampoline_statements,
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
let dyn_func_declarations = module_info
|
||||
.functions
|
||||
.keys()
|
||||
.take(module_info.num_imported_functions)
|
||||
.map(|func_index| {
|
||||
let dyn_func_declarations =
|
||||
module_info.functions.keys().take(module_info.num_imported_functions).map(|func_index| {
|
||||
let function_name =
|
||||
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
|
||||
// TODO: figure out the signature here
|
||||
@@ -266,9 +247,7 @@ pub fn generate_header_file(
|
||||
.map(|func_index| {
|
||||
let function_name =
|
||||
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
|
||||
CStatement::LiteralConstant {
|
||||
value: function_name,
|
||||
}
|
||||
CStatement::LiteralConstant { value: function_name }
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
c_statements.push(CStatement::Declaration {
|
||||
@@ -284,9 +263,7 @@ 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 {
|
||||
value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(),
|
||||
|
||||
@@ -19,11 +19,7 @@ use clap::{Clap, ErrorKind};
|
||||
)]
|
||||
#[cfg_attr(
|
||||
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
|
||||
enum WasmerCLIOptions {
|
||||
|
||||
@@ -34,8 +34,7 @@ pub struct Compile {
|
||||
impl Compile {
|
||||
/// Runs logic for the `compile` subcommand
|
||||
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(
|
||||
@@ -63,11 +62,8 @@ impl Compile {
|
||||
.target_triple
|
||||
.as_ref()
|
||||
.map(|target_triple| {
|
||||
let mut features = self
|
||||
.cpu_features
|
||||
.clone()
|
||||
.into_iter()
|
||||
.fold(CpuFeature::set(), |a, b| a | b);
|
||||
let mut features =
|
||||
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b);
|
||||
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
|
||||
// usage
|
||||
features |= CpuFeature::SSE2;
|
||||
@@ -98,10 +94,7 @@ impl Compile {
|
||||
|
||||
let module = Module::from_file(&store, &self.path)?;
|
||||
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")]
|
||||
if engine_type == EngineType::ObjectFile {
|
||||
@@ -135,10 +128,7 @@ impl Compile {
|
||||
|
||||
use std::io::Write;
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -40,21 +40,13 @@ pub struct Config {
|
||||
impl Config {
|
||||
/// Runs logic for the `config` subcommand
|
||||
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<()> {
|
||||
let key = "WASMER_DIR";
|
||||
let wasmer_dir = env::var(key)
|
||||
.or_else(|e| {
|
||||
option_env!("WASMER_INSTALL_PREFIX")
|
||||
.map(str::to_string)
|
||||
.ok_or(e)
|
||||
})
|
||||
.context(format!(
|
||||
"failed to retrieve the {} environment variables",
|
||||
key
|
||||
))?;
|
||||
.or_else(|e| 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);
|
||||
|
||||
|
||||
@@ -45,11 +45,8 @@ impl CreateExe {
|
||||
.target_triple
|
||||
.as_ref()
|
||||
.map(|target_triple| {
|
||||
let mut features = self
|
||||
.cpu_features
|
||||
.clone()
|
||||
.into_iter()
|
||||
.fold(CpuFeature::set(), |a, b| a | b);
|
||||
let mut features =
|
||||
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b);
|
||||
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
|
||||
// usage
|
||||
features |= CpuFeature::SSE2;
|
||||
@@ -57,9 +54,8 @@ impl CreateExe {
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let engine_type = EngineType::ObjectFile;
|
||||
let (store, compiler_type) = self
|
||||
.compiler
|
||||
.get_store_for_target_and_engine(target.clone(), engine_type)?;
|
||||
let (store, compiler_type) =
|
||||
self.compiler.get_store_for_target_and_engine(target.clone(), engine_type)?;
|
||||
|
||||
println!("Engine: {}", engine_type.to_string());
|
||||
println!("Compiler: {}", compiler_type.to_string());
|
||||
@@ -97,10 +93,7 @@ impl CreateExe {
|
||||
generate_header(header_file_src.as_bytes())?;
|
||||
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(())
|
||||
}
|
||||
@@ -156,11 +149,7 @@ fn generate_header(header_file_src: &[u8]) -> anyhow::Result<()> {
|
||||
fn get_wasmer_dir() -> anyhow::Result<PathBuf> {
|
||||
Ok(PathBuf::from(
|
||||
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`")?,
|
||||
))
|
||||
}
|
||||
@@ -268,17 +257,8 @@ impl LinkCode {
|
||||
let mut command = Command::new(&self.linker_path);
|
||||
let command = command
|
||||
.arg(&self.optimization_flag)
|
||||
.args(
|
||||
self.object_paths
|
||||
.iter()
|
||||
.map(|path| path.canonicalize().unwrap()),
|
||||
)
|
||||
.arg(
|
||||
&self
|
||||
.libwasmer_path
|
||||
.canonicalize()
|
||||
.context("Failed to find libwasmer")?,
|
||||
);
|
||||
.args(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 {
|
||||
command.arg("-target").arg(format!("{}", target))
|
||||
} else {
|
||||
@@ -287,18 +267,12 @@ impl LinkCode {
|
||||
// Add libraries required per platform.
|
||||
// We need userenv, sockets (Ws2_32), advapi32 for some system calls and bcrypt for random numbers.
|
||||
#[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.
|
||||
#[cfg(not(windows))]
|
||||
let command = command.arg("-ldl").arg("-lm").arg("-pthread");
|
||||
let link_aganist_extra_libs = self
|
||||
.additional_libraries
|
||||
.iter()
|
||||
.map(|lib| format!("-l{}", lib));
|
||||
let link_aganist_extra_libs =
|
||||
self.additional_libraries.iter().map(|lib| format!("-l{}", lib));
|
||||
let command = command.args(link_aganist_extra_libs);
|
||||
let output = command.arg("-o").arg(&self.output_path).output()?;
|
||||
|
||||
|
||||
@@ -19,21 +19,13 @@ pub struct Inspect {
|
||||
impl Inspect {
|
||||
/// Runs logic for the `validate` subcommand
|
||||
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<()> {
|
||||
let (store, _engine_type, _compiler_type) = self.store.get_store()?;
|
||||
let module_contents = std::fs::read(&self.path)?;
|
||||
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!("Imports:");
|
||||
println!(" Functions:");
|
||||
|
||||
@@ -80,11 +80,7 @@ impl Run {
|
||||
format!(
|
||||
"failed to run `{}`{}",
|
||||
self.path.display(),
|
||||
if CompilerType::enabled().is_empty() {
|
||||
" (no compilers enabled)"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
if CompilerType::enabled().is_empty() { " (no compilers enabled)" } else { "" }
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -98,11 +94,7 @@ impl Run {
|
||||
let result = self.invoke_function(&instance, &invoke, &self.args)?;
|
||||
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(());
|
||||
}
|
||||
@@ -157,11 +149,7 @@ impl Run {
|
||||
let program_name = self
|
||||
.command_name
|
||||
.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();
|
||||
return self
|
||||
.wasi
|
||||
@@ -359,31 +347,19 @@ impl Run {
|
||||
.iter()
|
||||
.zip(func_ty.params().iter())
|
||||
.map(|(arg, param_type)| match param_type {
|
||||
ValType::I32 => {
|
||||
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::I32 => 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)),
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
Ok(func.call(&invoke_args)?)
|
||||
|
||||
@@ -23,10 +23,8 @@ impl SelfUpdate {
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
let mut process = Command::new("sh")
|
||||
.stdin(cmd.stdout.unwrap())
|
||||
.stdout(Stdio::inherit())
|
||||
.spawn()?;
|
||||
let mut process =
|
||||
Command::new("sh").stdin(cmd.stdout.unwrap()).stdout(Stdio::inherit()).spawn()?;
|
||||
|
||||
process.wait().unwrap();
|
||||
Ok(())
|
||||
|
||||
@@ -18,8 +18,7 @@ pub struct Validate {
|
||||
impl Validate {
|
||||
/// Runs logic for the `validate` subcommand
|
||||
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<()> {
|
||||
let (store, _engine_type, _compiler_type) = self.store.get_store()?;
|
||||
|
||||
@@ -23,8 +23,7 @@ pub struct Wast {
|
||||
impl Wast {
|
||||
/// Runs logic for the `validate` subcommand
|
||||
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<()> {
|
||||
let (store, _engine_name, _compiler_name) = self.store.get_store()?;
|
||||
|
||||
@@ -5,10 +5,8 @@ use std::time;
|
||||
|
||||
/// Subroutine to instantiate the loggers
|
||||
pub fn set_up_logging() -> Result<(), String> {
|
||||
let colors_line = ColoredLevelConfig::new()
|
||||
.error(Color::Red)
|
||||
.warn(Color::Yellow)
|
||||
.trace(Color::BrightBlack);
|
||||
let colors_line =
|
||||
ColoredLevelConfig::new().error(Color::Red).warn(Color::Yellow).trace(Color::BrightBlack);
|
||||
let should_color = wasmer_should_print_color();
|
||||
|
||||
let colors_level = colors_line.info(Color::Green);
|
||||
|
||||
@@ -73,10 +73,7 @@ impl CompilerOptions {
|
||||
} else if self.singlepass {
|
||||
Ok(CompilerType::Singlepass)
|
||||
} 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)
|
||||
} else {
|
||||
// Auto mode, we choose the best compiler for that platform
|
||||
@@ -158,10 +155,7 @@ impl CompilerOptions {
|
||||
.engine(),
|
||||
),
|
||||
#[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)
|
||||
@@ -293,10 +287,9 @@ impl CompilerOptions {
|
||||
Box::new(config)
|
||||
}
|
||||
#[cfg(not(all(feature = "singlepass", feature = "cranelift", feature = "llvm",)))]
|
||||
compiler => bail!(
|
||||
"The `{}` compiler is not included in this binary.",
|
||||
compiler.to_string()
|
||||
),
|
||||
compiler => {
|
||||
bail!("The `{}` compiler is not included in this binary.", compiler.to_string())
|
||||
}
|
||||
};
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
@@ -401,9 +394,7 @@ impl StoreOptions {
|
||||
compiler_config: Box<dyn CompilerConfig>,
|
||||
) -> Result<(Box<dyn Engine + Send + Sync>, EngineType)> {
|
||||
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))
|
||||
}
|
||||
@@ -448,10 +439,7 @@ impl StoreOptions {
|
||||
Arc::new(wasmer_engine_object_file::ObjectFile::headless().engine())
|
||||
}
|
||||
#[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))
|
||||
}
|
||||
|
||||
@@ -84,9 +84,6 @@ mod tests {
|
||||
);
|
||||
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=C=D").unwrap(),
|
||||
("A".into(), "B=C=D".into())
|
||||
);
|
||||
assert_eq!(parse_envvar("A=B=C=D").unwrap(), ("A".into(), "B=C=D".into()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,11 +47,5 @@ pub fn get_function_address_map<'data>(
|
||||
let start_srcloc = SourceLoc::new(data.module_offset 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 }
|
||||
}
|
||||
|
||||
@@ -178,16 +178,10 @@ impl Compiler for CraneliftCompiler {
|
||||
let func_jt_offsets = transform_jump_table(context.func.jt_offsets);
|
||||
|
||||
Ok(CompiledFunction {
|
||||
body: FunctionBody {
|
||||
body: code_buf,
|
||||
unwind_info,
|
||||
},
|
||||
body: FunctionBody { body: code_buf, unwind_info },
|
||||
jt_offsets: func_jt_offsets,
|
||||
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>>()?
|
||||
@@ -199,11 +193,7 @@ impl Compiler for CraneliftCompiler {
|
||||
let mut custom_sections = PrimaryMap::new();
|
||||
let dwarf = if let Some((dwarf_frametable, _cie_id)) = dwarf_frametable {
|
||||
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();
|
||||
custom_sections.push(eh_frame_section);
|
||||
|
||||
@@ -113,14 +113,10 @@ impl Cranelift {
|
||||
builder.enable("has_avx2").expect("should be valid flag");
|
||||
}
|
||||
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) {
|
||||
builder
|
||||
.enable("has_avx512vl")
|
||||
.expect("should be valid flag");
|
||||
builder.enable("has_avx512vl").expect("should be valid flag");
|
||||
}
|
||||
if cpu_features.contains(CpuFeature::LZCNT) {
|
||||
builder.enable("has_lzcnt").expect("should be valid flag");
|
||||
@@ -135,26 +131,16 @@ impl Cranelift {
|
||||
|
||||
// There are two possible traps for division, and this way
|
||||
// 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 {
|
||||
flags.enable("is_pic").expect("should be a valid flag");
|
||||
}
|
||||
|
||||
// Invert cranelift's default-on verification to instead default off.
|
||||
let enable_verifier = if self.enable_verifier {
|
||||
"true"
|
||||
} else {
|
||||
"false"
|
||||
};
|
||||
flags
|
||||
.set("enable_verifier", enable_verifier)
|
||||
.expect("should be valid flag");
|
||||
flags
|
||||
.set("enable_safepoints", "true")
|
||||
.expect("should be valid flag");
|
||||
let enable_verifier = if self.enable_verifier { "true" } 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 {
|
||||
"none"
|
||||
@@ -166,20 +152,13 @@ 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" };
|
||||
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 = if self.enable_nan_canonicalization {
|
||||
"true"
|
||||
} else {
|
||||
"false"
|
||||
};
|
||||
let enable_nan_canonicalization =
|
||||
if self.enable_nan_canonicalization { "true" } else { "false" };
|
||||
flags
|
||||
.set("enable_nan_canonicalization", enable_nan_canonicalization)
|
||||
.expect("should be valid flag");
|
||||
|
||||
@@ -20,10 +20,7 @@ impl WriterRelocate {
|
||||
// We autodetect it, based on the host
|
||||
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 {
|
||||
@@ -72,12 +69,7 @@ impl Writer for WriterRelocate {
|
||||
_ => unimplemented!("dwarf relocation size not yet supported: {}", size),
|
||||
};
|
||||
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)
|
||||
} else {
|
||||
unreachable!("Symbol {} in DWARF not recognized", symbol);
|
||||
|
||||
@@ -223,10 +223,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
&mut self,
|
||||
func: &mut Function,
|
||||
) -> (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 {
|
||||
@@ -245,10 +242,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
&mut self,
|
||||
func: &mut Function,
|
||||
) -> (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 {
|
||||
@@ -573,11 +567,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
||||
let sig = self.get_table_init_sig(func);
|
||||
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 {
|
||||
@@ -630,17 +620,9 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
||||
let sig = self.get_memory_copy_sig(func);
|
||||
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 {
|
||||
(
|
||||
sig,
|
||||
memory_index.index(),
|
||||
VMBuiltinFunctionIndex::get_imported_memory_copy_index(),
|
||||
)
|
||||
(sig, memory_index.index(), VMBuiltinFunctionIndex::get_imported_memory_copy_index())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,17 +655,9 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
||||
let sig = self.get_memory_fill_sig(func);
|
||||
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 {
|
||||
(
|
||||
sig,
|
||||
memory_index.index(),
|
||||
VMBuiltinFunctionIndex::get_imported_memory_fill_index(),
|
||||
)
|
||||
(sig, memory_index.index(), VMBuiltinFunctionIndex::get_imported_memory_fill_index())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,8 +759,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
let base_offset =
|
||||
i32::try_from(self.offsets.vmctx_vmtable_definition_base(def_index)).unwrap();
|
||||
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();
|
||||
(vmctx, base_offset, current_elements_offset)
|
||||
@@ -842,11 +815,8 @@ 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 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 call_inst = pos.ins().call_indirect(
|
||||
func_sig,
|
||||
func_addr,
|
||||
&[vmctx, init_value, delta, table_index],
|
||||
);
|
||||
let call_inst =
|
||||
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, init_value, delta, table_index]);
|
||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||
}
|
||||
|
||||
@@ -863,9 +833,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
self.get_table_get_func(&mut pos.func, table_index);
|
||||
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 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())
|
||||
}
|
||||
|
||||
@@ -883,8 +851,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
self.get_table_set_func(&mut pos.func, table_index);
|
||||
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);
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -901,11 +868,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
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);
|
||||
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(())
|
||||
}
|
||||
@@ -962,8 +925,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
ty if ty.is_ref() => pos.ins().is_null(value),
|
||||
// `funcref`
|
||||
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!(),
|
||||
};
|
||||
@@ -989,9 +951,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
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 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())
|
||||
}
|
||||
@@ -1021,11 +981,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
if let Some(def_index) = self.module.local_memory_index(index) {
|
||||
let base_offset =
|
||||
i32::try_from(self.offsets.vmctx_vmmemory_definition_base(def_index)).unwrap();
|
||||
let current_length_offset = i32::try_from(
|
||||
self.offsets
|
||||
.vmctx_vmmemory_definition_current_length(def_index),
|
||||
)
|
||||
.unwrap();
|
||||
let current_length_offset =
|
||||
i32::try_from(self.offsets.vmctx_vmmemory_definition_current_length(def_index))
|
||||
.unwrap();
|
||||
(vmctx, base_offset, current_length_offset)
|
||||
} else {
|
||||
let from_offset = self.offsets.vmctx_vmmemory_import_definition(index);
|
||||
@@ -1054,20 +1012,13 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
});
|
||||
(
|
||||
Uimm64::new(offset_guard_size),
|
||||
ir::HeapStyle::Dynamic {
|
||||
bound_gv: heap_bound,
|
||||
},
|
||||
ir::HeapStyle::Dynamic { bound_gv: heap_bound },
|
||||
false,
|
||||
)
|
||||
}
|
||||
MemoryStyle::Static {
|
||||
bound,
|
||||
offset_guard_size,
|
||||
} => (
|
||||
MemoryStyle::Static { bound, 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,
|
||||
),
|
||||
};
|
||||
@@ -1167,8 +1118,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
);
|
||||
|
||||
// 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(
|
||||
pointer_type,
|
||||
@@ -1283,9 +1233,7 @@ 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 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 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())
|
||||
}
|
||||
|
||||
@@ -1298,9 +1246,7 @@ 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 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 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())
|
||||
}
|
||||
|
||||
@@ -1321,8 +1267,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
|
||||
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(())
|
||||
}
|
||||
@@ -1343,11 +1288,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
|
||||
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(())
|
||||
}
|
||||
@@ -1382,8 +1323,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
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 (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(())
|
||||
}
|
||||
|
||||
@@ -1396,9 +1336,7 @@ 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 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 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())
|
||||
}
|
||||
|
||||
@@ -1424,14 +1362,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
pos.ins().call_indirect(
|
||||
func_sig,
|
||||
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(())
|
||||
@@ -1471,8 +1402,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
|
||||
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(())
|
||||
}
|
||||
@@ -1486,9 +1416,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
_expected: ir::Value,
|
||||
_timeout: 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(
|
||||
@@ -1499,9 +1427,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
||||
_addr: ir::Value,
|
||||
_count: 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> {
|
||||
|
||||
@@ -75,14 +75,9 @@ impl<'a> binemit::RelocSink for RelocSink<'a> {
|
||||
impl<'a> RelocSink<'a> {
|
||||
/// Return a new `RelocSink` instance.
|
||||
pub fn new(module: &'a ModuleInfo, func_index: FunctionIndex) -> Self {
|
||||
let local_func_index = module
|
||||
.local_func_index(func_index)
|
||||
.expect("The provided function should be local");
|
||||
Self {
|
||||
module,
|
||||
local_func_index,
|
||||
func_relocs: Vec::new(),
|
||||
}
|
||||
let local_func_index =
|
||||
module.local_func_index(func_index).expect("The provided function should be local");
|
||||
Self { module, local_func_index, func_relocs: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,7 @@ pub fn make_trampoline_dynamic_function(
|
||||
let signature = signature_to_cranelift_ir(func_type, frontend_config);
|
||||
let mut stub_sig = ir::Signature::new(frontend_config.default_call_conv);
|
||||
// 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.
|
||||
stub_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||
@@ -48,10 +45,9 @@ pub fn make_trampoline_dynamic_function(
|
||||
let mut context = Context::new();
|
||||
context.func = Function::with_name_signature(ExternalName::user(0, 0), signature.clone());
|
||||
|
||||
let ss = context.func.create_stack_slot(StackSlotData::new(
|
||||
StackSlotKind::ExplicitSlot,
|
||||
values_vec_len,
|
||||
));
|
||||
let ss = context
|
||||
.func
|
||||
.create_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, values_vec_len));
|
||||
|
||||
{
|
||||
let mut builder = FunctionBuilder::new(&mut context.func, fn_builder_ctx);
|
||||
@@ -66,12 +62,7 @@ pub fn make_trampoline_dynamic_function(
|
||||
// We only get the non-vmctx arguments
|
||||
for i in 1..signature.params.len() {
|
||||
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);
|
||||
@@ -88,9 +79,7 @@ pub fn make_trampoline_dynamic_function(
|
||||
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 mut results = Vec::new();
|
||||
@@ -112,19 +101,10 @@ pub fn make_trampoline_dynamic_function(
|
||||
let mut trap_sink = binemit::NullTrapSink {};
|
||||
let mut stackmap_sink = binemit::NullStackMapSink {};
|
||||
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)))?;
|
||||
|
||||
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 })
|
||||
}
|
||||
|
||||
@@ -34,10 +34,7 @@ pub fn make_trampoline_function_call(
|
||||
let mut wrapper_sig = ir::Signature::new(frontend_config.default_call_conv);
|
||||
|
||||
// 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.
|
||||
wrapper_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||
@@ -87,18 +84,14 @@ pub fn make_trampoline_function_call(
|
||||
|
||||
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();
|
||||
|
||||
// Store the return values into `values_vec`.
|
||||
let mflags = ir::MemFlags::trusted();
|
||||
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_(&[]);
|
||||
@@ -111,13 +104,7 @@ pub fn make_trampoline_function_call(
|
||||
let mut stackmap_sink = binemit::NullStackMapSink {};
|
||||
|
||||
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)))?;
|
||||
|
||||
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
|
||||
|
||||
@@ -80,13 +80,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let val = builder.use_var(Variable::with_u32(*local_index));
|
||||
let local_type = environ.get_local_type(*local_index).unwrap();
|
||||
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);
|
||||
builder.set_val_label(val, label);
|
||||
|
||||
@@ -151,13 +145,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
environ.translate_externref_inc(builder.cursor(), value)?;
|
||||
}
|
||||
|
||||
(
|
||||
value,
|
||||
ValueExtraInfo {
|
||||
ref_counted,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
(value, ValueExtraInfo { ref_counted, ..Default::default() })
|
||||
}
|
||||
GlobalVariable::Custom => (
|
||||
environ.translate_custom_global_get(builder.cursor(), global_index)?,
|
||||
@@ -216,10 +204,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let not_selected_ref = builder.ins().select(cond, arg2, arg1);
|
||||
state.push1_extra((
|
||||
selected_ref,
|
||||
ValueExtraInfo {
|
||||
ref_counted,
|
||||
..Default::default()
|
||||
},
|
||||
ValueExtraInfo { ref_counted, ..Default::default() },
|
||||
));
|
||||
environ.translate_externref_dec(builder.cursor(), not_selected_ref)?;
|
||||
} else {
|
||||
@@ -262,9 +247,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
// Pop the initial `Block` actuals and replace them with the `Block`'s
|
||||
// params since control flow joins at the top of the loop.
|
||||
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);
|
||||
environ.translate_loop_header(builder.cursor())?;
|
||||
@@ -402,9 +385,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
}
|
||||
|
||||
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 *********************************
|
||||
* The branch instructions all have as arguments a target nesting level, which
|
||||
@@ -586,10 +567,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let mut results_metadata = Vec::with_capacity(func_type.results().len());
|
||||
for result in func_type.results() {
|
||||
results_metadata.push(if *result == WasmerType::ExternRef {
|
||||
ValueExtraInfo {
|
||||
ref_counted: true,
|
||||
..Default::default()
|
||||
}
|
||||
ValueExtraInfo { ref_counted: true, ..Default::default() }
|
||||
} else {
|
||||
Default::default()
|
||||
});
|
||||
@@ -634,10 +612,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let mut results_metadata = Vec::with_capacity(func_type.results().len());
|
||||
for result in func_type.results() {
|
||||
results_metadata.push(if *result == WasmerType::ExternRef {
|
||||
ValueExtraInfo {
|
||||
ref_counted: true,
|
||||
..Default::default()
|
||||
}
|
||||
ValueExtraInfo { ref_counted: true, ..Default::default() }
|
||||
} else {
|
||||
Default::default()
|
||||
});
|
||||
@@ -1386,10 +1361,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let (index, _) = state.pop1();
|
||||
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 src_table = state.get_or_create_table(builder.func, *src_table_index, environ)?;
|
||||
let (len, _) = state.pop1();
|
||||
@@ -1413,10 +1385,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let (dest, _) = state.pop1();
|
||||
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 (len, _) = state.pop1();
|
||||
let (src, _) = state.pop1();
|
||||
@@ -1443,9 +1412,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
state.push1(value)
|
||||
}
|
||||
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);
|
||||
state.push1(splatted)
|
||||
}
|
||||
@@ -1686,12 +1653,9 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
Operator::I8x16LeS | Operator::I16x8LeS | Operator::I32x4LeS => {
|
||||
translate_vector_icmp(IntCC::SignedLessThanOrEqual, type_of(op), builder, state)
|
||||
}
|
||||
Operator::I8x16GeU | Operator::I16x8GeU | Operator::I32x4GeU => translate_vector_icmp(
|
||||
IntCC::UnsignedGreaterThanOrEqual,
|
||||
type_of(op),
|
||||
builder,
|
||||
state,
|
||||
),
|
||||
Operator::I8x16GeU | Operator::I16x8GeU | Operator::I32x4GeU => {
|
||||
translate_vector_icmp(IntCC::UnsignedGreaterThanOrEqual, type_of(op), builder, state)
|
||||
}
|
||||
Operator::I8x16LeU | Operator::I16x8LeU | Operator::I32x4LeU => {
|
||||
translate_vector_icmp(IntCC::UnsignedLessThanOrEqual, type_of(op), builder, state)
|
||||
}
|
||||
@@ -1921,9 +1885,7 @@ fn translate_unreachable_operator<FE: FuncEnvironment + ?Sized>(
|
||||
// so we don't have any branches anywhere.
|
||||
state.push_if(
|
||||
ir::Block::reserved_value(),
|
||||
ElseData::NoElse {
|
||||
branch_inst: ir::Inst::reserved_value(),
|
||||
},
|
||||
ElseData::NoElse { branch_inst: ir::Inst::reserved_value() },
|
||||
0,
|
||||
0,
|
||||
ty,
|
||||
@@ -2128,14 +2090,8 @@ fn prepare_load<FE: FuncEnvironment + ?Sized>(
|
||||
let (addr32, _) = state.pop1();
|
||||
|
||||
let heap = state.get_heap(builder.func, memarg.memory, environ)?;
|
||||
let (base, offset) = get_heap_addr(
|
||||
heap,
|
||||
addr32,
|
||||
memarg.offset,
|
||||
loaded_bytes,
|
||||
environ.pointer_type(),
|
||||
builder,
|
||||
);
|
||||
let (base, offset) =
|
||||
get_heap_addr(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
|
||||
// alignment immediate says it's aligned, because WebAssembly's immediate
|
||||
@@ -2154,13 +2110,8 @@ fn translate_load<FE: FuncEnvironment + ?Sized>(
|
||||
state: &mut FuncTranslationState,
|
||||
environ: &mut FE,
|
||||
) -> WasmResult<()> {
|
||||
let (flags, base, offset) = prepare_load(
|
||||
memarg,
|
||||
mem_op_size(opcode, result_ty),
|
||||
builder,
|
||||
state,
|
||||
environ,
|
||||
)?;
|
||||
let (flags, base, offset) =
|
||||
prepare_load(memarg, mem_op_size(opcode, result_ty), builder, state, environ)?;
|
||||
let (load, dfg) = builder.ins().Load(opcode, result_ty, flags, offset, base);
|
||||
state.push1(dfg.first_result(load));
|
||||
Ok(())
|
||||
@@ -2188,9 +2139,7 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
|
||||
);
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -2222,20 +2171,13 @@ fn finalise_atomic_mem_addr<FE: FuncEnvironment + ?Sized>(
|
||||
) -> WasmResult<Value> {
|
||||
// Check the alignment of `linear_mem_addr`.
|
||||
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 {
|
||||
assert!(access_ty_bytes == 2 || access_ty_bytes == 4 || access_ty_bytes == 8);
|
||||
let final_lma_misalignment = builder
|
||||
.ins()
|
||||
.band_imm(final_lma, i64::from(access_ty_bytes - 1));
|
||||
let f = builder
|
||||
.ins()
|
||||
.ifcmp_imm(final_lma_misalignment, i64::from(0));
|
||||
builder
|
||||
.ins()
|
||||
.trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned);
|
||||
let final_lma_misalignment =
|
||||
builder.ins().band_imm(final_lma, i64::from(access_ty_bytes - 1));
|
||||
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.
|
||||
@@ -2269,12 +2211,7 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
|
||||
// to type `widened_ty`.
|
||||
match access_ty {
|
||||
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 {
|
||||
I32 | I64 => true,
|
||||
@@ -2292,9 +2229,7 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
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 {
|
||||
res = builder.ins().uextend(widened_ty, res);
|
||||
}
|
||||
@@ -2318,12 +2253,7 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
|
||||
// to type `widened_ty`.
|
||||
match access_ty {
|
||||
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 {
|
||||
I32 | I64 => true,
|
||||
@@ -2345,9 +2275,7 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
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 {
|
||||
res = builder.ins().uextend(widened_ty, res);
|
||||
}
|
||||
@@ -2369,12 +2297,7 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
|
||||
// to `widened_ty`.
|
||||
match access_ty {
|
||||
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 {
|
||||
I32 | I64 => true,
|
||||
@@ -2387,9 +2310,7 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
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 {
|
||||
res = builder.ins().uextend(widened_ty, res);
|
||||
}
|
||||
@@ -2412,10 +2333,7 @@ fn translate_atomic_store<FE: FuncEnvironment + ?Sized>(
|
||||
match access_ty {
|
||||
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 {
|
||||
@@ -2433,9 +2351,7 @@ fn translate_atomic_store<FE: FuncEnvironment + ?Sized>(
|
||||
|
||||
// See the comments in `prepare_load` about the flags.
|
||||
let flags = MemFlags::new();
|
||||
builder
|
||||
.ins()
|
||||
.atomic_store(flags, data, final_effective_address);
|
||||
builder.ins().atomic_store(flags, data, final_effective_address);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2495,11 +2411,8 @@ fn translate_br_if_args(
|
||||
// The values returned by the branch are still available for the reachable
|
||||
// code that comes after it
|
||||
frame.set_branched_to_exit();
|
||||
let return_count = if frame.is_loop() {
|
||||
frame.num_param_values()
|
||||
} else {
|
||||
frame.num_return_values()
|
||||
};
|
||||
let return_count =
|
||||
if frame.is_loop() { frame.num_param_values() } else { frame.num_return_values() };
|
||||
(return_count, frame.br_destination())
|
||||
};
|
||||
let inputs = state.peekn_mut(return_count);
|
||||
@@ -2708,10 +2621,7 @@ fn optionally_bitcast_vector(
|
||||
|
||||
#[inline(always)]
|
||||
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
|
||||
@@ -2725,9 +2635,8 @@ fn canonicalise_v128_values<'a>(
|
||||
) -> &'a [ir::Value] {
|
||||
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.
|
||||
let any_non_canonical = values
|
||||
.iter()
|
||||
.any(|v| is_non_canonical_v128(builder.func.dfg.value_type(*v)));
|
||||
let any_non_canonical =
|
||||
values.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.
|
||||
if !any_non_canonical {
|
||||
return values;
|
||||
|
||||
@@ -95,28 +95,16 @@ pub enum ControlStackFrame {
|
||||
impl ControlStackFrame {
|
||||
pub fn num_return_values(&self) -> usize {
|
||||
match *self {
|
||||
Self::If {
|
||||
num_return_values, ..
|
||||
}
|
||||
| Self::Block {
|
||||
num_return_values, ..
|
||||
}
|
||||
| Self::Loop {
|
||||
num_return_values, ..
|
||||
} => num_return_values,
|
||||
Self::If { num_return_values, .. }
|
||||
| Self::Block { num_return_values, .. }
|
||||
| Self::Loop { num_return_values, .. } => num_return_values,
|
||||
}
|
||||
}
|
||||
pub fn num_param_values(&self) -> usize {
|
||||
match *self {
|
||||
Self::If {
|
||||
num_param_values, ..
|
||||
}
|
||||
| Self::Block {
|
||||
num_param_values, ..
|
||||
}
|
||||
| Self::Loop {
|
||||
num_param_values, ..
|
||||
} => num_param_values,
|
||||
Self::If { num_param_values, .. }
|
||||
| Self::Block { num_param_values, .. }
|
||||
| Self::Loop { num_param_values, .. } => num_param_values,
|
||||
}
|
||||
}
|
||||
pub fn following_code(&self) -> Block {
|
||||
@@ -136,18 +124,9 @@ impl ControlStackFrame {
|
||||
/// `truncate_value_stack_to_original_size()` to restore value-stack state.
|
||||
fn original_stack_size(&self) -> usize {
|
||||
match *self {
|
||||
Self::If {
|
||||
original_stack_size,
|
||||
..
|
||||
}
|
||||
| Self::Block {
|
||||
original_stack_size,
|
||||
..
|
||||
}
|
||||
| Self::Loop {
|
||||
original_stack_size,
|
||||
..
|
||||
} => original_stack_size,
|
||||
Self::If { original_stack_size, .. }
|
||||
| Self::Block { original_stack_size, .. }
|
||||
| Self::Loop { original_stack_size, .. } => original_stack_size,
|
||||
}
|
||||
}
|
||||
pub fn is_loop(&self) -> bool {
|
||||
@@ -159,28 +138,17 @@ impl ControlStackFrame {
|
||||
|
||||
pub fn exit_is_branched_to(&self) -> bool {
|
||||
match *self {
|
||||
Self::If {
|
||||
exit_is_branched_to,
|
||||
..
|
||||
Self::If { exit_is_branched_to, .. } | Self::Block { exit_is_branched_to, .. } => {
|
||||
exit_is_branched_to
|
||||
}
|
||||
| Self::Block {
|
||||
exit_is_branched_to,
|
||||
..
|
||||
} => exit_is_branched_to,
|
||||
Self::Loop { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_branched_to_exit(&mut self) {
|
||||
match *self {
|
||||
Self::If {
|
||||
ref mut exit_is_branched_to,
|
||||
..
|
||||
}
|
||||
| Self::Block {
|
||||
ref mut exit_is_branched_to,
|
||||
..
|
||||
} => *exit_is_branched_to = true,
|
||||
Self::If { ref mut exit_is_branched_to, .. }
|
||||
| Self::Block { ref mut exit_is_branched_to, .. } => *exit_is_branched_to = true,
|
||||
Self::Loop { .. } => {}
|
||||
}
|
||||
}
|
||||
@@ -201,9 +169,7 @@ impl ControlStackFrame {
|
||||
// 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.
|
||||
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());
|
||||
num_param_values
|
||||
}
|
||||
@@ -302,10 +268,7 @@ impl FuncTranslationState {
|
||||
self.push_block(
|
||||
exit_block,
|
||||
0,
|
||||
sig.returns
|
||||
.iter()
|
||||
.filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
|
||||
.count(),
|
||||
sig.returns.iter().filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal).count(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -333,20 +296,14 @@ impl FuncTranslationState {
|
||||
|
||||
/// Pop one value.
|
||||
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();
|
||||
(val, val_metadata)
|
||||
}
|
||||
|
||||
/// Peek at the top of the stack without popping it.
|
||||
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();
|
||||
(val, val_metadata)
|
||||
}
|
||||
@@ -361,11 +318,7 @@ impl FuncTranslationState {
|
||||
/// Pop three values. Return them in the order they were pushed.
|
||||
pub(crate) fn pop3(
|
||||
&mut self,
|
||||
) -> (
|
||||
(Value, ValueExtraInfo),
|
||||
(Value, ValueExtraInfo),
|
||||
(Value, ValueExtraInfo),
|
||||
) {
|
||||
) -> ((Value, ValueExtraInfo), (Value, ValueExtraInfo), (Value, ValueExtraInfo)) {
|
||||
let v3 = self.pop1();
|
||||
let v2 = self.pop1();
|
||||
let v1 = self.pop1();
|
||||
@@ -577,10 +530,7 @@ impl FuncTranslationState {
|
||||
Vacant(entry) => {
|
||||
let fref = environ.make_direct_func(func, index)?;
|
||||
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]))))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,7 +540,5 @@ fn num_wasm_parameters<FE: FuncEnvironment + ?Sized>(
|
||||
environ: &FE,
|
||||
signature: &ir::Signature,
|
||||
) -> 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()
|
||||
}
|
||||
|
||||
@@ -37,10 +37,7 @@ pub struct FuncTranslator {
|
||||
impl FuncTranslator {
|
||||
/// Create a new translator.
|
||||
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.
|
||||
@@ -73,9 +70,7 @@ impl FuncTranslator {
|
||||
) -> WasmResult<()> {
|
||||
let mut reader = MiddlewareBinaryReader::new_with_offset(code, code_offset);
|
||||
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);
|
||||
self.translate_from_reader(module_translation_state, reader, func, environ)
|
||||
@@ -90,12 +85,7 @@ impl FuncTranslator {
|
||||
environ: &mut FE,
|
||||
) -> WasmResult<()> {
|
||||
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_insts(), 0, "Function must be empty");
|
||||
|
||||
|
||||
@@ -33,10 +33,8 @@ pub fn signature_to_cranelift_ir(
|
||||
AbiParam::new(cret_arg)
|
||||
}));
|
||||
// The Vmctx signature
|
||||
sig.params.insert(
|
||||
0,
|
||||
AbiParam::special(target_config.pointer_type(), ir::ArgumentPurpose::VMContext),
|
||||
);
|
||||
sig.params
|
||||
.insert(0, AbiParam::special(target_config.pointer_type(), ir::ArgumentPurpose::VMContext));
|
||||
sig
|
||||
}
|
||||
|
||||
@@ -45,9 +43,7 @@ pub fn reference_type(target_config: TargetFrontendConfig) -> WasmResult<ir::Typ
|
||||
match target_config.pointer_type() {
|
||||
ir::types::I32 => Ok(ir::types::R32),
|
||||
ir::types::I64 => Ok(ir::types::R64),
|
||||
_ => Err(WasmError::Unsupported(
|
||||
"unsupported pointer type".to_string(),
|
||||
)),
|
||||
_ => Err(WasmError::Unsupported("unsupported pointer type".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,9 +72,7 @@ impl Abi for Aarch64SystemV {
|
||||
(
|
||||
context.create_enum_attribute(
|
||||
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),
|
||||
),
|
||||
@@ -83,9 +81,7 @@ impl Abi for Aarch64SystemV {
|
||||
|
||||
Ok(match sig.results() {
|
||||
[] => (
|
||||
intrinsics
|
||||
.void_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[_] => {
|
||||
@@ -225,9 +221,7 @@ impl Abi for Aarch64SystemV {
|
||||
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
|
||||
|
||||
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 {
|
||||
values.collect()
|
||||
}
|
||||
@@ -308,14 +302,9 @@ impl Abi for Aarch64SystemV {
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
let array_value = basic_value.into_array_value();
|
||||
let low = builder
|
||||
.build_extract_value(array_value, 0, "")
|
||||
.unwrap()
|
||||
.into_int_value();
|
||||
let high = builder
|
||||
.build_extract_value(array_value, 1, "")
|
||||
.unwrap()
|
||||
.into_int_value();
|
||||
let low = builder.build_extract_value(array_value, 0, "").unwrap().into_int_value();
|
||||
let high =
|
||||
builder.build_extract_value(array_value, 1, "").unwrap().into_int_value();
|
||||
let func_sig_returns_bitwidths = func_sig
|
||||
.results()
|
||||
.iter()
|
||||
@@ -473,9 +462,7 @@ impl Abi for Aarch64SystemV {
|
||||
if v.is_float_value() {
|
||||
let v = v.into_float_value();
|
||||
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, "");
|
||||
v.as_basic_value_enum()
|
||||
} else {
|
||||
@@ -522,10 +509,7 @@ impl Abi for Aarch64SystemV {
|
||||
&& v2.is_float_value()
|
||||
&& 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) => {
|
||||
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
||||
@@ -541,10 +525,7 @@ impl Abi for Aarch64SystemV {
|
||||
&& v2.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) => {
|
||||
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
||||
|
||||
@@ -25,12 +25,7 @@ use aarch64_systemv::Aarch64SystemV;
|
||||
use x86_64_systemv::X86_64SystemV;
|
||||
|
||||
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 {})
|
||||
} else {
|
||||
Box::new(X86_64SystemV {})
|
||||
|
||||
@@ -76,9 +76,7 @@ impl Abi for X86_64SystemV {
|
||||
(
|
||||
context.create_enum_attribute(
|
||||
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),
|
||||
),
|
||||
@@ -98,9 +96,7 @@ impl Abi for X86_64SystemV {
|
||||
|
||||
Ok(match sig_returns_bitwidths.as_slice() {
|
||||
[] => (
|
||||
intrinsics
|
||||
.void_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[_] => {
|
||||
@@ -133,9 +129,7 @@ impl Abi for X86_64SystemV {
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[32, 32] => (
|
||||
intrinsics
|
||||
.i64_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.i64_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
vmctx_attributes(0),
|
||||
),
|
||||
[32, 32, _] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => (
|
||||
@@ -213,9 +207,7 @@ impl Abi for X86_64SystemV {
|
||||
.map(|&ty| type_to_llvm(intrinsics, ty))
|
||||
.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);
|
||||
|
||||
@@ -226,9 +218,7 @@ impl Abi for X86_64SystemV {
|
||||
attributes.append(&mut vmctx_attributes(1));
|
||||
|
||||
(
|
||||
intrinsics
|
||||
.void_ty
|
||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||
attributes,
|
||||
)
|
||||
}
|
||||
@@ -262,9 +252,7 @@ impl Abi for X86_64SystemV {
|
||||
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
|
||||
|
||||
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 {
|
||||
values.collect()
|
||||
}
|
||||
@@ -541,10 +529,7 @@ impl Abi for X86_64SystemV {
|
||||
}
|
||||
[v1, 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(
|
||||
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
Reference in New Issue
Block a user