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,
|
i32,
|
||||||
> = dyn_f_many.native().unwrap();
|
> = dyn_f_many.native().unwrap();
|
||||||
c.bench_function(
|
c.bench_function(&format!("basic static func with many args {}", compiler_name), |b| {
|
||||||
&format!("basic static func with many args {}", compiler_name),
|
b.iter(|| {
|
||||||
|b| {
|
let result = black_box(
|
||||||
b.iter(|| {
|
f_many
|
||||||
let result = black_box(
|
.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
|
||||||
f_many
|
.unwrap(),
|
||||||
.call(
|
);
|
||||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
assert_eq!(result, 210);
|
||||||
)
|
})
|
||||||
.unwrap(),
|
});
|
||||||
);
|
|
||||||
assert_eq!(result, 210);
|
|
||||||
})
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_basic_dynamic_function(store: &Store, compiler_name: &str, c: &mut Criterion) {
|
pub fn run_basic_dynamic_function(store: &Store, compiler_name: &str, c: &mut Criterion) {
|
||||||
@@ -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();
|
let dyn_f_many: &Function = instance.exports.get("add20").unwrap();
|
||||||
c.bench_function(
|
c.bench_function(&format!("basic dynfunc with many args {}", compiler_name), |b| {
|
||||||
&format!("basic dynfunc with many args {}", compiler_name),
|
b.iter(|| {
|
||||||
|b| {
|
let dyn_result = black_box(
|
||||||
b.iter(|| {
|
dyn_f_many
|
||||||
let dyn_result = black_box(
|
.call(&[
|
||||||
dyn_f_many
|
Val::I32(1),
|
||||||
.call(&[
|
Val::I32(2),
|
||||||
Val::I32(1),
|
Val::I32(3),
|
||||||
Val::I32(2),
|
Val::I32(4),
|
||||||
Val::I32(3),
|
Val::I32(5),
|
||||||
Val::I32(4),
|
Val::I32(6),
|
||||||
Val::I32(5),
|
Val::I32(7),
|
||||||
Val::I32(6),
|
Val::I32(8),
|
||||||
Val::I32(7),
|
Val::I32(9),
|
||||||
Val::I32(8),
|
Val::I32(10),
|
||||||
Val::I32(9),
|
Val::I32(11),
|
||||||
Val::I32(10),
|
Val::I32(12),
|
||||||
Val::I32(11),
|
Val::I32(13),
|
||||||
Val::I32(12),
|
Val::I32(14),
|
||||||
Val::I32(13),
|
Val::I32(15),
|
||||||
Val::I32(14),
|
Val::I32(16),
|
||||||
Val::I32(15),
|
Val::I32(17),
|
||||||
Val::I32(16),
|
Val::I32(18),
|
||||||
Val::I32(17),
|
Val::I32(19),
|
||||||
Val::I32(18),
|
Val::I32(20),
|
||||||
Val::I32(19),
|
])
|
||||||
Val::I32(20),
|
.unwrap(),
|
||||||
])
|
);
|
||||||
.unwrap(),
|
assert_eq!(dyn_result[0], Val::I32(210));
|
||||||
);
|
})
|
||||||
assert_eq!(dyn_result[0], Val::I32(210));
|
});
|
||||||
})
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_static_benchmarks(_c: &mut Criterion) {
|
fn run_static_benchmarks(_c: &mut Criterion) {
|
||||||
|
|||||||
13
build.rs
13
build.rs
@@ -30,11 +30,8 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
// Spectests test generation
|
// Spectests test generation
|
||||||
{
|
{
|
||||||
let mut spectests = Testsuite {
|
let mut spectests =
|
||||||
buffer: String::new(),
|
Testsuite { buffer: String::new(), path: vec![], ignores: ignores.clone() };
|
||||||
path: vec![],
|
|
||||||
ignores: ignores.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
with_features(&mut spectests, &compilers, |mut spectests| {
|
with_features(&mut spectests, &compilers, |mut spectests| {
|
||||||
with_test_module(&mut spectests, "spec", |spectests| {
|
with_test_module(&mut spectests, "spec", |spectests| {
|
||||||
@@ -67,11 +64,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
// Wasitest test generation
|
// Wasitest test generation
|
||||||
{
|
{
|
||||||
let mut wasitests = Testsuite {
|
let mut wasitests = Testsuite { buffer: String::new(), path: vec![], ignores };
|
||||||
buffer: String::new(),
|
|
||||||
path: vec![],
|
|
||||||
ignores,
|
|
||||||
};
|
|
||||||
let wasi_versions = ["unstable", "snapshot1"];
|
let wasi_versions = ["unstable", "snapshot1"];
|
||||||
with_features(&mut wasitests, &compilers, |mut wasitests| {
|
with_features(&mut wasitests, &compilers, |mut wasitests| {
|
||||||
with_test_module(&mut wasitests, "wasitests", |wasitests| {
|
with_test_module(&mut wasitests, "wasitests", |wasitests| {
|
||||||
|
|||||||
@@ -87,10 +87,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
// When we call a function it can either succeed or fail. We expect it to fail.
|
// When we call a function it can either succeed or fail. We expect it to fail.
|
||||||
match run_func.call(1, 7) {
|
match run_func.call(1, 7) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
bail!(
|
bail!("Expected early termination with `ExitCode`, found: {}", result);
|
||||||
"Expected early termination with `ExitCode`, found: {}",
|
|
||||||
result
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// In case of a failure, which we expect, we attempt to downcast the error into the error
|
// In case of a failure, which we expect, we attempt to downcast the error into the error
|
||||||
// type that we were expecting.
|
// type that we were expecting.
|
||||||
|
|||||||
@@ -59,10 +59,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// produce an error.
|
// produce an error.
|
||||||
//
|
//
|
||||||
// Let's get it.
|
// Let's get it.
|
||||||
let div_by_zero = instance
|
let div_by_zero = instance.exports.get_function("div_by_zero")?.native::<(), i32>()?;
|
||||||
.exports
|
|
||||||
.get_function("div_by_zero")?
|
|
||||||
.native::<(), i32>()?;
|
|
||||||
|
|
||||||
println!("Calling `div_by_zero` function...");
|
println!("Calling `div_by_zero` function...");
|
||||||
// Let's call the `div_by_zero` exported function.
|
// Let's call the `div_by_zero` exported function.
|
||||||
|
|||||||
@@ -88,10 +88,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
//
|
//
|
||||||
// We will use an exported function for the `one` global
|
// We will use an exported function for the `one` global
|
||||||
// and the Global API for `some`.
|
// and the Global API for `some`.
|
||||||
let get_one = instance
|
let get_one = instance.exports.get_function("get_one")?.native::<(), f32>()?;
|
||||||
.exports
|
|
||||||
.get_function("get_one")?
|
|
||||||
.native::<(), f32>()?;
|
|
||||||
|
|
||||||
let one_value = get_one.call()?;
|
let one_value = get_one.call()?;
|
||||||
let some_value = some.get();
|
let some_value = some.get();
|
||||||
@@ -120,10 +117,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// 2. Using the Global API directly.
|
// 2. Using the Global API directly.
|
||||||
//
|
//
|
||||||
// We will use both for the `some` global.
|
// We will use both for the `some` global.
|
||||||
let set_some = instance
|
let set_some = instance.exports.get_function("set_some")?.native::<f32, ()>()?;
|
||||||
.exports
|
|
||||||
.get_function("set_some")?
|
|
||||||
.native::<f32, ()>()?;
|
|
||||||
set_some.call(21.0)?;
|
set_some.call(21.0)?;
|
||||||
let some_result = some.get();
|
let some_result = some.get();
|
||||||
println!("`some` value after `set_some`: {:?}", some_result);
|
println!("`some` value after `set_some`: {:?}", some_result);
|
||||||
|
|||||||
@@ -50,9 +50,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Let's instantiate the Wasm module.
|
// Let's instantiate the Wasm module.
|
||||||
let instance = Instance::new(&module, &import_object)?;
|
let instance = Instance::new(&module, &import_object)?;
|
||||||
|
|
||||||
let load = instance
|
let load = instance.exports.get_native_function::<(), (WasmPtr<u8, Array>, i32)>("load")?;
|
||||||
.exports
|
|
||||||
.get_native_function::<(), (WasmPtr<u8, Array>, i32)>("load")?;
|
|
||||||
|
|
||||||
// Here we go.
|
// Here we go.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -59,9 +59,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// covered in more detail in other examples.
|
// covered in more detail in other examples.
|
||||||
println!("Creating the imported function...");
|
println!("Creating the imported function...");
|
||||||
let host_function_signature = FunctionType::new(vec![], vec![Type::I32]);
|
let host_function_signature = FunctionType::new(vec![], vec![Type::I32]);
|
||||||
let host_function = Function::new(&store, &host_function_signature, |_args| {
|
let host_function =
|
||||||
Ok(vec![Value::I32(42)])
|
Function::new(&store, &host_function_signature, |_args| Ok(vec![Value::I32(42)]));
|
||||||
});
|
|
||||||
|
|
||||||
println!("Creating the imported global...");
|
println!("Creating the imported global...");
|
||||||
let host_global = Global::new(&store, Value::I32(42));
|
let host_global = Global::new(&store, Value::I32(42));
|
||||||
|
|||||||
@@ -85,10 +85,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Here we go.
|
// Here we go.
|
||||||
//
|
//
|
||||||
// The Wasm module exports a function called `sum`. Let's get it.
|
// The Wasm module exports a function called `sum`. Let's get it.
|
||||||
let sum = instance
|
let sum = instance.exports.get_function("sum")?.native::<(i32, i32), i32>()?;
|
||||||
.exports
|
|
||||||
.get_function("sum")?
|
|
||||||
.native::<(i32, i32), i32>()?;
|
|
||||||
|
|
||||||
println!("Calling `sum` function...");
|
println!("Calling `sum` function...");
|
||||||
// Let's call the `sum` exported function. It will call each
|
// Let's call the `sum` exported function. It will call each
|
||||||
|
|||||||
@@ -100,10 +100,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Here we go.
|
// Here we go.
|
||||||
//
|
//
|
||||||
// The Wasm module exports a function called `increment_counter_loop`. Let's get it.
|
// The Wasm module exports a function called `increment_counter_loop`. Let's get it.
|
||||||
let increment_counter_loop = instance
|
let increment_counter_loop =
|
||||||
.exports
|
instance.exports.get_function("increment_counter_loop")?.native::<i32, i32>()?;
|
||||||
.get_function("increment_counter_loop")?
|
|
||||||
.native::<i32, i32>()?;
|
|
||||||
|
|
||||||
let counter_value: i32 = *shared_counter.lock().unwrap();
|
let counter_value: i32 = *shared_counter.lock().unwrap();
|
||||||
println!("Initial ounter value: {:?}", counter_value);
|
println!("Initial ounter value: {:?}", counter_value);
|
||||||
|
|||||||
@@ -65,14 +65,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
//
|
//
|
||||||
// The Wasm module only imports some globals. We'll have to interact
|
// The Wasm module only imports some globals. We'll have to interact
|
||||||
// with them either using the Global API or exported functions.
|
// with them either using the Global API or exported functions.
|
||||||
let get_some = instance
|
let get_some = instance.exports.get_function("get_some")?.native::<(), f32>()?;
|
||||||
.exports
|
let get_other = instance.exports.get_function("get_other")?.native::<(), f32>()?;
|
||||||
.get_function("get_some")?
|
|
||||||
.native::<(), f32>()?;
|
|
||||||
let get_other = instance
|
|
||||||
.exports
|
|
||||||
.get_function("get_other")?
|
|
||||||
.native::<(), f32>()?;
|
|
||||||
|
|
||||||
let some_result = get_some.call()?;
|
let some_result = get_some.call()?;
|
||||||
let other_result = get_other.call()?;
|
let other_result = get_other.call()?;
|
||||||
@@ -102,10 +96,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("Altering global values through exported functions...");
|
println!("Altering global values through exported functions...");
|
||||||
// Changes made to global through exported functions will
|
// Changes made to global through exported functions will
|
||||||
// be reflected on the host side.
|
// be reflected on the host side.
|
||||||
let set_other = instance
|
let set_other = instance.exports.get_function("set_other")?.native::<f32, ()>()?;
|
||||||
.exports
|
|
||||||
.get_function("set_other")?
|
|
||||||
.native::<f32, ()>()?;
|
|
||||||
set_other.call(42.0)?;
|
set_other.call(42.0)?;
|
||||||
|
|
||||||
println!("other value (via Global API): {:?}", other.get());
|
println!("other value (via Global API): {:?}", other.get());
|
||||||
|
|||||||
@@ -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
|
// Here we are retrieving the exported function. We won't go into details here
|
||||||
// as the main focus of this example is to show how to create an instance out
|
// as the main focus of this example is to show how to create an instance out
|
||||||
// of a Wasm module and have basic interactions with it.
|
// of a Wasm module and have basic interactions with it.
|
||||||
let add_one = instance
|
let add_one = instance.exports.get_function("add_one")?.native::<i32, i32>()?;
|
||||||
.exports
|
|
||||||
.get_function("add_one")?
|
|
||||||
.native::<i32, i32>()?;
|
|
||||||
|
|
||||||
println!("Calling `add_one` function...");
|
println!("Calling `add_one` function...");
|
||||||
let result = add_one.call(1)?;
|
let result = add_one.call(1)?;
|
||||||
|
|||||||
@@ -87,10 +87,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
//
|
//
|
||||||
// Our module exports a single `add_one` function. We want to
|
// Our module exports a single `add_one` function. We want to
|
||||||
// measure the cost of executing this function.
|
// measure the cost of executing this function.
|
||||||
let add_one = instance
|
let add_one = instance.exports.get_function("add_one")?.native::<i32, i32>()?;
|
||||||
.exports
|
|
||||||
.get_function("add_one")?
|
|
||||||
.native::<i32, i32>()?;
|
|
||||||
|
|
||||||
println!("Calling `add_one` function once...");
|
println!("Calling `add_one` function once...");
|
||||||
add_one.call(1)?;
|
add_one.call(1)?;
|
||||||
@@ -102,15 +99,9 @@ fn main() -> anyhow::Result<()> {
|
|||||||
// * `i32.const` is a `Operator::I32Const` which costs 1 point;
|
// * `i32.const` is a `Operator::I32Const` which costs 1 point;
|
||||||
// * `i32.add` is a `Operator::I32Add` which costs 2 points.
|
// * `i32.add` is a `Operator::I32Add` which costs 2 points.
|
||||||
let remaining_points_after_first_call = get_remaining_points(&instance);
|
let remaining_points_after_first_call = get_remaining_points(&instance);
|
||||||
assert_eq!(
|
assert_eq!(remaining_points_after_first_call, MeteringPoints::Remaining(6));
|
||||||
remaining_points_after_first_call,
|
|
||||||
MeteringPoints::Remaining(6)
|
|
||||||
);
|
|
||||||
|
|
||||||
println!(
|
println!("Remaining points after the first call: {:?}", remaining_points_after_first_call);
|
||||||
"Remaining points after the first call: {:?}",
|
|
||||||
remaining_points_after_first_call
|
|
||||||
);
|
|
||||||
|
|
||||||
println!("Calling `add_one` function twice...");
|
println!("Calling `add_one` function twice...");
|
||||||
add_one.call(1)?;
|
add_one.call(1)?;
|
||||||
@@ -118,15 +109,9 @@ fn main() -> anyhow::Result<()> {
|
|||||||
// We spent 4 more points with the second call.
|
// We spent 4 more points with the second call.
|
||||||
// We have 2 remaining points.
|
// We have 2 remaining points.
|
||||||
let remaining_points_after_second_call = get_remaining_points(&instance);
|
let remaining_points_after_second_call = get_remaining_points(&instance);
|
||||||
assert_eq!(
|
assert_eq!(remaining_points_after_second_call, MeteringPoints::Remaining(2));
|
||||||
remaining_points_after_second_call,
|
|
||||||
MeteringPoints::Remaining(2)
|
|
||||||
);
|
|
||||||
|
|
||||||
println!(
|
println!("Remaining points after the second call: {:?}", remaining_points_after_second_call);
|
||||||
"Remaining points after the second call: {:?}",
|
|
||||||
remaining_points_after_second_call
|
|
||||||
);
|
|
||||||
|
|
||||||
// Because calling our `add_one` function consumes 4 points,
|
// Because calling our `add_one` function consumes 4 points,
|
||||||
// calling it a third time will fail: we already consume 8
|
// calling it a third time will fail: we already consume 8
|
||||||
@@ -134,10 +119,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
println!("Calling `add_one` function a third time...");
|
println!("Calling `add_one` function a third time...");
|
||||||
match add_one.call(1) {
|
match add_one.call(1) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
bail!(
|
bail!("Expected failure while calling `add_one`, found: {}", result);
|
||||||
"Expected failure while calling `add_one`, found: {}",
|
|
||||||
result
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("Calling `add_one` failed.");
|
println!("Calling `add_one` failed.");
|
||||||
|
|||||||
@@ -74,14 +74,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let guest_table = instance.exports.get_table("__indirect_function_table")?;
|
let guest_table = instance.exports.get_table("__indirect_function_table")?;
|
||||||
// And demonstrate that it has the properties that we set in the Wasm.
|
// And demonstrate that it has the properties that we set in the Wasm.
|
||||||
assert_eq!(guest_table.size(), 3);
|
assert_eq!(guest_table.size(), 3);
|
||||||
assert_eq!(
|
assert_eq!(guest_table.ty(), &TableType { ty: Type::FuncRef, minimum: 3, maximum: Some(6) });
|
||||||
guest_table.ty(),
|
|
||||||
&TableType {
|
|
||||||
ty: Type::FuncRef,
|
|
||||||
minimum: 3,
|
|
||||||
maximum: Some(6),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// == Setting elements in a table ==
|
// == Setting elements in a table ==
|
||||||
|
|
||||||
@@ -108,14 +101,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
assert_eq!(previous_size, 3);
|
assert_eq!(previous_size, 3);
|
||||||
|
|
||||||
assert_eq!(guest_table.size(), 6);
|
assert_eq!(guest_table.size(), 6);
|
||||||
assert_eq!(
|
assert_eq!(guest_table.ty(), &TableType { ty: Type::FuncRef, minimum: 3, maximum: Some(6) });
|
||||||
guest_table.ty(),
|
|
||||||
&TableType {
|
|
||||||
ty: Type::FuncRef,
|
|
||||||
minimum: 3,
|
|
||||||
maximum: Some(6),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Now demonstrate that the function we grew the table with is actually in the table.
|
// Now demonstrate that the function we grew the table with is actually in the table.
|
||||||
for table_index in 3..6 {
|
for table_index in 3..6 {
|
||||||
if let Value::FuncRef(Some(f)) = guest_table.get(table_index as _).unwrap() {
|
if let Value::FuncRef(Some(f)) = guest_table.get(table_index as _).unwrap() {
|
||||||
|
|||||||
@@ -105,8 +105,7 @@ impl<T: Tunables> Tunables for LimitingTunables<T> {
|
|||||||
) -> Result<Arc<dyn vm::Memory>, MemoryError> {
|
) -> Result<Arc<dyn vm::Memory>, MemoryError> {
|
||||||
let adjusted = self.adjust_memory(ty);
|
let adjusted = self.adjust_memory(ty);
|
||||||
self.validate_memory(&adjusted)?;
|
self.validate_memory(&adjusted)?;
|
||||||
self.base
|
self.base.create_vm_memory(&adjusted, style, vm_definition_location)
|
||||||
.create_vm_memory(&adjusted, style, vm_definition_location)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
|
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
|
||||||
@@ -164,12 +163,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let instance = Instance::new(&module, &import_object)?;
|
let instance = Instance::new(&module, &import_object)?;
|
||||||
|
|
||||||
// Check what happened
|
// Check what happened
|
||||||
let mut memories: Vec<Memory> = instance
|
let mut memories: Vec<Memory> =
|
||||||
.exports
|
instance.exports.iter().memories().map(|pair| pair.1.clone()).collect();
|
||||||
.iter()
|
|
||||||
.memories()
|
|
||||||
.map(|pair| pair.1.clone())
|
|
||||||
.collect();
|
|
||||||
assert_eq!(memories.len(), 1);
|
assert_eq!(memories.len(), 1);
|
||||||
|
|
||||||
let first_memory = memories.pop().unwrap();
|
let first_memory = memories.pop().unwrap();
|
||||||
|
|||||||
@@ -21,10 +21,8 @@ use wasmer_engine_jit::JIT;
|
|||||||
use wasmer_wasi::WasiState;
|
use wasmer_wasi::WasiState;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let wasm_path = concat!(
|
let wasm_path =
|
||||||
env!("CARGO_MANIFEST_DIR"),
|
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/wasi-wast/wasi/unstable/hello.wasm");
|
||||||
"/tests/wasi-wast/wasi/unstable/hello.wasm"
|
|
||||||
);
|
|
||||||
// Let's declare the Wasm module with the text representation.
|
// Let's declare the Wasm module with the text representation.
|
||||||
let wasm_bytes = std::fs::read(wasm_path)?;
|
let wasm_bytes = std::fs::read(wasm_path)?;
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,8 @@ use wasmer_engine_jit::JIT;
|
|||||||
use wasmer_wasi::{Pipe, WasiState};
|
use wasmer_wasi::{Pipe, WasiState};
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let wasm_path = concat!(
|
let wasm_path =
|
||||||
env!("CARGO_MANIFEST_DIR"),
|
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/wasi-wast/wasi/unstable/pipe_reverse.wasm");
|
||||||
"/tests/wasi-wast/wasi/unstable/pipe_reverse.wasm"
|
|
||||||
);
|
|
||||||
// Let's declare the Wasm module with the text representation.
|
// Let's declare the Wasm module with the text representation.
|
||||||
let wasm_bytes = std::fs::read(wasm_path)?;
|
let wasm_bytes = std::fs::read(wasm_path)?;
|
||||||
|
|
||||||
@@ -38,10 +36,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// First, we create the `WasiEnv` with the stdio pipes
|
// First, we create the `WasiEnv` with the stdio pipes
|
||||||
let input = Pipe::new();
|
let input = Pipe::new();
|
||||||
let output = Pipe::new();
|
let output = Pipe::new();
|
||||||
let mut wasi_env = WasiState::new("hello")
|
let mut wasi_env =
|
||||||
.stdin(Box::new(input))
|
WasiState::new("hello").stdin(Box::new(input)).stdout(Box::new(output)).finalize()?;
|
||||||
.stdout(Box::new(output))
|
|
||||||
.finalize()?;
|
|
||||||
|
|
||||||
println!("Instantiating module with WASI imports...");
|
println!("Instantiating module with WASI imports...");
|
||||||
// Then, we get the import object related to our WASI
|
// Then, we get the import object related to our WASI
|
||||||
|
|||||||
@@ -140,10 +140,7 @@ pub struct LazyInit<T: Sized> {
|
|||||||
impl<T> LazyInit<T> {
|
impl<T> LazyInit<T> {
|
||||||
/// Creates an unitialized value.
|
/// Creates an unitialized value.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self { data: std::mem::MaybeUninit::uninit(), initialized: false }
|
||||||
data: std::mem::MaybeUninit::uninit(),
|
|
||||||
initialized: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@@ -176,24 +173,16 @@ impl<T> LazyInit<T> {
|
|||||||
|
|
||||||
impl<T: std::fmt::Debug> std::fmt::Debug for LazyInit<T> {
|
impl<T: std::fmt::Debug> std::fmt::Debug for LazyInit<T> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("LazyInit")
|
f.debug_struct("LazyInit").field("data", &self.get_ref()).finish()
|
||||||
.field("data", &self.get_ref())
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> Clone for LazyInit<T> {
|
impl<T: Clone> Clone for LazyInit<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
if let Some(inner) = self.get_ref() {
|
if let Some(inner) = self.get_ref() {
|
||||||
Self {
|
Self { data: std::mem::MaybeUninit::new(inner.clone()), initialized: true }
|
||||||
data: std::mem::MaybeUninit::new(inner.clone()),
|
|
||||||
initialized: true,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Self {
|
Self { data: std::mem::MaybeUninit::uninit(), initialized: false }
|
||||||
data: std::mem::MaybeUninit::uninit(),
|
|
||||||
initialized: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,9 +75,7 @@ impl Exports {
|
|||||||
|
|
||||||
/// Creates a new `Exports` with capacity `n`.
|
/// Creates a new `Exports` with capacity `n`.
|
||||||
pub fn with_capacity(n: usize) -> Self {
|
pub fn with_capacity(n: usize) -> Self {
|
||||||
Self {
|
Self { map: Arc::new(IndexMap::with_capacity(n)) }
|
||||||
map: Arc::new(IndexMap::with_capacity(n)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of exports in the `Exports` map.
|
/// Return the number of exports in the `Exports` map.
|
||||||
@@ -96,9 +94,7 @@ impl Exports {
|
|||||||
S: Into<String>,
|
S: Into<String>,
|
||||||
E: Into<Extern>,
|
E: Into<Extern>,
|
||||||
{
|
{
|
||||||
Arc::get_mut(&mut self.map)
|
Arc::get_mut(&mut self.map).unwrap().insert(name.into(), value.into());
|
||||||
.unwrap()
|
|
||||||
.insert(name.into(), value.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an export given a `name`.
|
/// Get an export given a `name`.
|
||||||
@@ -148,9 +144,7 @@ impl Exports {
|
|||||||
Args: WasmTypeList,
|
Args: WasmTypeList,
|
||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
{
|
{
|
||||||
self.get_function(name)?
|
self.get_function(name)?.native().map_err(|_| ExportError::IncompatibleType)
|
||||||
.native()
|
|
||||||
.map_err(|_| ExportError::IncompatibleType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hack to get this working with nativefunc too
|
/// Hack to get this working with nativefunc too
|
||||||
@@ -181,9 +175,7 @@ impl Exports {
|
|||||||
|
|
||||||
/// Get an iterator over the exports.
|
/// Get an iterator over the exports.
|
||||||
pub fn iter(&self) -> ExportsIterator<impl Iterator<Item = (&String, &Extern)>> {
|
pub fn iter(&self) -> ExportsIterator<impl Iterator<Item = (&String, &Extern)>> {
|
||||||
ExportsIterator {
|
ExportsIterator { iter: self.map.iter() }
|
||||||
iter: self.map.iter(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,9 +252,7 @@ where
|
|||||||
|
|
||||||
impl FromIterator<(String, Extern)> for Exports {
|
impl FromIterator<(String, Extern)> for Exports {
|
||||||
fn from_iter<I: IntoIterator<Item = (String, Extern)>>(iter: I) -> Self {
|
fn from_iter<I: IntoIterator<Item = (String, Extern)>>(iter: I) -> Self {
|
||||||
Self {
|
Self { map: Arc::new(IndexMap::from_iter(iter)) }
|
||||||
map: Arc::new(IndexMap::from_iter(iter)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,10 +262,7 @@ impl LikeNamespace for Exports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_namespace_exports(&self) -> Vec<(String, Export)> {
|
fn get_namespace_exports(&self) -> Vec<(String, Export)> {
|
||||||
self.map
|
self.map.iter().map(|(k, v)| (k.clone(), v.to_export())).collect()
|
||||||
.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 host_env_clone_fn = |ptr: *mut c_void| -> *mut c_void {
|
||||||
let env_ref: &Env = unsafe {
|
let env_ref: &Env = unsafe {
|
||||||
ptr.cast::<Env>()
|
ptr.cast::<Env>().as_ref().expect("`ptr` to the environment is null when cloning it")
|
||||||
.as_ref()
|
|
||||||
.expect("`ptr` to the environment is null when cloning it")
|
|
||||||
};
|
};
|
||||||
Box::into_raw(Box::new(env_ref.clone())) as _
|
Box::into_raw(Box::new(env_ref.clone())) as _
|
||||||
};
|
};
|
||||||
@@ -352,9 +350,7 @@ impl Function {
|
|||||||
}
|
}
|
||||||
let function = inner::Function::<Args, Rets>::new(func);
|
let function = inner::Function::<Args, Rets>::new(func);
|
||||||
let address = function.address() as *const VMFunctionBody;
|
let address = function.address() as *const VMFunctionBody;
|
||||||
let vmctx = VMFunctionEnvironment {
|
let vmctx = VMFunctionEnvironment { host_env: std::ptr::null_mut() as *mut _ };
|
||||||
host_env: std::ptr::null_mut() as *mut _,
|
|
||||||
};
|
|
||||||
let signature = function.ty();
|
let signature = function.ty();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -517,11 +513,7 @@ impl Function {
|
|||||||
results: &mut [Val],
|
results: &mut [Val],
|
||||||
) -> Result<(), RuntimeError> {
|
) -> Result<(), RuntimeError> {
|
||||||
let format_types_for_error_message = |items: &[Val]| {
|
let format_types_for_error_message = |items: &[Val]| {
|
||||||
items
|
items.iter().map(|param| param.ty().to_string()).collect::<Vec<String>>().join(", ")
|
||||||
.iter()
|
|
||||||
.map(|param| param.ty().to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(", ")
|
|
||||||
};
|
};
|
||||||
let signature = self.ty();
|
let signature = self.ty();
|
||||||
if signature.params().len() != params.len() {
|
if signature.params().len() != params.len() {
|
||||||
@@ -798,11 +790,7 @@ impl Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(NativeFunc::new(
|
Ok(NativeFunc::new(self.store.clone(), self.exported.clone(), self.definition.clone()))
|
||||||
self.store.clone(),
|
|
||||||
self.exported.clone(),
|
|
||||||
self.definition.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
@@ -826,10 +814,7 @@ impl<'a> Exportable<'a> for Function {
|
|||||||
|
|
||||||
impl fmt::Debug for Function {
|
impl fmt::Debug for Function {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
formatter
|
formatter.debug_struct("Function").field("ty", &self.ty()).finish()
|
||||||
.debug_struct("Function")
|
|
||||||
.field("ty", &self.ty())
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,10 +890,7 @@ trait VMDynamicFunctionCall<T: VMDynamicFunction> {
|
|||||||
|
|
||||||
impl<T: VMDynamicFunction> VMDynamicFunctionCall<T> for VMDynamicFunctionContext<T> {
|
impl<T: VMDynamicFunction> VMDynamicFunctionCall<T> for VMDynamicFunctionContext<T> {
|
||||||
fn from_context(ctx: T) -> Self {
|
fn from_context(ctx: T) -> Self {
|
||||||
Self {
|
Self { address: Self::address_ptr(), ctx }
|
||||||
address: Self::address_ptr(),
|
|
||||||
ctx,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_ptr() -> *const VMFunctionBody {
|
fn address_ptr() -> *const VMFunctionBody {
|
||||||
@@ -1312,10 +1294,7 @@ mod inner {
|
|||||||
T: HostFunctionKind,
|
T: HostFunctionKind,
|
||||||
E: Sized,
|
E: Sized,
|
||||||
{
|
{
|
||||||
Self {
|
Self { address: function.function_body_ptr(), _phantom: PhantomData }
|
||||||
address: function.function_body_ptr(),
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the function type of this `Function`.
|
/// Get the function type of this `Function`.
|
||||||
@@ -1734,14 +1713,8 @@ mod inner {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_function_types() {
|
fn test_function_types() {
|
||||||
assert_eq!(Function::new(func).ty(), FunctionType::new(vec![], vec![]));
|
assert_eq!(Function::new(func).ty(), FunctionType::new(vec![], vec![]));
|
||||||
assert_eq!(
|
assert_eq!(Function::new(func__i32).ty(), FunctionType::new(vec![], vec![Type::I32]));
|
||||||
Function::new(func__i32).ty(),
|
assert_eq!(Function::new(func_i32).ty(), FunctionType::new(vec![Type::I32], vec![]));
|
||||||
FunctionType::new(vec![], vec![Type::I32])
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
Function::new(func_i32).ty(),
|
|
||||||
FunctionType::new(vec![Type::I32], vec![])
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Function::new(func_i32__i32).ty(),
|
Function::new(func_i32__i32).ty(),
|
||||||
FunctionType::new(vec![Type::I32], vec![Type::I32])
|
FunctionType::new(vec![Type::I32], vec![Type::I32])
|
||||||
|
|||||||
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) {
|
if !val.comes_from_same_store(store) {
|
||||||
return Err(RuntimeError::new("cross-`Store` globals are not supported"));
|
return Err(RuntimeError::new("cross-`Store` globals are not supported"));
|
||||||
}
|
}
|
||||||
let global = RuntimeGlobal::new(GlobalType {
|
let global = RuntimeGlobal::new(GlobalType { mutability, ty: val.ty() });
|
||||||
mutability,
|
|
||||||
ty: val.ty(),
|
|
||||||
});
|
|
||||||
unsafe {
|
unsafe {
|
||||||
global
|
global
|
||||||
.set_unchecked(val.clone())
|
.set_unchecked(val.clone())
|
||||||
.map_err(|e| RuntimeError::new(format!("create global for {:?}: {}", val, e)))?;
|
.map_err(|e| RuntimeError::new(format!("create global for {:?}: {}", val, e)))?;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self { store: store.clone(), global: Arc::new(global) })
|
||||||
store: store.clone(),
|
|
||||||
global: Arc::new(global),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`GlobalType`] of the `Global`.
|
/// Returns the [`GlobalType`] of the `Global`.
|
||||||
@@ -175,18 +169,13 @@ impl Global {
|
|||||||
return Err(RuntimeError::new("cross-`Store` values are not supported"));
|
return Err(RuntimeError::new("cross-`Store` values are not supported"));
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
self.global
|
self.global.set(val).map_err(|e| RuntimeError::new(format!("{}", e)))?;
|
||||||
.set(val)
|
|
||||||
.map_err(|e| RuntimeError::new(format!("{}", e)))?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportGlobal) -> Self {
|
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportGlobal) -> Self {
|
||||||
Self {
|
Self { store: store.clone(), global: wasmer_export.vm_global.from }
|
||||||
store: store.clone(),
|
|
||||||
global: wasmer_export.vm_global.from,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether or not these two globals refer to the same data.
|
/// Returns whether or not these two globals refer to the same data.
|
||||||
@@ -218,13 +207,8 @@ impl fmt::Debug for Global {
|
|||||||
|
|
||||||
impl<'a> Exportable<'a> for Global {
|
impl<'a> Exportable<'a> for Global {
|
||||||
fn to_export(&self) -> Export {
|
fn to_export(&self) -> Export {
|
||||||
ExportGlobal {
|
ExportGlobal { vm_global: VMExportGlobal { from: self.global.clone(), instance_ref: None } }
|
||||||
vm_global: VMExportGlobal {
|
.into()
|
||||||
from: self.global.clone(),
|
|
||||||
instance_ref: None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||||
|
|||||||
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 style = tunables.memory_style(&ty);
|
||||||
let memory = tunables.create_host_memory(&ty, &style)?;
|
let memory = tunables.create_host_memory(&ty, &style)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self { store: store.clone(), memory })
|
||||||
store: store.clone(),
|
|
||||||
memory,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`MemoryType`] of the `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 {
|
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportMemory) -> Self {
|
||||||
Self {
|
Self { store: store.clone(), memory: wasmer_export.vm_memory.from }
|
||||||
store: store.clone(),
|
|
||||||
memory: wasmer_export.vm_memory.from,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether or not these two memories refer to the same data.
|
/// Returns whether or not these two memories refer to the same data.
|
||||||
@@ -247,13 +241,8 @@ impl Memory {
|
|||||||
|
|
||||||
impl<'a> Exportable<'a> for Memory {
|
impl<'a> Exportable<'a> for Memory {
|
||||||
fn to_export(&self) -> Export {
|
fn to_export(&self) -> Export {
|
||||||
ExportMemory {
|
ExportMemory { vm_memory: VMExportMemory { from: self.memory.clone(), instance_ref: None } }
|
||||||
vm_memory: VMExportMemory {
|
.into()
|
||||||
from: self.memory.clone(),
|
|
||||||
instance_ref: None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||||
|
|||||||
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 item = init.into_table_reference(store)?;
|
||||||
let tunables = store.tunables();
|
let tunables = store.tunables();
|
||||||
let style = tunables.table_style(&ty);
|
let style = tunables.table_style(&ty);
|
||||||
let table = tunables
|
let table = tunables.create_host_table(&ty, &style).map_err(RuntimeError::new)?;
|
||||||
.create_host_table(&ty, &style)
|
|
||||||
.map_err(RuntimeError::new)?;
|
|
||||||
|
|
||||||
let num_elements = table.size();
|
let num_elements = table.size();
|
||||||
for i in 0..num_elements {
|
for i in 0..num_elements {
|
||||||
set_table_item(table.as_ref(), i, item.clone())?;
|
set_table_item(table.as_ref(), i, item.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self { store: store.clone(), table })
|
||||||
store: store.clone(),
|
|
||||||
table,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`TableType`] of the `Table`.
|
/// Returns the [`TableType`] of the `Table`.
|
||||||
@@ -116,9 +111,7 @@ impl Table {
|
|||||||
len: u32,
|
len: u32,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> Result<(), RuntimeError> {
|
||||||
if !Store::same(&dst_table.store, &src_table.store) {
|
if !Store::same(&dst_table.store, &src_table.store) {
|
||||||
return Err(RuntimeError::new(
|
return Err(RuntimeError::new("cross-`Store` table copies are not supported"));
|
||||||
"cross-`Store` table copies are not supported",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
RuntimeTable::copy(
|
RuntimeTable::copy(
|
||||||
dst_table.table.as_ref(),
|
dst_table.table.as_ref(),
|
||||||
@@ -132,10 +125,7 @@ impl Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportTable) -> Self {
|
pub(crate) fn from_vm_export(store: &Store, wasmer_export: ExportTable) -> Self {
|
||||||
Self {
|
Self { store: store.clone(), table: wasmer_export.vm_table.from }
|
||||||
store: store.clone(),
|
|
||||||
table: wasmer_export.vm_table.from,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether or not these two tables refer to the same data.
|
/// Returns whether or not these two tables refer to the same data.
|
||||||
@@ -146,13 +136,8 @@ impl Table {
|
|||||||
|
|
||||||
impl<'a> Exportable<'a> for Table {
|
impl<'a> Exportable<'a> for Table {
|
||||||
fn to_export(&self) -> Export {
|
fn to_export(&self) -> Export {
|
||||||
ExportTable {
|
ExportTable { vm_table: VMExportTable { from: self.table.clone(), instance_ref: None } }
|
||||||
vm_table: VMExportTable {
|
.into()
|
||||||
from: self.table.clone(),
|
|
||||||
instance_ref: None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||||
|
|||||||
@@ -137,9 +137,7 @@ impl IntoIterator for ImportObject {
|
|||||||
type Item = ((String, String), Export);
|
type Item = ((String, String), Export);
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
ImportObjectIterator {
|
ImportObjectIterator { elements: self.get_objects() }
|
||||||
elements: self.get_objects(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,10 +168,7 @@ impl fmt::Debug for ImportObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
f.debug_struct("ImportObject")
|
f.debug_struct("ImportObject")
|
||||||
.field(
|
.field("map", &SecretMap::new(self.map.lock().unwrap().borrow().len()))
|
||||||
"map",
|
|
||||||
&SecretMap::new(self.map.lock().unwrap().borrow().len()),
|
|
||||||
)
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,11 +125,8 @@ impl Instance {
|
|||||||
})
|
})
|
||||||
.collect::<Exports>();
|
.collect::<Exports>();
|
||||||
|
|
||||||
let instance = Self {
|
let instance =
|
||||||
handle: Arc::new(Mutex::new(handle)),
|
Self { handle: Arc::new(Mutex::new(handle)), module: module.clone(), exports };
|
||||||
module: module.clone(),
|
|
||||||
exports,
|
|
||||||
};
|
|
||||||
|
|
||||||
// # Safety
|
// # Safety
|
||||||
// `initialize_host_envs` should be called after instantiation but before
|
// `initialize_host_envs` should be called after instantiation but before
|
||||||
@@ -168,8 +165,6 @@ impl Instance {
|
|||||||
|
|
||||||
impl fmt::Debug for Instance {
|
impl fmt::Debug for Instance {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("Instance")
|
f.debug_struct("Instance").field("exports", &self.exports).finish()
|
||||||
.field("exports", &self.exports)
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,7 @@
|
|||||||
html_logo_url = "https://github.com/wasmerio.png?size=200",
|
html_logo_url = "https://github.com/wasmerio.png?size=200",
|
||||||
html_favicon_url = "https://wasmer.io/static/icons/favicon.ico"
|
html_favicon_url = "https://wasmer.io/static/icons/favicon.ico"
|
||||||
)]
|
)]
|
||||||
#![deny(
|
#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates, broken_intra_doc_links)]
|
||||||
missing_docs,
|
|
||||||
trivial_numeric_casts,
|
|
||||||
unused_extern_crates,
|
|
||||||
broken_intra_doc_links
|
|
||||||
)]
|
|
||||||
#![warn(unused_import_braces)]
|
#![warn(unused_import_braces)]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
|
|||||||
@@ -101,10 +101,7 @@ impl Module {
|
|||||||
pub fn new(store: &Store, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> {
|
pub fn new(store: &Store, bytes: impl AsRef<[u8]>) -> Result<Self, CompileError> {
|
||||||
#[cfg(feature = "wat")]
|
#[cfg(feature = "wat")]
|
||||||
let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| {
|
let bytes = wat::parse_bytes(bytes.as_ref()).map_err(|e| {
|
||||||
CompileError::Wasm(WasmError::Generic(format!(
|
CompileError::Wasm(WasmError::Generic(format!("Error when converting wat: {}", e)))
|
||||||
"Error when converting wat: {}",
|
|
||||||
e
|
|
||||||
)))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Self::from_binary(store, bytes.as_ref())
|
Self::from_binary(store, bytes.as_ref())
|
||||||
@@ -253,10 +250,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn from_artifact(store: &Store, artifact: Arc<dyn Artifact>) -> Self {
|
fn from_artifact(store: &Store, artifact: Arc<dyn Artifact>) -> Self {
|
||||||
Self {
|
Self { store: store.clone(), artifact }
|
||||||
store: store.clone(),
|
|
||||||
artifact,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn instantiate(
|
pub(crate) fn instantiate(
|
||||||
@@ -265,8 +259,7 @@ impl Module {
|
|||||||
) -> Result<InstanceHandle, InstantiationError> {
|
) -> Result<InstanceHandle, InstantiationError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let instance_handle =
|
let instance_handle =
|
||||||
self.artifact
|
self.artifact.instantiate(self.store.tunables(), resolver, Box::new(()))?;
|
||||||
.instantiate(self.store.tunables(), resolver, Box::new(()))?;
|
|
||||||
|
|
||||||
// After the instance handle is created, we need to initialize
|
// After the instance handle is created, we need to initialize
|
||||||
// the data, call the start function and so. However, if any
|
// the data, call the start function and so. However, if any
|
||||||
@@ -425,8 +418,6 @@ impl Module {
|
|||||||
|
|
||||||
impl fmt::Debug for Module {
|
impl fmt::Debug for Module {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Module")
|
f.debug_struct("Module").field("name", &self.name()).finish()
|
||||||
.field("name", &self.name())
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,7 @@ where
|
|||||||
exported: ExportFunction,
|
exported: ExportFunction,
|
||||||
definition: FunctionDefinition,
|
definition: FunctionDefinition,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self { definition, store, exported, _phantom: PhantomData }
|
||||||
definition,
|
|
||||||
store,
|
|
||||||
exported,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn vmctx(&self) -> VMFunctionEnvironment {
|
pub(crate) fn vmctx(&self) -> VMFunctionEnvironment {
|
||||||
@@ -97,11 +92,7 @@ where
|
|||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
{
|
{
|
||||||
fn from(other: NativeFunc<Args, Rets>) -> Self {
|
fn from(other: NativeFunc<Args, Rets>) -> Self {
|
||||||
Self {
|
Self { store: other.store, definition: other.definition, exported: other.exported }
|
||||||
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.
|
/// Create a new `WasmPtr` at the given offset.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(offset: u32) -> Self {
|
pub fn new(offset: u32) -> Self {
|
||||||
Self {
|
Self { offset, _phantom: PhantomData }
|
||||||
offset,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the offset into Wasm linear memory for this `WasmPtr`.
|
/// 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
|
self.offset as i32
|
||||||
}
|
}
|
||||||
fn from_native(n: Self::Native) -> Self {
|
fn from_native(n: Self::Native) -> Self {
|
||||||
Self {
|
Self { offset: n as u32, _phantom: PhantomData }
|
||||||
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> {
|
impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self { offset: self.offset, _phantom: PhantomData }
|
||||||
offset: self.offset,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,7 @@ impl Store {
|
|||||||
where
|
where
|
||||||
E: Engine + ?Sized,
|
E: Engine + ?Sized,
|
||||||
{
|
{
|
||||||
Self {
|
Self { engine: engine.cloned(), tunables: Arc::new(tunables) }
|
||||||
engine: engine.cloned(),
|
|
||||||
tunables: Arc::new(tunables),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`Tunables`].
|
/// Returns the [`Tunables`].
|
||||||
@@ -109,10 +106,7 @@ impl Default for Store {
|
|||||||
let config = get_config();
|
let config = get_config();
|
||||||
let engine = get_engine(config);
|
let engine = get_engine(config);
|
||||||
let tunables = BaseTunables::for_target(engine.target());
|
let tunables = BaseTunables::for_target(engine.target());
|
||||||
Store {
|
Store { engine: Arc::new(engine), tunables: Arc::new(tunables) }
|
||||||
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,
|
offset_guard_size: self.static_memory_offset_guard_size,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MemoryStyle::Dynamic {
|
MemoryStyle::Dynamic { offset_guard_size: self.dynamic_memory_offset_guard_size }
|
||||||
offset_guard_size: self.dynamic_memory_offset_guard_size,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,11 +113,7 @@ impl Tunables for BaseTunables {
|
|||||||
style: &MemoryStyle,
|
style: &MemoryStyle,
|
||||||
vm_definition_location: NonNull<VMMemoryDefinition>,
|
vm_definition_location: NonNull<VMMemoryDefinition>,
|
||||||
) -> Result<Arc<dyn Memory>, MemoryError> {
|
) -> Result<Arc<dyn Memory>, MemoryError> {
|
||||||
Ok(Arc::new(LinearMemory::from_definition(
|
Ok(Arc::new(LinearMemory::from_definition(&ty, &style, vm_definition_location)?))
|
||||||
&ty,
|
|
||||||
&style,
|
|
||||||
vm_definition_location,
|
|
||||||
)?))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
|
/// Create a table owned by the host given a [`TableType`] and a [`TableStyle`].
|
||||||
@@ -142,11 +136,7 @@ impl Tunables for BaseTunables {
|
|||||||
style: &TableStyle,
|
style: &TableStyle,
|
||||||
vm_definition_location: NonNull<VMTableDefinition>,
|
vm_definition_location: NonNull<VMTableDefinition>,
|
||||||
) -> Result<Arc<dyn Table>, String> {
|
) -> Result<Arc<dyn Table>, String> {
|
||||||
Ok(Arc::new(LinearTable::from_definition(
|
Ok(Arc::new(LinearTable::from_definition(&ty, &style, vm_definition_location)?))
|
||||||
&ty,
|
|
||||||
&style,
|
|
||||||
vm_definition_location,
|
|
||||||
)?))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,10 +172,7 @@ mod tests {
|
|||||||
let requested = MemoryType::new(3, Some(16), true);
|
let requested = MemoryType::new(3, Some(16), true);
|
||||||
let style = tunables.memory_style(&requested);
|
let style = tunables.memory_style(&requested);
|
||||||
match style {
|
match style {
|
||||||
MemoryStyle::Static {
|
MemoryStyle::Static { bound, offset_guard_size } => {
|
||||||
bound,
|
|
||||||
offset_guard_size,
|
|
||||||
} => {
|
|
||||||
assert_eq!(bound, Pages(2048));
|
assert_eq!(bound, Pages(2048));
|
||||||
assert_eq!(offset_guard_size, 128);
|
assert_eq!(offset_guard_size, 128);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,10 +66,8 @@ impl ValFuncRef for Val {
|
|||||||
let anyfunc: *const wasmer_vm::VMCallerCheckedAnyfunc = *func_ref;
|
let anyfunc: *const wasmer_vm::VMCallerCheckedAnyfunc = *func_ref;
|
||||||
&*anyfunc
|
&*anyfunc
|
||||||
};
|
};
|
||||||
let signature = store
|
let signature =
|
||||||
.engine()
|
store.engine().lookup_signature(item.type_index).expect("Signature not found in store");
|
||||||
.lookup_signature(item.type_index)
|
|
||||||
.expect("Signature not found in store");
|
|
||||||
let export = wasmer_engine::ExportFunction {
|
let export = wasmer_engine::ExportFunction {
|
||||||
// TODO:
|
// TODO:
|
||||||
// figure out if we ever need a value here: need testing with complicated import patterns
|
// figure out if we ever need a value here: need testing with complicated import patterns
|
||||||
|
|||||||
@@ -5,22 +5,10 @@ use wasmer::*;
|
|||||||
fn global_new() -> Result<()> {
|
fn global_new() -> Result<()> {
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
let global = Global::new(&store, Value::I32(10));
|
let global = Global::new(&store, Value::I32(10));
|
||||||
assert_eq!(
|
assert_eq!(*global.ty(), GlobalType { ty: Type::I32, mutability: Mutability::Const });
|
||||||
*global.ty(),
|
|
||||||
GlobalType {
|
|
||||||
ty: Type::I32,
|
|
||||||
mutability: Mutability::Const,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let global_mut = Global::new_mut(&store, Value::I32(10));
|
let global_mut = Global::new_mut(&store, Value::I32(10));
|
||||||
assert_eq!(
|
assert_eq!(*global_mut.ty(), GlobalType { ty: Type::I32, mutability: Mutability::Var });
|
||||||
*global_mut.ty(),
|
|
||||||
GlobalType {
|
|
||||||
ty: Type::I32,
|
|
||||||
mutability: Mutability::Var,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -61,11 +49,7 @@ fn global_set() -> Result<()> {
|
|||||||
#[test]
|
#[test]
|
||||||
fn table_new() -> Result<()> {
|
fn table_new() -> Result<()> {
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
let table_type = TableType {
|
let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: None };
|
||||||
ty: Type::FuncRef,
|
|
||||||
minimum: 0,
|
|
||||||
maximum: None,
|
|
||||||
};
|
|
||||||
let f = Function::new_native(&store, || {});
|
let f = Function::new_native(&store, || {});
|
||||||
let table = Table::new(&store, table_type, Value::FuncRef(Some(f)))?;
|
let table = Table::new(&store, table_type, Value::FuncRef(Some(f)))?;
|
||||||
assert_eq!(*table.ty(), table_type);
|
assert_eq!(*table.ty(), table_type);
|
||||||
@@ -86,11 +70,7 @@ fn table_new() -> Result<()> {
|
|||||||
#[ignore]
|
#[ignore]
|
||||||
fn table_get() -> Result<()> {
|
fn table_get() -> Result<()> {
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
let table_type = TableType {
|
let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: Some(1) };
|
||||||
ty: Type::FuncRef,
|
|
||||||
minimum: 0,
|
|
||||||
maximum: Some(1),
|
|
||||||
};
|
|
||||||
let f = Function::new_native(&store, |num: i32| num + 1);
|
let f = Function::new_native(&store, |num: i32| num + 1);
|
||||||
let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
|
let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
|
||||||
assert_eq!(*table.ty(), table_type);
|
assert_eq!(*table.ty(), table_type);
|
||||||
@@ -109,11 +89,7 @@ fn table_set() -> Result<()> {
|
|||||||
#[test]
|
#[test]
|
||||||
fn table_grow() -> Result<()> {
|
fn table_grow() -> Result<()> {
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
let table_type = TableType {
|
let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: Some(10) };
|
||||||
ty: Type::FuncRef,
|
|
||||||
minimum: 0,
|
|
||||||
maximum: Some(10),
|
|
||||||
};
|
|
||||||
let f = Function::new_native(&store, |num: i32| num + 1);
|
let f = Function::new_native(&store, |num: i32| num + 1);
|
||||||
let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
|
let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?;
|
||||||
// Growing to a bigger maximum should return None
|
// Growing to a bigger maximum should return None
|
||||||
@@ -137,11 +113,7 @@ fn table_copy() -> Result<()> {
|
|||||||
#[test]
|
#[test]
|
||||||
fn memory_new() -> Result<()> {
|
fn memory_new() -> Result<()> {
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
let memory_type = MemoryType {
|
let memory_type = MemoryType { shared: false, minimum: Pages(0), maximum: Some(Pages(10)) };
|
||||||
shared: false,
|
|
||||||
minimum: Pages(0),
|
|
||||||
maximum: Some(Pages(10)),
|
|
||||||
};
|
|
||||||
let memory = Memory::new(&store, memory_type)?;
|
let memory = Memory::new(&store, memory_type)?;
|
||||||
assert_eq!(memory.size(), Pages(0));
|
assert_eq!(memory.size(), Pages(0));
|
||||||
assert_eq!(*memory.ty(), memory_type);
|
assert_eq!(*memory.ty(), memory_type);
|
||||||
@@ -163,10 +135,7 @@ fn memory_grow() -> Result<()> {
|
|||||||
let result = memory.grow(Pages(10));
|
let result = memory.grow(Pages(10));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result,
|
result,
|
||||||
Err(MemoryError::CouldNotGrow {
|
Err(MemoryError::CouldNotGrow { current: 12.into(), attempted_delta: 10.into() })
|
||||||
current: 12.into(),
|
|
||||||
attempted_delta: 10.into(),
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let bad_desc = MemoryType::new(Pages(15), Some(Pages(10)), false);
|
let bad_desc = MemoryType::new(Pages(15), Some(Pages(10)), false);
|
||||||
@@ -183,20 +152,14 @@ fn function_new() -> Result<()> {
|
|||||||
let function = Function::new_native(&store, || {});
|
let function = Function::new_native(&store, || {});
|
||||||
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
|
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
|
||||||
let function = Function::new_native(&store, |_a: i32| {});
|
let function = Function::new_native(&store, |_a: i32| {});
|
||||||
assert_eq!(
|
assert_eq!(function.ty().clone(), FunctionType::new(vec![Type::I32], vec![]));
|
||||||
function.ty().clone(),
|
|
||||||
FunctionType::new(vec![Type::I32], vec![])
|
|
||||||
);
|
|
||||||
let function = Function::new_native(&store, |_a: i32, _b: i64, _c: f32, _d: f64| {});
|
let function = Function::new_native(&store, |_a: i32, _b: i64, _c: f32, _d: f64| {});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
function.ty().clone(),
|
function.ty().clone(),
|
||||||
FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![])
|
FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![])
|
||||||
);
|
);
|
||||||
let function = Function::new_native(&store, || -> i32 { 1 });
|
let function = Function::new_native(&store, || -> i32 { 1 });
|
||||||
assert_eq!(
|
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![Type::I32]));
|
||||||
function.ty().clone(),
|
|
||||||
FunctionType::new(vec![], vec![Type::I32])
|
|
||||||
);
|
|
||||||
let function = Function::new_native(&store, || -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) });
|
let function = Function::new_native(&store, || -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) });
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
function.ty().clone(),
|
function.ty().clone(),
|
||||||
@@ -216,10 +179,7 @@ fn function_new_env() -> Result<()> {
|
|||||||
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
|
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![]));
|
||||||
let function =
|
let function =
|
||||||
Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv, _a: i32| {});
|
Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv, _a: i32| {});
|
||||||
assert_eq!(
|
assert_eq!(function.ty().clone(), FunctionType::new(vec![Type::I32], vec![]));
|
||||||
function.ty().clone(),
|
|
||||||
FunctionType::new(vec![Type::I32], vec![])
|
|
||||||
);
|
|
||||||
let function = Function::new_native_with_env(
|
let function = Function::new_native_with_env(
|
||||||
&store,
|
&store,
|
||||||
my_env.clone(),
|
my_env.clone(),
|
||||||
@@ -231,10 +191,7 @@ fn function_new_env() -> Result<()> {
|
|||||||
);
|
);
|
||||||
let function =
|
let function =
|
||||||
Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv| -> i32 { 1 });
|
Function::new_native_with_env(&store, my_env.clone(), |_env: &MyEnv| -> i32 { 1 });
|
||||||
assert_eq!(
|
assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![Type::I32]));
|
||||||
function.ty().clone(),
|
|
||||||
FunctionType::new(vec![], vec![Type::I32])
|
|
||||||
);
|
|
||||||
let function = Function::new_native_with_env(
|
let function = Function::new_native_with_env(
|
||||||
&store,
|
&store,
|
||||||
my_env.clone(),
|
my_env.clone(),
|
||||||
@@ -413,10 +370,7 @@ fn manually_generate_wasmer_env() -> Result<()> {
|
|||||||
env.val + arg1 + arg2
|
env.val + arg1 + arg2
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut env = MyEnv {
|
let mut env = MyEnv { val: 5, memory: LazyInit::new() };
|
||||||
val: 5,
|
|
||||||
memory: LazyInit::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = host_function(&mut env, 7, 9);
|
let result = host_function(&mut env, 7, 9);
|
||||||
assert_eq!(result, 21);
|
assert_eq!(result, 21);
|
||||||
|
|||||||
@@ -30,10 +30,7 @@ fn exports_work_after_multiple_instances_have_been_freed() -> Result<()> {
|
|||||||
drop(instance3);
|
drop(instance3);
|
||||||
|
|
||||||
// All instances have been dropped, but `sum` continues to work!
|
// All instances have been dropped, but `sum` continues to work!
|
||||||
assert_eq!(
|
assert_eq!(sum.call(&[Value::I32(1), Value::I32(2)])?.into_vec(), vec![Value::I32(3)],);
|
||||||
sum.call(&[Value::I32(1), Value::I32(2)])?.into_vec(),
|
|
||||||
vec![Value::I32(3)],
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,35 +63,19 @@ fn imports() -> Result<()> {
|
|||||||
// Now we test the iterators
|
// Now we test the iterators
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.imports().functions().collect::<Vec<_>>(),
|
module.imports().functions().collect::<Vec<_>>(),
|
||||||
vec![ImportType::new(
|
vec![ImportType::new("host", "func", FunctionType::new(vec![], vec![])),]
|
||||||
"host",
|
|
||||||
"func",
|
|
||||||
FunctionType::new(vec![], vec![])
|
|
||||||
),]
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.imports().memories().collect::<Vec<_>>(),
|
module.imports().memories().collect::<Vec<_>>(),
|
||||||
vec![ImportType::new(
|
vec![ImportType::new("host", "memory", MemoryType::new(Pages(1), None, false)),]
|
||||||
"host",
|
|
||||||
"memory",
|
|
||||||
MemoryType::new(Pages(1), None, false)
|
|
||||||
),]
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.imports().tables().collect::<Vec<_>>(),
|
module.imports().tables().collect::<Vec<_>>(),
|
||||||
vec![ImportType::new(
|
vec![ImportType::new("host", "table", TableType::new(Type::FuncRef, 1, None)),]
|
||||||
"host",
|
|
||||||
"table",
|
|
||||||
TableType::new(Type::FuncRef, 1, None)
|
|
||||||
),]
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.imports().globals().collect::<Vec<_>>(),
|
module.imports().globals().collect::<Vec<_>>(),
|
||||||
vec![ImportType::new(
|
vec![ImportType::new("host", "global", GlobalType::new(Type::I32, Mutability::Const)),]
|
||||||
"host",
|
|
||||||
"global",
|
|
||||||
GlobalType::new(Type::I32, Mutability::Const)
|
|
||||||
),]
|
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -109,18 +93,9 @@ fn exports() -> Result<()> {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.exports().collect::<Vec<_>>(),
|
module.exports().collect::<Vec<_>>(),
|
||||||
vec![
|
vec![
|
||||||
ExportType::new(
|
ExportType::new("func", ExternType::Function(FunctionType::new(vec![], vec![]))),
|
||||||
"func",
|
ExportType::new("memory", ExternType::Memory(MemoryType::new(Pages(1), None, false))),
|
||||||
ExternType::Function(FunctionType::new(vec![], vec![]))
|
ExportType::new("table", ExternType::Table(TableType::new(Type::FuncRef, 1, None))),
|
||||||
),
|
|
||||||
ExportType::new(
|
|
||||||
"memory",
|
|
||||||
ExternType::Memory(MemoryType::new(Pages(1), None, false))
|
|
||||||
),
|
|
||||||
ExportType::new(
|
|
||||||
"table",
|
|
||||||
ExternType::Table(TableType::new(Type::FuncRef, 1, None))
|
|
||||||
),
|
|
||||||
ExportType::new(
|
ExportType::new(
|
||||||
"global",
|
"global",
|
||||||
ExternType::Global(GlobalType::new(Type::I32, Mutability::Const))
|
ExternType::Global(GlobalType::new(Type::I32, Mutability::Const))
|
||||||
@@ -135,24 +110,15 @@ fn exports() -> Result<()> {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.exports().memories().collect::<Vec<_>>(),
|
module.exports().memories().collect::<Vec<_>>(),
|
||||||
vec![ExportType::new(
|
vec![ExportType::new("memory", MemoryType::new(Pages(1), None, false)),]
|
||||||
"memory",
|
|
||||||
MemoryType::new(Pages(1), None, false)
|
|
||||||
),]
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.exports().tables().collect::<Vec<_>>(),
|
module.exports().tables().collect::<Vec<_>>(),
|
||||||
vec![ExportType::new(
|
vec![ExportType::new("table", TableType::new(Type::FuncRef, 1, None)),]
|
||||||
"table",
|
|
||||||
TableType::new(Type::FuncRef, 1, None)
|
|
||||||
),]
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
module.exports().globals().collect::<Vec<_>>(),
|
module.exports().globals().collect::<Vec<_>>(),
|
||||||
vec![ExportType::new(
|
vec![ExportType::new("global", GlobalType::new(Type::I32, Mutability::Const)),]
|
||||||
"global",
|
|
||||||
GlobalType::new(Type::I32, Mutability::Const)
|
|
||||||
),]
|
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,9 +112,8 @@ fn func_ref_passed_and_called() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let f: NativeFunc<(), i32> = instance
|
let f: NativeFunc<(), i32> =
|
||||||
.exports
|
instance.exports.get_native_function("call_host_func_with_wasm_func")?;
|
||||||
.get_native_function("call_host_func_with_wasm_func")?;
|
|
||||||
let result = f.call()?;
|
let result = f.call()?;
|
||||||
assert_eq!(result, 63);
|
assert_eq!(result, 63);
|
||||||
}
|
}
|
||||||
@@ -415,12 +414,10 @@ fn extern_ref_ref_counting_table_instructions() -> Result<()> {
|
|||||||
let module = Module::new(&store, wat)?;
|
let module = Module::new(&store, wat)?;
|
||||||
let instance = Instance::new(&module, &imports! {})?;
|
let instance = Instance::new(&module, &imports! {})?;
|
||||||
|
|
||||||
let grow_table_with_ref: NativeFunc<(ExternRef, i32), i32> = instance
|
let grow_table_with_ref: NativeFunc<(ExternRef, i32), i32> =
|
||||||
.exports
|
instance.exports.get_native_function("grow_table_with_ref")?;
|
||||||
.get_native_function("grow_table_with_ref")?;
|
let fill_table_with_ref: NativeFunc<(ExternRef, i32, i32), ()> =
|
||||||
let fill_table_with_ref: NativeFunc<(ExternRef, i32, i32), ()> = instance
|
instance.exports.get_native_function("fill_table_with_ref")?;
|
||||||
.exports
|
|
||||||
.get_native_function("fill_table_with_ref")?;
|
|
||||||
let copy_into_table2: NativeFunc<(), ()> =
|
let copy_into_table2: NativeFunc<(), ()> =
|
||||||
instance.exports.get_native_function("copy_into_table2")?;
|
instance.exports.get_native_function("copy_into_table2")?;
|
||||||
let table1: &Table = instance.exports.get_table("table1")?;
|
let table1: &Table = instance.exports.get_table("table1")?;
|
||||||
|
|||||||
@@ -142,9 +142,8 @@ pub unsafe extern "C" fn wasmer_export_descriptors(
|
|||||||
) {
|
) {
|
||||||
let module = &*(module as *const Module);
|
let module = &*(module as *const Module);
|
||||||
|
|
||||||
let named_export_descriptors: Box<NamedExportDescriptors> = Box::new(NamedExportDescriptors(
|
let named_export_descriptors: Box<NamedExportDescriptors> =
|
||||||
module.exports().into_iter().map(|e| e.into()).collect(),
|
Box::new(NamedExportDescriptors(module.exports().into_iter().map(|e| e.into()).collect()));
|
||||||
));
|
|
||||||
*export_descriptors =
|
*export_descriptors =
|
||||||
Box::into_raw(named_export_descriptors) as *mut wasmer_export_descriptors_t;
|
Box::into_raw(named_export_descriptors) as *mut wasmer_export_descriptors_t;
|
||||||
}
|
}
|
||||||
@@ -403,10 +402,8 @@ pub unsafe extern "C" fn wasmer_export_to_memory(
|
|||||||
let named_export = &*(export as *const NamedExport);
|
let named_export = &*(export as *const NamedExport);
|
||||||
let instance = named_export.instance.as_ref();
|
let instance = named_export.instance.as_ref();
|
||||||
|
|
||||||
if let Ok(exported_memory) = instance
|
if let Ok(exported_memory) =
|
||||||
.instance
|
instance.instance.exports.get::<Memory>(&named_export.export_type.name())
|
||||||
.exports
|
|
||||||
.get::<Memory>(&named_export.export_type.name())
|
|
||||||
{
|
{
|
||||||
let mem = Box::new(exported_memory.clone());
|
let mem = Box::new(exported_memory.clone());
|
||||||
*memory = Box::into_raw(mem) as *mut wasmer_memory_t;
|
*memory = Box::into_raw(mem) as *mut wasmer_memory_t;
|
||||||
@@ -449,16 +446,12 @@ pub unsafe extern "C" fn wasmer_export_func_call(
|
|||||||
results_len: c_uint,
|
results_len: c_uint,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
if func.is_null() {
|
if func.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "func ptr is null".to_string() });
|
||||||
msg: "func ptr is null".to_string(),
|
|
||||||
});
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if params_len > 0 && params.is_null() {
|
if params_len > 0 && params.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "params ptr is null".to_string() });
|
||||||
msg: "params ptr is null".to_string(),
|
|
||||||
});
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
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 results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
|
||||||
|
|
||||||
let instance = named_export.instance.as_ref();
|
let instance = named_export.instance.as_ref();
|
||||||
let f: &Function = match instance
|
let f: &Function = match instance.instance.exports.get(&named_export.export_type.name()) {
|
||||||
.instance
|
|
||||||
.exports
|
|
||||||
.get(&named_export.export_type.name())
|
|
||||||
{
|
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
update_last_error(err);
|
update_last_error(err);
|
||||||
@@ -530,10 +519,7 @@ pub unsafe extern "C" fn wasmer_export_func_call(
|
|||||||
|
|
||||||
impl From<ExportType> for NamedExportDescriptor {
|
impl From<ExportType> for NamedExportDescriptor {
|
||||||
fn from(et: ExportType) -> Self {
|
fn from(et: ExportType) -> Self {
|
||||||
NamedExportDescriptor {
|
NamedExportDescriptor { name: et.name().to_string(), kind: et.into() }
|
||||||
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 {
|
) -> wasmer_global_descriptor_t {
|
||||||
let global = &*(global as *mut Global);
|
let global = &*(global as *mut Global);
|
||||||
let descriptor = global.ty();
|
let descriptor = global.ty();
|
||||||
wasmer_global_descriptor_t {
|
wasmer_global_descriptor_t { mutable: descriptor.mutability.into(), kind: descriptor.ty.into() }
|
||||||
mutable: descriptor.mutability.into(),
|
|
||||||
kind: descriptor.ty.into(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Frees memory for the given Global
|
/// 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 {
|
let mut import_object_iter = if let Some(import_object_iter) = import_object_iter {
|
||||||
import_object_iter.cast::<WasmerImportObjectIterator>()
|
import_object_iter.cast::<WasmerImportObjectIterator>()
|
||||||
} else {
|
} else {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "import_object_iter must not be null".to_owned() });
|
||||||
msg: "import_object_iter must not be null".to_owned(),
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
let iter = import_object_iter.as_mut();
|
let iter = import_object_iter.as_mut();
|
||||||
@@ -359,11 +357,7 @@ pub unsafe extern "C" fn wasmer_import_object_iter_destroy(
|
|||||||
import_object_iter: Option<NonNull<wasmer_import_object_iter_t>>,
|
import_object_iter: Option<NonNull<wasmer_import_object_iter_t>>,
|
||||||
) {
|
) {
|
||||||
if let Some(import_object_iter) = import_object_iter {
|
if let Some(import_object_iter) = import_object_iter {
|
||||||
let _ = Box::from_raw(
|
let _ = Box::from_raw(import_object_iter.cast::<WasmerImportObjectIterator>().as_ptr());
|
||||||
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 mut import_data: HashMap<String, Exports> = HashMap::new();
|
||||||
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
||||||
for import in imports {
|
for import in imports {
|
||||||
let module_name = slice::from_raw_parts(
|
let module_name =
|
||||||
import.module_name.bytes,
|
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize);
|
||||||
import.module_name.bytes_len as usize,
|
|
||||||
);
|
|
||||||
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
||||||
s
|
s
|
||||||
} else {
|
} else {
|
||||||
@@ -438,10 +430,8 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
});
|
});
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
};
|
};
|
||||||
let import_name = slice::from_raw_parts(
|
let import_name =
|
||||||
import.import_name.bytes,
|
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize);
|
||||||
import.import_name.bytes_len as usize,
|
|
||||||
);
|
|
||||||
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
||||||
s
|
s
|
||||||
} else {
|
} else {
|
||||||
@@ -461,9 +451,7 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
// TODO: investigate consistent usage of `FunctionWrapper` in this context
|
// TODO: investigate consistent usage of `FunctionWrapper` in this context
|
||||||
let func_wrapper = import.value.func as *mut FunctionWrapper;
|
let func_wrapper = import.value.func as *mut FunctionWrapper;
|
||||||
let func_export = (*func_wrapper).func.as_ptr();
|
let func_export = (*func_wrapper).func.as_ptr();
|
||||||
import_object
|
import_object.instance_pointers_to_update.push((*func_wrapper).legacy_env.clone());
|
||||||
.instance_pointers_to_update
|
|
||||||
.push((*func_wrapper).legacy_env.clone());
|
|
||||||
Extern::Function((&*func_export).clone())
|
Extern::Function((&*func_export).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||||
@@ -476,9 +464,7 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let export_entry = import_data
|
let export_entry = import_data.entry(module_name.to_string()).or_insert_with(Exports::new);
|
||||||
.entry(module_name.to_string())
|
|
||||||
.or_insert_with(Exports::new);
|
|
||||||
export_entry.insert(import_name.to_string(), export);
|
export_entry.insert(import_name.to_string(), export);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,9 +632,7 @@ unsafe impl Sync for LegacyEnv {}
|
|||||||
|
|
||||||
impl LegacyEnv {
|
impl LegacyEnv {
|
||||||
pub(crate) fn ctx_ptr(&self) -> *mut CAPIInstance {
|
pub(crate) fn ctx_ptr(&self) -> *mut CAPIInstance {
|
||||||
self.instance_ptr
|
self.instance_ptr.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut())
|
||||||
.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,
|
error_message: *const c_char,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
if error_message.is_null() {
|
if error_message.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "error_message is null in wasmer_trap".to_string() });
|
||||||
msg: "error_message is null in wasmer_trap".to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
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 mut wasi_state_builder = wasi::WasiState::new("wasmer-wasi-default-program-name");
|
||||||
let wasi_state = wasi_state_builder.build().unwrap();
|
let wasi_state = wasi_state_builder.build().unwrap();
|
||||||
let wasi_env = wasi::WasiEnv::new(wasi_state);
|
let wasi_env = wasi::WasiEnv::new(wasi_state);
|
||||||
let import_object_inner: Box<dyn NamedResolver> = Box::new(
|
let import_object_inner: Box<dyn NamedResolver> =
|
||||||
wasi::generate_import_object_from_env(store, wasi_env, wasi::WasiVersion::Latest),
|
Box::new(wasi::generate_import_object_from_env(store, wasi_env, wasi::WasiVersion::Latest));
|
||||||
);
|
|
||||||
let import_object: Box<CAPIImportObject> = Box::new(CAPIImportObject {
|
let import_object: Box<CAPIImportObject> = Box::new(CAPIImportObject {
|
||||||
import_object: import_object_inner,
|
import_object: import_object_inner,
|
||||||
imported_memories: vec![],
|
imported_memories: vec![],
|
||||||
|
|||||||
@@ -124,34 +124,25 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
|||||||
let wasm_bytes = if let Some(wasm_bytes_inner) = wasm_bytes {
|
let wasm_bytes = if let Some(wasm_bytes_inner) = wasm_bytes {
|
||||||
wasm_bytes_inner
|
wasm_bytes_inner
|
||||||
} else {
|
} else {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "wasm bytes ptr is null".to_string() });
|
||||||
msg: "wasm bytes ptr is null".to_string(),
|
|
||||||
});
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
if imports_len > 0 && imports.is_null() {
|
if imports_len > 0 && imports.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "imports ptr is null".to_string() });
|
||||||
msg: "imports ptr is null".to_string(),
|
|
||||||
});
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut imported_memories = vec![];
|
let mut imported_memories = vec![];
|
||||||
let mut instance_pointers_to_update = vec![];
|
let mut instance_pointers_to_update = vec![];
|
||||||
let imports: &[wasmer_import_t] = if imports_len == 0 {
|
let imports: &[wasmer_import_t] =
|
||||||
&[]
|
if imports_len == 0 { &[] } else { slice::from_raw_parts(imports, imports_len as usize) };
|
||||||
} else {
|
|
||||||
slice::from_raw_parts(imports, imports_len as usize)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut import_object = ImportObject::new();
|
let mut import_object = ImportObject::new();
|
||||||
let mut namespaces = HashMap::new();
|
let mut namespaces = HashMap::new();
|
||||||
for import in imports {
|
for import in imports {
|
||||||
let module_name = slice::from_raw_parts(
|
let module_name =
|
||||||
import.module_name.bytes,
|
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize);
|
||||||
import.module_name.bytes_len as usize,
|
|
||||||
);
|
|
||||||
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
||||||
s
|
s
|
||||||
} else {
|
} else {
|
||||||
@@ -160,10 +151,8 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
|||||||
});
|
});
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
};
|
};
|
||||||
let import_name = slice::from_raw_parts(
|
let import_name =
|
||||||
import.import_name.bytes,
|
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize);
|
||||||
import.import_name.bytes_len as usize,
|
|
||||||
);
|
|
||||||
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
||||||
s
|
s
|
||||||
} else {
|
} else {
|
||||||
@@ -223,11 +212,7 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
|||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let c_api_instance = CAPIInstance {
|
let c_api_instance = CAPIInstance { instance: new_instance, imported_memories, ctx_data: None };
|
||||||
instance: new_instance,
|
|
||||||
imported_memories,
|
|
||||||
ctx_data: None,
|
|
||||||
};
|
|
||||||
let c_api_instance_pointer = Box::into_raw(Box::new(c_api_instance));
|
let c_api_instance_pointer = Box::into_raw(Box::new(c_api_instance));
|
||||||
for to_update in instance_pointers_to_update {
|
for to_update in instance_pointers_to_update {
|
||||||
let mut to_update_guard = to_update.lock().unwrap();
|
let mut to_update_guard = to_update.lock().unwrap();
|
||||||
@@ -322,25 +307,19 @@ pub unsafe extern "C" fn wasmer_instance_call(
|
|||||||
results_len: u32,
|
results_len: u32,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
if instance.is_null() {
|
if instance.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "instance ptr is null".to_string() });
|
||||||
msg: "instance ptr is null".to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.is_null() {
|
if name.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "name ptr is null".to_string() });
|
||||||
msg: "name ptr is null".to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if params_len > 0 && params.is_null() {
|
if params_len > 0 && params.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "params ptr is null".to_string() });
|
||||||
msg: "params ptr is null".to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
@@ -469,10 +448,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
|||||||
.instance
|
.instance
|
||||||
.module()
|
.module()
|
||||||
.exports()
|
.exports()
|
||||||
.map(|export_type| NamedExport {
|
.map(|export_type| NamedExport { export_type, instance })
|
||||||
export_type,
|
|
||||||
instance,
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let named_exports: Box<NamedExports> = Box::new(NamedExports(exports_vec));
|
let named_exports: Box<NamedExports> = Box::new(NamedExports(exports_vec));
|
||||||
@@ -578,19 +554,13 @@ pub unsafe extern "C" fn wasmer_instance_context_memory(
|
|||||||
{
|
{
|
||||||
name
|
name
|
||||||
} else {
|
} else {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "Could not find an exported memory".to_string() });
|
||||||
msg: "Could not find an exported memory".to_string(),
|
|
||||||
});
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let memory = instance
|
let memory = instance.instance.exports.get_memory(exported_memory_name).expect(&format!(
|
||||||
.instance
|
"Module exports memory named `{}` but it's inaccessible",
|
||||||
.exports
|
&exported_memory_name
|
||||||
.get_memory(exported_memory_name)
|
));
|
||||||
.expect(&format!(
|
|
||||||
"Module exports memory named `{}` but it's inaccessible",
|
|
||||||
&exported_memory_name
|
|
||||||
));
|
|
||||||
Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t))
|
Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,11 +60,7 @@ pub unsafe extern "C" fn wasmer_memory_new(
|
|||||||
memory: *mut *mut wasmer_memory_t,
|
memory: *mut *mut wasmer_memory_t,
|
||||||
limits: wasmer_limits_t,
|
limits: wasmer_limits_t,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
let max = if limits.max.has_some {
|
let max = if limits.max.has_some { Some(Pages(limits.max.some)) } else { None };
|
||||||
Some(Pages(limits.max.some))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let store = get_global_store();
|
let store = get_global_store();
|
||||||
let desc = MemoryType::new(Pages(limits.min), max, false);
|
let desc = MemoryType::new(Pages(limits.min), max, false);
|
||||||
match Memory::new(store, desc) {
|
match Memory::new(store, desc) {
|
||||||
@@ -73,9 +69,7 @@ pub unsafe extern "C" fn wasmer_memory_new(
|
|||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: err.to_string() });
|
||||||
msg: err.to_string(),
|
|
||||||
});
|
|
||||||
wasmer_result_t::WASMER_ERROR
|
wasmer_result_t::WASMER_ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,9 +95,7 @@ pub unsafe extern "C" fn wasmer_memory_new(
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -> wasmer_result_t {
|
pub extern "C" fn wasmer_memory_grow(memory: *mut wasmer_memory_t, delta: u32) -> wasmer_result_t {
|
||||||
if memory.is_null() {
|
if memory.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "`memory` is NULL.".to_string() });
|
||||||
msg: "`memory` is NULL.".to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
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 {
|
match grow_result {
|
||||||
Ok(_) => wasmer_result_t::WASMER_OK,
|
Ok(_) => wasmer_result_t::WASMER_OK,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: err.to_string() });
|
||||||
msg: err.to_string(),
|
|
||||||
});
|
|
||||||
wasmer_result_t::WASMER_ERROR
|
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 import_object = ImportObject::new();
|
||||||
let mut namespaces = HashMap::new();
|
let mut namespaces = HashMap::new();
|
||||||
for import in imports {
|
for import in imports {
|
||||||
let module_name = slice::from_raw_parts(
|
let module_name =
|
||||||
import.module_name.bytes,
|
slice::from_raw_parts(import.module_name.bytes, import.module_name.bytes_len as usize);
|
||||||
import.module_name.bytes_len as usize,
|
|
||||||
);
|
|
||||||
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
let module_name = if let Ok(s) = std::str::from_utf8(module_name) {
|
||||||
s
|
s
|
||||||
} else {
|
} else {
|
||||||
@@ -104,10 +102,8 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
|||||||
});
|
});
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
};
|
};
|
||||||
let import_name = slice::from_raw_parts(
|
let import_name =
|
||||||
import.import_name.bytes,
|
slice::from_raw_parts(import.import_name.bytes, import.import_name.bytes_len as usize);
|
||||||
import.import_name.bytes_len as usize,
|
|
||||||
);
|
|
||||||
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
let import_name = if let Ok(s) = std::str::from_utf8(import_name) {
|
||||||
s
|
s
|
||||||
} else {
|
} else {
|
||||||
@@ -153,11 +149,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let c_api_instance = CAPIInstance {
|
let c_api_instance = CAPIInstance { instance: new_instance, imported_memories, ctx_data: None };
|
||||||
instance: new_instance,
|
|
||||||
imported_memories,
|
|
||||||
ctx_data: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
|
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
|
||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
@@ -224,9 +216,7 @@ pub unsafe extern "C" fn wasmer_module_serialize(
|
|||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "Failed to serialize the module".to_string() });
|
||||||
msg: "Failed to serialize the module".to_string(),
|
|
||||||
});
|
|
||||||
wasmer_result_t::WASMER_ERROR
|
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;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
let serialized_module_bytes: &[u8] = slice::from_raw_parts(
|
let serialized_module_bytes: &[u8] =
|
||||||
serialized_module_bytes,
|
slice::from_raw_parts(serialized_module_bytes, serialized_module_bytes_length as usize);
|
||||||
serialized_module_bytes_length as usize,
|
|
||||||
);
|
|
||||||
|
|
||||||
*serialized_module = Box::into_raw(Box::new(serialized_module_bytes)) as _;
|
*serialized_module = Box::into_raw(Box::new(serialized_module_bytes)) as _;
|
||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
@@ -293,9 +281,7 @@ pub unsafe extern "C" fn wasmer_module_deserialize(
|
|||||||
let serialized_module: &[u8] = if let Some(sm) = serialized_module {
|
let serialized_module: &[u8] = if let Some(sm) = serialized_module {
|
||||||
&*(sm as *const wasmer_serialized_module_t as *const &[u8])
|
&*(sm as *const wasmer_serialized_module_t as *const &[u8])
|
||||||
} else {
|
} else {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: "`serialized_module` pointer is null".to_string() });
|
||||||
msg: "`serialized_module` pointer is null".to_string(),
|
|
||||||
});
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,16 +36,8 @@ pub unsafe extern "C" fn wasmer_table_new(
|
|||||||
table: *mut *mut wasmer_table_t,
|
table: *mut *mut wasmer_table_t,
|
||||||
limits: wasmer_limits_t,
|
limits: wasmer_limits_t,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
let max = if limits.max.has_some {
|
let max = if limits.max.has_some { Some(limits.max.some) } else { None };
|
||||||
Some(limits.max.some)
|
let desc = TableType { ty: ValType::FuncRef, minimum: limits.min, maximum: max };
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let desc = TableType {
|
|
||||||
ty: ValType::FuncRef,
|
|
||||||
minimum: limits.min,
|
|
||||||
maximum: max,
|
|
||||||
};
|
|
||||||
let store = get_global_store();
|
let store = get_global_store();
|
||||||
let result = Table::new(store, desc, get_default_table_value(ValType::FuncRef));
|
let result = Table::new(store, desc, get_default_table_value(ValType::FuncRef));
|
||||||
let new_table = match result {
|
let new_table = match result {
|
||||||
|
|||||||
@@ -74,22 +74,18 @@ impl From<wasmer_value_t> for Val {
|
|||||||
unsafe {
|
unsafe {
|
||||||
#[allow(unreachable_patterns, non_snake_case)]
|
#[allow(unreachable_patterns, non_snake_case)]
|
||||||
match v {
|
match v {
|
||||||
wasmer_value_t {
|
wasmer_value_t { tag: wasmer_value_tag::WASM_I32, value: wasmer_value { I32 } } => {
|
||||||
tag: wasmer_value_tag::WASM_I32,
|
Val::I32(I32)
|
||||||
value: wasmer_value { I32 },
|
}
|
||||||
} => Val::I32(I32),
|
wasmer_value_t { tag: wasmer_value_tag::WASM_I64, value: wasmer_value { I64 } } => {
|
||||||
wasmer_value_t {
|
Val::I64(I64)
|
||||||
tag: wasmer_value_tag::WASM_I64,
|
}
|
||||||
value: wasmer_value { I64 },
|
wasmer_value_t { tag: wasmer_value_tag::WASM_F32, value: wasmer_value { F32 } } => {
|
||||||
} => Val::I64(I64),
|
Val::F32(F32)
|
||||||
wasmer_value_t {
|
}
|
||||||
tag: wasmer_value_tag::WASM_F32,
|
wasmer_value_t { tag: wasmer_value_tag::WASM_F64, value: wasmer_value { F64 } } => {
|
||||||
value: wasmer_value { F32 },
|
Val::F64(F64)
|
||||||
} => Val::F32(F32),
|
}
|
||||||
wasmer_value_t {
|
|
||||||
tag: wasmer_value_tag::WASM_F64,
|
|
||||||
value: wasmer_value { F64 },
|
|
||||||
} => Val::F64(F64),
|
|
||||||
_ => unreachable!("unknown Wasm type"),
|
_ => unreachable!("unknown Wasm type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,22 +95,18 @@ impl From<wasmer_value_t> for Val {
|
|||||||
impl From<Val> for wasmer_value_t {
|
impl From<Val> for wasmer_value_t {
|
||||||
fn from(val: Val) -> Self {
|
fn from(val: Val) -> Self {
|
||||||
match val {
|
match val {
|
||||||
Val::I32(x) => wasmer_value_t {
|
Val::I32(x) => {
|
||||||
tag: wasmer_value_tag::WASM_I32,
|
wasmer_value_t { tag: wasmer_value_tag::WASM_I32, value: wasmer_value { I32: x } }
|
||||||
value: wasmer_value { I32: x },
|
}
|
||||||
},
|
Val::I64(x) => {
|
||||||
Val::I64(x) => wasmer_value_t {
|
wasmer_value_t { tag: wasmer_value_tag::WASM_I64, value: wasmer_value { I64: x } }
|
||||||
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::F32(x) => wasmer_value_t {
|
}
|
||||||
tag: wasmer_value_tag::WASM_F32,
|
Val::F64(x) => {
|
||||||
value: wasmer_value { F32: x },
|
wasmer_value_t { tag: wasmer_value_tag::WASM_F64, value: wasmer_value { F64: x } }
|
||||||
},
|
}
|
||||||
Val::F64(x) => wasmer_value_t {
|
|
||||||
tag: wasmer_value_tag::WASM_F64,
|
|
||||||
value: wasmer_value { F64: x },
|
|
||||||
},
|
|
||||||
Val::V128(_) => unimplemented!("V128 not supported in C API"),
|
Val::V128(_) => unimplemented!("V128 not supported in C API"),
|
||||||
Val::ExternRef(_) => unimplemented!("ExternRef not supported in C API"),
|
Val::ExternRef(_) => unimplemented!("ExternRef not supported in C API"),
|
||||||
Val::FuncRef(_) => unimplemented!("FuncRef not supported in C API"),
|
Val::FuncRef(_) => unimplemented!("FuncRef not supported in C API"),
|
||||||
|
|||||||
@@ -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);
|
let buffer = slice::from_raw_parts_mut(buffer.cast::<u8>().as_ptr(), length);
|
||||||
|
|
||||||
ptr::copy_nonoverlapping(
|
ptr::copy_nonoverlapping(error_message.as_ptr(), buffer.as_mut_ptr(), error_message.len());
|
||||||
error_message.as_ptr(),
|
|
||||||
buffer.as_mut_ptr(),
|
|
||||||
error_message.len(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add a trailing null so people using the string as a `char *` don't
|
// Add a trailing null so people using the string as a `char *` don't
|
||||||
// accidentally read into garbage.
|
// accidentally read into garbage.
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ pub struct OrderedResolver {
|
|||||||
|
|
||||||
impl Resolver for OrderedResolver {
|
impl Resolver for OrderedResolver {
|
||||||
fn resolve(&self, index: u32, _module: &str, _name: &str) -> Option<Export> {
|
fn resolve(&self, index: u32, _module: &str, _name: &str) -> Option<Export> {
|
||||||
self.externs
|
self.externs.get(index as usize).map(|extern_| extern_.to_export())
|
||||||
.get(index as usize)
|
|
||||||
.map(|extern_| extern_.to_export())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -435,9 +435,7 @@ pub extern "C" fn wasm_engine_new_with_config(
|
|||||||
where
|
where
|
||||||
M: ToString,
|
M: ToString,
|
||||||
{
|
{
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError { msg: msg.to_string() });
|
||||||
msg: msg.to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return None;
|
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 {
|
impl wasm_func_t {
|
||||||
pub(crate) fn new(function: Function) -> Self {
|
pub(crate) fn new(function: Function) -> Self {
|
||||||
Self {
|
Self { tag: CApiExternTag::Function, inner: Box::new(function) }
|
||||||
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(
|
let function = Function::new_with_env(
|
||||||
&store.inner,
|
&store.inner,
|
||||||
func_sig,
|
func_sig,
|
||||||
WrapperEnv {
|
WrapperEnv { env, env_finalizer: Arc::new(env_finalizer) },
|
||||||
env,
|
|
||||||
env_finalizer: Arc::new(env_finalizer),
|
|
||||||
},
|
|
||||||
trampoline,
|
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 {
|
impl wasm_global_t {
|
||||||
pub(crate) fn new(global: Global) -> Self {
|
pub(crate) fn new(global: Global) -> Self {
|
||||||
Self {
|
Self { tag: CApiExternTag::Global, inner: Box::new(global) }
|
||||||
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 {
|
impl wasm_memory_t {
|
||||||
pub(crate) fn new(memory: Memory) -> Self {
|
pub(crate) fn new(memory: Memory) -> Self {
|
||||||
Self {
|
Self { tag: CApiExternTag::Memory, inner: Box::new(memory) }
|
||||||
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 {
|
fn clone(&self) -> Self {
|
||||||
match self.get_tag() {
|
match self.get_tag() {
|
||||||
CApiExternTag::Function => Self {
|
CApiExternTag::Function => Self {
|
||||||
inner: wasm_extern_inner {
|
inner: wasm_extern_inner { function: unsafe { self.inner.function.clone() } },
|
||||||
function: unsafe { self.inner.function.clone() },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
CApiExternTag::Memory => Self {
|
|
||||||
inner: wasm_extern_inner {
|
|
||||||
memory: unsafe { self.inner.memory.clone() },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
CApiExternTag::Global => Self {
|
|
||||||
inner: wasm_extern_inner {
|
|
||||||
global: unsafe { self.inner.global.clone() },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
CApiExternTag::Table => Self {
|
|
||||||
inner: wasm_extern_inner {
|
|
||||||
table: unsafe { self.inner.table.clone() },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
CApiExternTag::Memory => {
|
||||||
|
Self { inner: wasm_extern_inner { memory: unsafe { self.inner.memory.clone() } } }
|
||||||
|
}
|
||||||
|
CApiExternTag::Global => {
|
||||||
|
Self { inner: wasm_extern_inner { global: unsafe { self.inner.global.clone() } } }
|
||||||
|
}
|
||||||
|
CApiExternTag::Table => {
|
||||||
|
Self { inner: wasm_extern_inner { table: unsafe { self.inner.table.clone() } } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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 {
|
impl wasm_table_t {
|
||||||
pub(crate) fn new(table: Table) -> Self {
|
pub(crate) fn new(table: Table) -> Self {
|
||||||
Self {
|
Self { tag: CApiExternTag::Table, inner: Box::new(table) }
|
||||||
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 bytes = bytes.into_slice()?;
|
||||||
let module = c_try!(Module::from_binary(&store.inner, bytes));
|
let module = c_try!(Module::from_binary(&store.inner, bytes));
|
||||||
|
|
||||||
Some(Box::new(wasm_module_t {
|
Some(Box::new(wasm_module_t { inner: Arc::new(module) }))
|
||||||
inner: Arc::new(module),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes a WebAssembly 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));
|
let module = c_try!(Module::deserialize(&store.inner, byte_slice));
|
||||||
|
|
||||||
Some(NonNull::new_unchecked(Box::into_raw(Box::new(
|
Some(NonNull::new_unchecked(Box::into_raw(Box::new(wasm_module_t { inner: Arc::new(module) }))))
|
||||||
wasm_module_t {
|
|
||||||
inner: Arc::new(module),
|
|
||||||
},
|
|
||||||
))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes a module into a binary representation that the
|
/// Serializes a module into a binary representation that the
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ pub extern "C" fn wasm_exporttype_new(
|
|||||||
extern_type: Option<Box<wasm_externtype_t>>,
|
extern_type: Option<Box<wasm_externtype_t>>,
|
||||||
) -> Option<Box<wasm_exporttype_t>> {
|
) -> Option<Box<wasm_exporttype_t>> {
|
||||||
let name = unsafe { owned_wasm_name_t::new(name?) };
|
let name = unsafe { owned_wasm_name_t::new(name?) };
|
||||||
Some(Box::new(wasm_exporttype_t {
|
Some(Box::new(wasm_exporttype_t { name, extern_type: extern_type? }))
|
||||||
name,
|
|
||||||
extern_type: extern_type?,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -13,11 +13,7 @@ impl WasmFunctionType {
|
|||||||
let params: Box<wasm_valtype_vec_t> = Box::new(function_type.params().into());
|
let params: Box<wasm_valtype_vec_t> = Box::new(function_type.params().into());
|
||||||
let results: Box<wasm_valtype_vec_t> = Box::new(function_type.results().into());
|
let results: Box<wasm_valtype_vec_t> = Box::new(function_type.results().into());
|
||||||
|
|
||||||
Self {
|
Self { function_type, params, results }
|
||||||
function_type,
|
|
||||||
params,
|
|
||||||
results,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,9 +32,7 @@ pub struct wasm_functype_t {
|
|||||||
|
|
||||||
impl wasm_functype_t {
|
impl wasm_functype_t {
|
||||||
pub(crate) fn new(function_type: FunctionType) -> Self {
|
pub(crate) fn new(function_type: FunctionType) -> Self {
|
||||||
Self {
|
Self { extern_type: wasm_externtype_t::new(ExternType::Function(function_type)) }
|
||||||
extern_type: wasm_externtype_t::new(ExternType::Function(function_type)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn inner(&self) -> &WasmFunctionType {
|
pub(crate) fn inner(&self) -> &WasmFunctionType {
|
||||||
@@ -61,24 +55,15 @@ pub unsafe extern "C" fn wasm_functype_new(
|
|||||||
let params = params?;
|
let params = params?;
|
||||||
let results = results?;
|
let results = results?;
|
||||||
|
|
||||||
let params_as_valtype: Vec<ValType> = params
|
let params_as_valtype: Vec<ValType> =
|
||||||
.into_slice()?
|
params.into_slice()?.into_iter().map(|val| val.as_ref().into()).collect::<Vec<_>>();
|
||||||
.into_iter()
|
let results_as_valtype: Vec<ValType> =
|
||||||
.map(|val| val.as_ref().into())
|
results.into_slice()?.iter().map(|val| val.as_ref().into()).collect::<Vec<_>>();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let results_as_valtype: Vec<ValType> = results
|
|
||||||
.into_slice()?
|
|
||||||
.iter()
|
|
||||||
.map(|val| val.as_ref().into())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
wasm_valtype_vec_delete(Some(params));
|
wasm_valtype_vec_delete(Some(params));
|
||||||
wasm_valtype_vec_delete(Some(results));
|
wasm_valtype_vec_delete(Some(results));
|
||||||
|
|
||||||
Some(Box::new(wasm_functype_t::new(FunctionType::new(
|
Some(Box::new(wasm_functype_t::new(FunctionType::new(params_as_valtype, results_as_valtype))))
|
||||||
params_as_valtype,
|
|
||||||
results_as_valtype,
|
|
||||||
))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ impl WasmGlobalType {
|
|||||||
pub(crate) fn new(global_type: GlobalType) -> Self {
|
pub(crate) fn new(global_type: GlobalType) -> Self {
|
||||||
let content = Box::new(global_type.ty.into());
|
let content = Box::new(global_type.ty.into());
|
||||||
|
|
||||||
Self {
|
Self { global_type, content }
|
||||||
global_type,
|
|
||||||
content,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,9 +28,7 @@ pub struct wasm_globaltype_t {
|
|||||||
|
|
||||||
impl wasm_globaltype_t {
|
impl wasm_globaltype_t {
|
||||||
pub(crate) fn new(global_type: GlobalType) -> Self {
|
pub(crate) fn new(global_type: GlobalType) -> Self {
|
||||||
Self {
|
Self { extern_type: wasm_externtype_t::new(ExternType::Global(global_type)) }
|
||||||
extern_type: wasm_externtype_t::new(ExternType::Global(global_type)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn inner(&self) -> &WasmGlobalType {
|
pub(crate) fn inner(&self) -> &WasmGlobalType {
|
||||||
@@ -55,10 +50,8 @@ pub unsafe extern "C" fn wasm_globaltype_new(
|
|||||||
) -> Option<Box<wasm_globaltype_t>> {
|
) -> Option<Box<wasm_globaltype_t>> {
|
||||||
let valtype = valtype?;
|
let valtype = valtype?;
|
||||||
let mutability: wasm_mutability_enum = mutability.try_into().ok()?;
|
let mutability: wasm_mutability_enum = mutability.try_into().ok()?;
|
||||||
let global_type = Box::new(wasm_globaltype_t::new(GlobalType::new(
|
let global_type =
|
||||||
(*valtype).into(),
|
Box::new(wasm_globaltype_t::new(GlobalType::new((*valtype).into(), mutability.into())));
|
||||||
mutability.into(),
|
|
||||||
)));
|
|
||||||
|
|
||||||
wasm_valtype_delete(Some(valtype));
|
wasm_valtype_delete(Some(valtype));
|
||||||
|
|
||||||
|
|||||||
@@ -18,17 +18,9 @@ pub extern "C" fn wasm_importtype_new(
|
|||||||
name: Option<&wasm_name_t>,
|
name: Option<&wasm_name_t>,
|
||||||
extern_type: Option<Box<wasm_externtype_t>>,
|
extern_type: Option<Box<wasm_externtype_t>>,
|
||||||
) -> Option<Box<wasm_importtype_t>> {
|
) -> Option<Box<wasm_importtype_t>> {
|
||||||
let (module, name) = unsafe {
|
let (module, name) =
|
||||||
(
|
unsafe { (owned_wasm_name_t::new(module?), owned_wasm_name_t::new(name?)) };
|
||||||
owned_wasm_name_t::new(module?),
|
Some(Box::new(wasm_importtype_t { name, module, extern_type: extern_type? }))
|
||||||
owned_wasm_name_t::new(name?),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
Some(Box::new(wasm_importtype_t {
|
|
||||||
name,
|
|
||||||
module,
|
|
||||||
extern_type: extern_type?,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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 name: owned_wasm_name_t = other.name().to_string().into();
|
||||||
let extern_type: Box<wasm_externtype_t> = Box::new(other.ty().into());
|
let extern_type: Box<wasm_externtype_t> = Box::new(other.ty().into());
|
||||||
|
|
||||||
wasm_importtype_t {
|
wasm_importtype_t { module, name, extern_type }
|
||||||
module,
|
|
||||||
name,
|
|
||||||
extern_type,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,16 +11,10 @@ impl WasmMemoryType {
|
|||||||
pub(crate) fn new(memory_type: MemoryType) -> Self {
|
pub(crate) fn new(memory_type: MemoryType) -> Self {
|
||||||
let limits = Box::new(wasm_limits_t {
|
let limits = Box::new(wasm_limits_t {
|
||||||
min: memory_type.minimum.0 as _,
|
min: memory_type.minimum.0 as _,
|
||||||
max: memory_type
|
max: memory_type.maximum.map(|max| max.0 as _).unwrap_or(LIMITS_MAX_SENTINEL),
|
||||||
.maximum
|
|
||||||
.map(|max| max.0 as _)
|
|
||||||
.unwrap_or(LIMITS_MAX_SENTINEL),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self { memory_type, limits }
|
||||||
memory_type,
|
|
||||||
limits,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,9 +27,7 @@ pub struct wasm_memorytype_t {
|
|||||||
|
|
||||||
impl wasm_memorytype_t {
|
impl wasm_memorytype_t {
|
||||||
pub(crate) fn new(memory_type: MemoryType) -> Self {
|
pub(crate) fn new(memory_type: MemoryType) -> Self {
|
||||||
Self {
|
Self { extern_type: wasm_externtype_t::new(ExternType::Memory(memory_type)) }
|
||||||
extern_type: wasm_externtype_t::new(ExternType::Memory(memory_type)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn inner(&self) -> &WasmMemoryType {
|
pub(crate) fn inner(&self) -> &WasmMemoryType {
|
||||||
@@ -53,15 +45,10 @@ wasm_declare_boxed_vec!(memorytype);
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
|
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
|
||||||
let min_pages = Pages(limits.min as _);
|
let min_pages = Pages(limits.min as _);
|
||||||
let max_pages = if limits.max == LIMITS_MAX_SENTINEL {
|
let max_pages =
|
||||||
None
|
if limits.max == LIMITS_MAX_SENTINEL { None } else { Some(Pages(limits.max as _)) };
|
||||||
} else {
|
|
||||||
Some(Pages(limits.max as _))
|
|
||||||
};
|
|
||||||
|
|
||||||
Box::new(wasm_memorytype_t::new(MemoryType::new(
|
Box::new(wasm_memorytype_t::new(MemoryType::new(min_pages, max_pages, false)))
|
||||||
min_pages, max_pages, false,
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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
|
/// You must ensure that the data pointed to by `wasm_name_t` is valid and
|
||||||
/// that it is not owned by anyone else.
|
/// that it is not owned by anyone else.
|
||||||
pub unsafe fn new(name: &wasm_name_t) -> Self {
|
pub unsafe fn new(name: &wasm_name_t) -> Self {
|
||||||
Self(wasm_name_t {
|
Self(wasm_name_t { size: name.size, data: name.data })
|
||||||
size: name.size,
|
|
||||||
data: name.data,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,7 @@ impl WasmTableType {
|
|||||||
});
|
});
|
||||||
let content = Box::new(table_type.ty.into());
|
let content = Box::new(table_type.ty.into());
|
||||||
|
|
||||||
Self {
|
Self { table_type, limits, content }
|
||||||
table_type,
|
|
||||||
limits,
|
|
||||||
content,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,9 +36,7 @@ pub struct wasm_tabletype_t {
|
|||||||
|
|
||||||
impl wasm_tabletype_t {
|
impl wasm_tabletype_t {
|
||||||
pub(crate) fn new(table_type: TableType) -> Self {
|
pub(crate) fn new(table_type: TableType) -> Self {
|
||||||
Self {
|
Self { extern_type: wasm_externtype_t::new(ExternType::Table(table_type)) }
|
||||||
extern_type: wasm_externtype_t::new(ExternType::Table(table_type)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn inner(&self) -> &WasmTableType {
|
pub(crate) fn inner(&self) -> &WasmTableType {
|
||||||
@@ -61,11 +55,7 @@ pub unsafe extern "C" fn wasm_tabletype_new(
|
|||||||
limits: &wasm_limits_t,
|
limits: &wasm_limits_t,
|
||||||
) -> Option<Box<wasm_tabletype_t>> {
|
) -> Option<Box<wasm_tabletype_t>> {
|
||||||
let valtype = valtype?;
|
let valtype = valtype?;
|
||||||
let max_elements = if limits.max == LIMITS_MAX_SENTINEL {
|
let max_elements = if limits.max == LIMITS_MAX_SENTINEL { None } else { Some(limits.max as _) };
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(limits.max as _)
|
|
||||||
};
|
|
||||||
let table_type = Box::new(wasm_tabletype_t::new(TableType::new(
|
let table_type = Box::new(wasm_tabletype_t::new(TableType::new(
|
||||||
(*valtype).into(),
|
(*valtype).into(),
|
||||||
limits.min as _,
|
limits.min as _,
|
||||||
|
|||||||
@@ -50,9 +50,7 @@ pub struct wasm_valtype_t {
|
|||||||
|
|
||||||
impl Default for wasm_valtype_t {
|
impl Default for wasm_valtype_t {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self { valkind: wasm_valkind_enum::WASM_I32 }
|
||||||
valkind: wasm_valkind_enum::WASM_I32,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,9 +70,7 @@ impl From<&wasm_valtype_t> for ValType {
|
|||||||
|
|
||||||
impl From<ValType> for wasm_valtype_t {
|
impl From<ValType> for wasm_valtype_t {
|
||||||
fn from(other: ValType) -> Self {
|
fn from(other: ValType) -> Self {
|
||||||
Self {
|
Self { valkind: other.into() }
|
||||||
valkind: other.into(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +87,5 @@ pub unsafe extern "C" fn wasm_valtype_delete(_valtype: Option<Box<wasm_valtype_t
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_valtype_kind(valtype: Option<&wasm_valtype_t>) -> wasm_valkind_t {
|
pub unsafe extern "C" fn wasm_valtype_kind(valtype: Option<&wasm_valtype_t>) -> wasm_valkind_t {
|
||||||
valtype
|
valtype.expect("`wasm_valtype_kind: argument is a null pointer").valkind as wasm_valkind_t
|
||||||
.expect("`wasm_valtype_kind: argument is a null pointer")
|
|
||||||
.valkind as wasm_valkind_t
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,10 +133,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wasmer_is_headless() {
|
fn test_wasmer_is_headless() {
|
||||||
set_var(
|
set_var("COMPILER", if cfg!(feature = "compiler") { "0" } else { "1" });
|
||||||
"COMPILER",
|
|
||||||
if cfg!(feature = "compiler") { "0" } else { "1" },
|
|
||||||
);
|
|
||||||
|
|
||||||
(assert_c! {
|
(assert_c! {
|
||||||
#include "tests/wasmer_wasm.h"
|
#include "tests/wasmer_wasm.h"
|
||||||
@@ -155,23 +152,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wasmer_is_compiler_available() {
|
fn test_wasmer_is_compiler_available() {
|
||||||
set_var(
|
set_var("CRANELIFT", if cfg!(feature = "cranelift") { "1" } else { "0" });
|
||||||
"CRANELIFT",
|
|
||||||
if cfg!(feature = "cranelift") {
|
|
||||||
"1"
|
|
||||||
} else {
|
|
||||||
"0"
|
|
||||||
},
|
|
||||||
);
|
|
||||||
set_var("LLVM", if cfg!(feature = "llvm") { "1" } else { "0" });
|
set_var("LLVM", if cfg!(feature = "llvm") { "1" } else { "0" });
|
||||||
set_var(
|
set_var("SINGLEPASS", if cfg!(feature = "singlepass") { "1" } else { "0" });
|
||||||
"SINGLEPASS",
|
|
||||||
if cfg!(feature = "singlepass") {
|
|
||||||
"1"
|
|
||||||
} else {
|
|
||||||
"0"
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
(assert_c! {
|
(assert_c! {
|
||||||
#include "tests/wasmer_wasm.h"
|
#include "tests/wasmer_wasm.h"
|
||||||
@@ -196,14 +179,7 @@ mod tests {
|
|||||||
fn test_wasmer_is_engine_available() {
|
fn test_wasmer_is_engine_available() {
|
||||||
set_var("JIT", if cfg!(feature = "jit") { "1" } else { "0" });
|
set_var("JIT", if cfg!(feature = "jit") { "1" } else { "0" });
|
||||||
set_var("NATIVE", if cfg!(feature = "native") { "1" } else { "0" });
|
set_var("NATIVE", if cfg!(feature = "native") { "1" } else { "0" });
|
||||||
set_var(
|
set_var("OBJECT_FILE", if cfg!(feature = "object-file") { "1" } else { "0" });
|
||||||
"OBJECT_FILE",
|
|
||||||
if cfg!(feature = "object-file") {
|
|
||||||
"1"
|
|
||||||
} else {
|
|
||||||
"0"
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
(assert_c! {
|
(assert_c! {
|
||||||
#include "tests/wasmer_wasm.h"
|
#include "tests/wasmer_wasm.h"
|
||||||
|
|||||||
@@ -55,9 +55,7 @@ pub struct wasmer_features_t {
|
|||||||
/// See the module's documentation.
|
/// See the module's documentation.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_features_new() -> Box<wasmer_features_t> {
|
pub extern "C" fn wasmer_features_new() -> Box<wasmer_features_t> {
|
||||||
Box::new(wasmer_features_t {
|
Box::new(wasmer_features_t { inner: Features::new() })
|
||||||
inner: Features::new(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a [`wasmer_features_t`].
|
/// 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.
|
/// See module's documentation.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_t) -> bool {
|
pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_t) -> bool {
|
||||||
matches!(
|
matches!(get_remaining_points(&instance.inner), MeteringPoints::Exhausted,)
|
||||||
get_remaining_points(&instance.inner),
|
|
||||||
MeteringPoints::Exhausted,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a new amount of points for the given metering middleware.
|
/// Set a new amount of points for the given metering middleware.
|
||||||
@@ -313,7 +310,5 @@ pub extern "C" fn wasmer_metering_as_middleware(
|
|||||||
) -> Option<Box<wasmer_middleware_t>> {
|
) -> Option<Box<wasmer_middleware_t>> {
|
||||||
let metering = metering?;
|
let metering = metering?;
|
||||||
|
|
||||||
Some(Box::new(wasmer_middleware_t {
|
Some(Box::new(wasmer_middleware_t { inner: metering.inner }))
|
||||||
inner: metering.inner,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,10 +147,7 @@ pub unsafe extern "C" fn wasmer_triple_new(
|
|||||||
triple: Option<&wasm_name_t>,
|
triple: Option<&wasm_name_t>,
|
||||||
) -> Option<Box<wasmer_triple_t>> {
|
) -> Option<Box<wasmer_triple_t>> {
|
||||||
let triple = triple?;
|
let triple = triple?;
|
||||||
let triple = c_try!(str::from_utf8(slice::from_raw_parts(
|
let triple = c_try!(str::from_utf8(slice::from_raw_parts(triple.data, triple.size)));
|
||||||
triple.data,
|
|
||||||
triple.size
|
|
||||||
)));
|
|
||||||
|
|
||||||
Some(Box::new(wasmer_triple_t {
|
Some(Box::new(wasmer_triple_t {
|
||||||
inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })),
|
inner: c_try!(Triple::from_str(triple).map_err(|e| CApiError { msg: e.to_string() })),
|
||||||
@@ -183,9 +180,7 @@ pub unsafe extern "C" fn wasmer_triple_new(
|
|||||||
/// See also [`wasmer_triple_new`].
|
/// See also [`wasmer_triple_new`].
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_triple_new_from_host() -> Box<wasmer_triple_t> {
|
pub extern "C" fn wasmer_triple_new_from_host() -> Box<wasmer_triple_t> {
|
||||||
Box::new(wasmer_triple_t {
|
Box::new(wasmer_triple_t { inner: Triple::host() })
|
||||||
inner: Triple::host(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a [`wasmer_triple_t`].
|
/// Delete a [`wasmer_triple_t`].
|
||||||
@@ -265,9 +260,7 @@ pub struct wasmer_cpu_features_t {
|
|||||||
/// See [`wasmer_cpu_features_t`].
|
/// See [`wasmer_cpu_features_t`].
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_cpu_features_new() -> Box<wasmer_cpu_features_t> {
|
pub extern "C" fn wasmer_cpu_features_new() -> Box<wasmer_cpu_features_t> {
|
||||||
Box::new(wasmer_cpu_features_t {
|
Box::new(wasmer_cpu_features_t { inner: CpuFeature::set() })
|
||||||
inner: CpuFeature::set(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a [`wasmer_cpu_features_t`].
|
/// Delete a [`wasmer_cpu_features_t`].
|
||||||
|
|||||||
@@ -171,11 +171,9 @@ fn wasi_get_unordered_imports_inner(
|
|||||||
|
|
||||||
let store = &store.inner;
|
let store = &store.inner;
|
||||||
|
|
||||||
let version = c_try!(
|
let version = c_try!(get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
|
||||||
get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
|
msg: "could not detect a WASI version on the given module".to_string(),
|
||||||
msg: "could not detect a WASI version on the given module".to_string(),
|
}));
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);
|
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);
|
||||||
|
|
||||||
|
|||||||
@@ -114,10 +114,7 @@ wasm_declare_vec!(val);
|
|||||||
|
|
||||||
impl Clone for wasm_val_t {
|
impl Clone for wasm_val_t {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
wasm_val_t {
|
wasm_val_t { kind: self.kind, of: self.of.clone() }
|
||||||
kind: self.kind,
|
|
||||||
of: self.of.clone(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,18 +127,10 @@ pub unsafe extern "C" fn wasm_val_copy(
|
|||||||
out.kind = val.kind;
|
out.kind = val.kind;
|
||||||
out.of = match val.kind.try_into() {
|
out.of = match val.kind.try_into() {
|
||||||
Ok(kind) => match kind {
|
Ok(kind) => match kind {
|
||||||
wasm_valkind_enum::WASM_I32 => wasm_val_inner {
|
wasm_valkind_enum::WASM_I32 => wasm_val_inner { int32_t: val.of.int32_t },
|
||||||
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_I64 => wasm_val_inner {
|
wasm_valkind_enum::WASM_F64 => wasm_val_inner { float64_t: val.of.float64_t },
|
||||||
int64_t: val.of.int64_t,
|
|
||||||
},
|
|
||||||
wasm_valkind_enum::WASM_F32 => wasm_val_inner {
|
|
||||||
float32_t: val.of.float32_t,
|
|
||||||
},
|
|
||||||
wasm_valkind_enum::WASM_F64 => wasm_val_inner {
|
|
||||||
float64_t: val.of.float64_t,
|
|
||||||
},
|
|
||||||
wasm_valkind_enum::WASM_ANYREF => wasm_val_inner { wref: val.of.wref },
|
wasm_valkind_enum::WASM_ANYREF => wasm_val_inner { wref: val.of.wref },
|
||||||
wasm_valkind_enum::WASM_FUNCREF => wasm_val_inner { wref: val.of.wref },
|
wasm_valkind_enum::WASM_FUNCREF => wasm_val_inner { wref: val.of.wref },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ pub struct OutputCapturer {
|
|||||||
|
|
||||||
impl OutputCapturer {
|
impl OutputCapturer {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self { buffer: VecDeque::new() }
|
||||||
buffer: VecDeque::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,36 +46,21 @@ impl WasiFile for OutputCapturer {
|
|||||||
// fail when reading or Seeking
|
// fail when reading or Seeking
|
||||||
impl Read for OutputCapturer {
|
impl Read for OutputCapturer {
|
||||||
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "can not read from capturing stdout"))
|
||||||
io::ErrorKind::Other,
|
|
||||||
"can not read from capturing stdout",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> std::io::Result<usize> {
|
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> std::io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(std::io::Error::new(std::io::ErrorKind::Other, "can not read from capturing stdout"))
|
||||||
std::io::ErrorKind::Other,
|
|
||||||
"can not read from capturing stdout",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
|
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "can not read from capturing stdout"))
|
||||||
io::ErrorKind::Other,
|
|
||||||
"can not read from capturing stdout",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
|
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "can not read from capturing stdout"))
|
||||||
io::ErrorKind::Other,
|
|
||||||
"can not read from capturing stdout",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Seek for OutputCapturer {
|
impl Seek for OutputCapturer {
|
||||||
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "can not seek capturing stdout"))
|
||||||
io::ErrorKind::Other,
|
|
||||||
"can not seek capturing stdout",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Write for OutputCapturer {
|
impl Write for OutputCapturer {
|
||||||
|
|||||||
@@ -175,24 +175,18 @@ pub struct wasi_env_t {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasi_env_new(mut config: Box<wasi_config_t>) -> Option<Box<wasi_env_t>> {
|
pub extern "C" fn wasi_env_new(mut config: Box<wasi_config_t>) -> Option<Box<wasi_env_t>> {
|
||||||
if !config.inherit_stdout {
|
if !config.inherit_stdout {
|
||||||
config
|
config.state_builder.stdout(Box::new(capture_files::OutputCapturer::new()));
|
||||||
.state_builder
|
|
||||||
.stdout(Box::new(capture_files::OutputCapturer::new()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.inherit_stderr {
|
if !config.inherit_stderr {
|
||||||
config
|
config.state_builder.stderr(Box::new(capture_files::OutputCapturer::new()));
|
||||||
.state_builder
|
|
||||||
.stderr(Box::new(capture_files::OutputCapturer::new()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: impl capturer for stdin
|
// TODO: impl capturer for stdin
|
||||||
|
|
||||||
let wasi_state = c_try!(config.state_builder.build());
|
let wasi_state = c_try!(config.state_builder.build());
|
||||||
|
|
||||||
Some(Box::new(wasi_env_t {
|
Some(Box::new(wasi_env_t { inner: WasiEnv::new(wasi_state) }))
|
||||||
inner: WasiEnv::new(wasi_state),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a [`wasi_env_t`].
|
/// 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>() {
|
if let Some(oc) = wasi_file.downcast_mut::<capture_files::OutputCapturer>() {
|
||||||
let total_to_read = min(inner_buffer.len(), oc.buffer.len());
|
let total_to_read = min(inner_buffer.len(), oc.buffer.len());
|
||||||
|
|
||||||
for (address, value) in inner_buffer
|
for (address, value) in inner_buffer.iter_mut().zip(oc.buffer.drain(..total_to_read)) {
|
||||||
.iter_mut()
|
|
||||||
.zip(oc.buffer.drain(..total_to_read))
|
|
||||||
{
|
|
||||||
*address = value;
|
*address = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,11 +358,9 @@ fn wasi_get_imports_inner(
|
|||||||
|
|
||||||
let store = &store.inner;
|
let store = &store.inner;
|
||||||
|
|
||||||
let version = c_try!(
|
let version = c_try!(get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
|
||||||
get_wasi_version(&module.inner, false).ok_or_else(|| CApiError {
|
msg: "could not detect a WASI version on the given module".to_string(),
|
||||||
msg: "could not detect a WASI version on the given module".to_string(),
|
}));
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);
|
let import_object = generate_import_object_from_env(store, wasi_env.inner.clone(), version);
|
||||||
|
|
||||||
|
|||||||
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 mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||||
let compiler = Singlepass::default();
|
let compiler = Singlepass::default();
|
||||||
let store = Store::new(&JIT::new(compiler).engine());
|
let store = Store::new(&JIT::new(compiler).engine());
|
||||||
let module = Module::new(
|
let module =
|
||||||
&store,
|
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
.unwrap();
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
c.bench_function("store jit module in filesystem cache", |b| {
|
c.bench_function("store jit module in filesystem cache", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
@@ -37,11 +35,9 @@ pub fn load_cache_jit(c: &mut Criterion) {
|
|||||||
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||||
let compiler = Singlepass::default();
|
let compiler = Singlepass::default();
|
||||||
let store = Store::new(&JIT::new(compiler).engine());
|
let store = Store::new(&JIT::new(compiler).engine());
|
||||||
let module = Module::new(
|
let module =
|
||||||
&store,
|
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
.unwrap();
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let key = Hash::new([0u8; 32]);
|
let key = Hash::new([0u8; 32]);
|
||||||
fs_cache.store(key, &module).unwrap();
|
fs_cache.store(key, &module).unwrap();
|
||||||
|
|
||||||
@@ -55,11 +51,9 @@ pub fn store_cache_native(c: &mut Criterion) {
|
|||||||
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||||
let compiler = Singlepass::default();
|
let compiler = Singlepass::default();
|
||||||
let store = Store::new(&Native::new(compiler).engine());
|
let store = Store::new(&Native::new(compiler).engine());
|
||||||
let module = Module::new(
|
let module =
|
||||||
&store,
|
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
.unwrap();
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
c.bench_function("store native module in filesystem cache", |b| {
|
c.bench_function("store native module in filesystem cache", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
@@ -74,11 +68,9 @@ pub fn load_cache_native(c: &mut Criterion) {
|
|||||||
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap();
|
||||||
let compiler = Singlepass::default();
|
let compiler = Singlepass::default();
|
||||||
let store = Store::new(&Native::new(compiler).engine());
|
let store = Store::new(&Native::new(compiler).engine());
|
||||||
let module = Module::new(
|
let module =
|
||||||
&store,
|
Module::new(&store, std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap())
|
||||||
std::fs::read("../../lib/c-api/tests/assets/qjs.wasm").unwrap(),
|
.unwrap();
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let key = Hash::new([0u8; 32]);
|
let key = Hash::new([0u8; 32]);
|
||||||
fs_cache.store(key, &module).unwrap();
|
fs_cache.store(key, &module).unwrap();
|
||||||
|
|
||||||
|
|||||||
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.
|
// This path points to a file.
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::PermissionDenied,
|
io::ErrorKind::PermissionDenied,
|
||||||
format!(
|
format!("the supplied path already points to a file: {}", path.display()),
|
||||||
"the supplied path already points to a file: {}",
|
|
||||||
path.display()
|
|
||||||
),
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -59,19 +59,13 @@ pub enum CType {
|
|||||||
impl CType {
|
impl CType {
|
||||||
/// Convenience function to get a mutable void pointer type.
|
/// Convenience function to get a mutable void pointer type.
|
||||||
pub fn void_ptr() -> Self {
|
pub fn void_ptr() -> Self {
|
||||||
CType::PointerTo {
|
CType::PointerTo { is_const: false, inner: Box::new(CType::Void) }
|
||||||
is_const: false,
|
|
||||||
inner: Box::new(CType::Void),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to get a const void pointer type.
|
/// Convenience function to get a const void pointer type.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn const_void_ptr() -> Self {
|
pub fn const_void_ptr() -> Self {
|
||||||
CType::PointerTo {
|
CType::PointerTo { is_const: true, inner: Box::new(CType::Void) }
|
||||||
is_const: true,
|
|
||||||
inner: Box::new(CType::Void),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate the C source code for a type into the given `String`.
|
/// Generate the C source code for a type into the given `String`.
|
||||||
@@ -117,15 +111,10 @@ impl CType {
|
|||||||
Self::ISize => {
|
Self::ISize => {
|
||||||
w.push_str("size_t");
|
w.push_str("size_t");
|
||||||
}
|
}
|
||||||
Self::Function {
|
Self::Function { arguments, return_value } => {
|
||||||
arguments,
|
|
||||||
return_value,
|
|
||||||
} => {
|
|
||||||
// function with no, name, assume it's a function pointer
|
// function with no, name, assume it's a function pointer
|
||||||
let ret: CType = return_value
|
let ret: CType =
|
||||||
.as_ref()
|
return_value.as_ref().map(|i: &Box<CType>| (&**i).clone()).unwrap_or_default();
|
||||||
.map(|i: &Box<CType>| (&**i).clone())
|
|
||||||
.unwrap_or_default();
|
|
||||||
ret.generate_c(w);
|
ret.generate_c(w);
|
||||||
w.push(' ');
|
w.push(' ');
|
||||||
w.push_str("(*)");
|
w.push_str("(*)");
|
||||||
@@ -171,14 +160,9 @@ impl CType {
|
|||||||
w.push(' ');
|
w.push(' ');
|
||||||
w.push_str(name);
|
w.push_str(name);
|
||||||
}
|
}
|
||||||
Self::Function {
|
Self::Function { arguments, return_value } => {
|
||||||
arguments,
|
let ret: CType =
|
||||||
return_value,
|
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);
|
ret.generate_c(w);
|
||||||
w.push(' ');
|
w.push(' ');
|
||||||
w.push_str(&name);
|
w.push_str(&name);
|
||||||
@@ -264,13 +248,7 @@ impl CStatement {
|
|||||||
/// Generate C source code for the given CStatement.
|
/// Generate C source code for the given CStatement.
|
||||||
fn generate_c(&self, w: &mut String) {
|
fn generate_c(&self, w: &mut String) {
|
||||||
match &self {
|
match &self {
|
||||||
Self::Declaration {
|
Self::Declaration { name, is_extern, is_const, ctype, definition } => {
|
||||||
name,
|
|
||||||
is_extern,
|
|
||||||
is_const,
|
|
||||||
ctype,
|
|
||||||
definition,
|
|
||||||
} => {
|
|
||||||
if *is_const {
|
if *is_const {
|
||||||
w.push_str("const ");
|
w.push_str("const ");
|
||||||
}
|
}
|
||||||
@@ -301,20 +279,14 @@ impl CStatement {
|
|||||||
Self::LiteralConstant { value } => {
|
Self::LiteralConstant { value } => {
|
||||||
w.push_str(&value);
|
w.push_str(&value);
|
||||||
}
|
}
|
||||||
Self::Cast {
|
Self::Cast { target_type, expression } => {
|
||||||
target_type,
|
|
||||||
expression,
|
|
||||||
} => {
|
|
||||||
w.push('(');
|
w.push('(');
|
||||||
target_type.generate_c(w);
|
target_type.generate_c(w);
|
||||||
w.push(')');
|
w.push(')');
|
||||||
w.push(' ');
|
w.push(' ');
|
||||||
expression.generate_c(w);
|
expression.generate_c(w);
|
||||||
}
|
}
|
||||||
Self::TypeDef {
|
Self::TypeDef { source_type, new_name } => {
|
||||||
source_type,
|
|
||||||
new_name,
|
|
||||||
} => {
|
|
||||||
w.push_str("typedef ");
|
w.push_str("typedef ");
|
||||||
// leaky abstraction / hack, doesn't fully solve the problem
|
// leaky abstraction / hack, doesn't fully solve the problem
|
||||||
if let CType::Function { .. } = source_type {
|
if let CType::Function { .. } = source_type {
|
||||||
@@ -371,26 +343,17 @@ mod test {
|
|||||||
assert_c_type!(CType::ISize, "size_t");
|
assert_c_type!(CType::ISize, "size_t");
|
||||||
assert_c_type!(CType::TypeDef("my_type".to_string()), "my_type");
|
assert_c_type!(CType::TypeDef("my_type".to_string()), "my_type");
|
||||||
assert_c_type!(
|
assert_c_type!(
|
||||||
CType::Function {
|
CType::Function { arguments: vec![CType::U8, CType::ISize], return_value: None },
|
||||||
arguments: vec![CType::U8, CType::ISize],
|
|
||||||
return_value: None,
|
|
||||||
},
|
|
||||||
"void (*)(unsigned char, size_t)"
|
"void (*)(unsigned char, size_t)"
|
||||||
);
|
);
|
||||||
assert_c_type!(
|
assert_c_type!(
|
||||||
CType::Function {
|
CType::Function { arguments: vec![], return_value: Some(Box::new(CType::ISize)) },
|
||||||
arguments: vec![],
|
|
||||||
return_value: Some(Box::new(CType::ISize)),
|
|
||||||
},
|
|
||||||
"size_t (*)()"
|
"size_t (*)()"
|
||||||
);
|
);
|
||||||
assert_c_type!(
|
assert_c_type!(
|
||||||
CType::PointerTo {
|
CType::PointerTo {
|
||||||
is_const: true,
|
is_const: true,
|
||||||
inner: Box::new(CType::PointerTo {
|
inner: Box::new(CType::PointerTo { is_const: false, inner: Box::new(CType::U32) })
|
||||||
is_const: false,
|
|
||||||
inner: Box::new(CType::U32),
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
"const unsigned int**"
|
"const unsigned int**"
|
||||||
);
|
);
|
||||||
@@ -421,34 +384,21 @@ mod test {
|
|||||||
assert_c_type!(CType::I32, "data", "int data");
|
assert_c_type!(CType::I32, "data", "int data");
|
||||||
assert_c_type!(CType::I64, "data", "long long data");
|
assert_c_type!(CType::I64, "data", "long long data");
|
||||||
assert_c_type!(CType::ISize, "data", "size_t data");
|
assert_c_type!(CType::ISize, "data", "size_t data");
|
||||||
|
assert_c_type!(CType::TypeDef("my_type".to_string()), "data", "my_type data");
|
||||||
assert_c_type!(
|
assert_c_type!(
|
||||||
CType::TypeDef("my_type".to_string()),
|
CType::Function { arguments: vec![CType::U8, CType::ISize], return_value: None },
|
||||||
"data",
|
|
||||||
"my_type data"
|
|
||||||
);
|
|
||||||
assert_c_type!(
|
|
||||||
CType::Function {
|
|
||||||
arguments: vec![CType::U8, CType::ISize],
|
|
||||||
return_value: None,
|
|
||||||
},
|
|
||||||
"my_func",
|
"my_func",
|
||||||
"void my_func(unsigned char, size_t)"
|
"void my_func(unsigned char, size_t)"
|
||||||
);
|
);
|
||||||
assert_c_type!(
|
assert_c_type!(
|
||||||
CType::Function {
|
CType::Function { arguments: vec![], return_value: Some(Box::new(CType::ISize)) },
|
||||||
arguments: vec![],
|
|
||||||
return_value: Some(Box::new(CType::ISize)),
|
|
||||||
},
|
|
||||||
"my_func",
|
"my_func",
|
||||||
"size_t my_func()"
|
"size_t my_func()"
|
||||||
);
|
);
|
||||||
assert_c_type!(
|
assert_c_type!(
|
||||||
CType::PointerTo {
|
CType::PointerTo {
|
||||||
is_const: true,
|
is_const: true,
|
||||||
inner: Box::new(CType::PointerTo {
|
inner: Box::new(CType::PointerTo { is_const: false, inner: Box::new(CType::U32) })
|
||||||
is_const: false,
|
|
||||||
inner: Box::new(CType::U32),
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
"data",
|
"data",
|
||||||
"const unsigned int** data"
|
"const unsigned int** data"
|
||||||
@@ -468,9 +418,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_c_expr!(
|
assert_c_expr!(
|
||||||
CStatement::LiteralConstant {
|
CStatement::LiteralConstant { value: "\"Hello, world!\"".to_string() },
|
||||||
value: "\"Hello, world!\"".to_string(),
|
|
||||||
},
|
|
||||||
"\"Hello, world!\""
|
"\"Hello, world!\""
|
||||||
);
|
);
|
||||||
assert_c_expr!(
|
assert_c_expr!(
|
||||||
@@ -486,15 +434,9 @@ mod test {
|
|||||||
assert_c_expr!(
|
assert_c_expr!(
|
||||||
CStatement::LiteralArray {
|
CStatement::LiteralArray {
|
||||||
items: vec![
|
items: vec![
|
||||||
CStatement::LiteralConstant {
|
CStatement::LiteralConstant { value: "1".to_string() },
|
||||||
value: "1".to_string()
|
CStatement::LiteralConstant { value: "2".to_string() },
|
||||||
},
|
CStatement::LiteralConstant { value: "3".to_string() },
|
||||||
CStatement::LiteralConstant {
|
|
||||||
value: "2".to_string()
|
|
||||||
},
|
|
||||||
CStatement::LiteralConstant {
|
|
||||||
value: "3".to_string()
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"{\n\t1,\n\t2,\n\t3,\n}"
|
"{\n\t1,\n\t2,\n\t3,\n}"
|
||||||
@@ -505,20 +447,12 @@ mod test {
|
|||||||
name: "my_array".to_string(),
|
name: "my_array".to_string(),
|
||||||
is_extern: false,
|
is_extern: false,
|
||||||
is_const: true,
|
is_const: true,
|
||||||
ctype: CType::Array {
|
ctype: CType::Array { inner: Box::new(CType::I32) },
|
||||||
inner: Box::new(CType::I32),
|
|
||||||
},
|
|
||||||
definition: Some(Box::new(CStatement::LiteralArray {
|
definition: Some(Box::new(CStatement::LiteralArray {
|
||||||
items: vec![
|
items: vec![
|
||||||
CStatement::LiteralConstant {
|
CStatement::LiteralConstant { value: "1".to_string() },
|
||||||
value: "1".to_string()
|
CStatement::LiteralConstant { value: "2".to_string() },
|
||||||
},
|
CStatement::LiteralConstant { value: "3".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(),
|
name: "my_array".to_string(),
|
||||||
is_extern: true,
|
is_extern: true,
|
||||||
is_const: true,
|
is_const: true,
|
||||||
ctype: CType::Array {
|
ctype: CType::Array { inner: Box::new(CType::I32) },
|
||||||
inner: Box::new(CType::I32),
|
|
||||||
},
|
|
||||||
definition: None,
|
definition: None,
|
||||||
},
|
},
|
||||||
"const extern int my_array[];\n"
|
"const extern int my_array[];\n"
|
||||||
|
|||||||
@@ -94,9 +94,7 @@ pub fn generate_header_file(
|
|||||||
name: "WASMER_METADATA".to_string(),
|
name: "WASMER_METADATA".to_string(),
|
||||||
is_extern: true,
|
is_extern: true,
|
||||||
is_const: true,
|
is_const: true,
|
||||||
ctype: CType::Array {
|
ctype: CType::Array { inner: Box::new(CType::U8) },
|
||||||
inner: Box::new(CType::U8),
|
|
||||||
},
|
|
||||||
definition: None,
|
definition: None,
|
||||||
});
|
});
|
||||||
let function_declarations = module_info
|
let function_declarations = module_info
|
||||||
@@ -113,10 +111,7 @@ pub fn generate_header_file(
|
|||||||
name: function_name,
|
name: function_name,
|
||||||
is_extern: false,
|
is_extern: false,
|
||||||
is_const: false,
|
is_const: false,
|
||||||
ctype: CType::Function {
|
ctype: CType::Function { arguments: vec![CType::Void], return_value: None },
|
||||||
arguments: vec![CType::Void],
|
|
||||||
return_value: None,
|
|
||||||
},
|
|
||||||
definition: None,
|
definition: None,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -144,9 +139,7 @@ pub fn generate_header_file(
|
|||||||
|
|
||||||
CStatement::Cast {
|
CStatement::Cast {
|
||||||
target_type: CType::void_ptr(),
|
target_type: CType::void_ptr(),
|
||||||
expression: Box::new(CStatement::LiteralConstant {
|
expression: Box::new(CStatement::LiteralConstant { value: function_name }),
|
||||||
value: function_name,
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@@ -155,9 +148,7 @@ pub fn generate_header_file(
|
|||||||
name: "function_pointers".to_string(),
|
name: "function_pointers".to_string(),
|
||||||
is_extern: false,
|
is_extern: false,
|
||||||
is_const: true,
|
is_const: true,
|
||||||
ctype: CType::Array {
|
ctype: CType::Array { inner: Box::new(CType::void_ptr()) },
|
||||||
inner: Box::new(CType::void_ptr()),
|
|
||||||
},
|
|
||||||
definition: Some(Box::new(CStatement::LiteralArray {
|
definition: Some(Box::new(CStatement::LiteralArray {
|
||||||
items: function_pointer_array_statements,
|
items: function_pointer_array_statements,
|
||||||
})),
|
})),
|
||||||
@@ -165,24 +156,21 @@ pub fn generate_header_file(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let func_trampoline_declarations =
|
let func_trampoline_declarations =
|
||||||
module_info
|
module_info.signatures.iter().map(|(sig_index, _func_type)| {
|
||||||
.signatures
|
let function_name =
|
||||||
.iter()
|
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
|
||||||
.map(|(sig_index, _func_type)| {
|
|
||||||
let function_name =
|
|
||||||
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
|
|
||||||
|
|
||||||
CStatement::Declaration {
|
CStatement::Declaration {
|
||||||
name: function_name,
|
name: function_name,
|
||||||
is_extern: false,
|
is_extern: false,
|
||||||
is_const: false,
|
is_const: false,
|
||||||
ctype: CType::Function {
|
ctype: CType::Function {
|
||||||
arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
|
arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
|
||||||
return_value: None,
|
return_value: None,
|
||||||
},
|
},
|
||||||
definition: None,
|
definition: None,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
c_statements.push(CStatement::LiteralConstant {
|
c_statements.push(CStatement::LiteralConstant {
|
||||||
value: r#"
|
value: r#"
|
||||||
// Trampolines (functions by which we can call into Wasm) ordered by signature.
|
// Trampolines (functions by which we can call into Wasm) ordered by signature.
|
||||||
@@ -201,9 +189,7 @@ pub fn generate_header_file(
|
|||||||
.map(|(sig_index, _vm_shared_index)| {
|
.map(|(sig_index, _vm_shared_index)| {
|
||||||
let function_name =
|
let function_name =
|
||||||
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
|
symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
|
||||||
CStatement::LiteralConstant {
|
CStatement::LiteralConstant { value: function_name }
|
||||||
value: function_name,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
@@ -211,20 +197,15 @@ pub fn generate_header_file(
|
|||||||
name: "function_trampolines".to_string(),
|
name: "function_trampolines".to_string(),
|
||||||
is_extern: false,
|
is_extern: false,
|
||||||
is_const: true,
|
is_const: true,
|
||||||
ctype: CType::Array {
|
ctype: CType::Array { inner: Box::new(CType::void_ptr()) },
|
||||||
inner: Box::new(CType::void_ptr()),
|
|
||||||
},
|
|
||||||
definition: Some(Box::new(CStatement::LiteralArray {
|
definition: Some(Box::new(CStatement::LiteralArray {
|
||||||
items: function_trampoline_statements,
|
items: function_trampoline_statements,
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let dyn_func_declarations = module_info
|
let dyn_func_declarations =
|
||||||
.functions
|
module_info.functions.keys().take(module_info.num_imported_functions).map(|func_index| {
|
||||||
.keys()
|
|
||||||
.take(module_info.num_imported_functions)
|
|
||||||
.map(|func_index| {
|
|
||||||
let function_name =
|
let function_name =
|
||||||
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
|
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
|
||||||
// TODO: figure out the signature here
|
// TODO: figure out the signature here
|
||||||
@@ -266,9 +247,7 @@ pub fn generate_header_file(
|
|||||||
.map(|func_index| {
|
.map(|func_index| {
|
||||||
let function_name =
|
let function_name =
|
||||||
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
|
symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
|
||||||
CStatement::LiteralConstant {
|
CStatement::LiteralConstant { value: function_name }
|
||||||
value: function_name,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
c_statements.push(CStatement::Declaration {
|
c_statements.push(CStatement::Declaration {
|
||||||
@@ -284,9 +263,7 @@ pub fn generate_header_file(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
c_statements.push(CStatement::LiteralConstant {
|
c_statements.push(CStatement::LiteralConstant { value: HELPER_FUNCTIONS.to_string() });
|
||||||
value: HELPER_FUNCTIONS.to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
c_statements.push(CStatement::LiteralConstant {
|
c_statements.push(CStatement::LiteralConstant {
|
||||||
value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(),
|
value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(),
|
||||||
|
|||||||
@@ -19,11 +19,7 @@ use clap::{Clap, ErrorKind};
|
|||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "headless",
|
feature = "headless",
|
||||||
clap(
|
clap(name = "wasmer-headless", about = "Headless WebAssembly standalone runtime.", author)
|
||||||
name = "wasmer-headless",
|
|
||||||
about = "Headless WebAssembly standalone runtime.",
|
|
||||||
author
|
|
||||||
)
|
|
||||||
)]
|
)]
|
||||||
/// The options for the wasmer Command Line Interface
|
/// The options for the wasmer Command Line Interface
|
||||||
enum WasmerCLIOptions {
|
enum WasmerCLIOptions {
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ pub struct Compile {
|
|||||||
impl Compile {
|
impl Compile {
|
||||||
/// Runs logic for the `compile` subcommand
|
/// Runs logic for the `compile` subcommand
|
||||||
pub fn execute(&self) -> Result<()> {
|
pub fn execute(&self) -> Result<()> {
|
||||||
self.inner_execute()
|
self.inner_execute().context(format!("failed to compile `{}`", self.path.display()))
|
||||||
.context(format!("failed to compile `{}`", self.path.display()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_recommend_extension(
|
pub(crate) fn get_recommend_extension(
|
||||||
@@ -63,11 +62,8 @@ impl Compile {
|
|||||||
.target_triple
|
.target_triple
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|target_triple| {
|
.map(|target_triple| {
|
||||||
let mut features = self
|
let mut features =
|
||||||
.cpu_features
|
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b);
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.fold(CpuFeature::set(), |a, b| a | b);
|
|
||||||
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
|
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
|
||||||
// usage
|
// usage
|
||||||
features |= CpuFeature::SSE2;
|
features |= CpuFeature::SSE2;
|
||||||
@@ -98,10 +94,7 @@ impl Compile {
|
|||||||
|
|
||||||
let module = Module::from_file(&store, &self.path)?;
|
let module = Module::from_file(&store, &self.path)?;
|
||||||
let _ = module.serialize_to_file(&self.output)?;
|
let _ = module.serialize_to_file(&self.output)?;
|
||||||
eprintln!(
|
eprintln!("✔ File compiled successfully to `{}`.", self.output.display(),);
|
||||||
"✔ File compiled successfully to `{}`.",
|
|
||||||
self.output.display(),
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(feature = "object-file")]
|
#[cfg(feature = "object-file")]
|
||||||
if engine_type == EngineType::ObjectFile {
|
if engine_type == EngineType::ObjectFile {
|
||||||
@@ -135,10 +128,7 @@ impl Compile {
|
|||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
header.write_all(header_file_src.as_bytes())?;
|
header.write_all(header_file_src.as_bytes())?;
|
||||||
eprintln!(
|
eprintln!("✔ Header file generated successfully at `{}`.", header_path.display(),);
|
||||||
"✔ Header file generated successfully at `{}`.",
|
|
||||||
header_path.display(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,21 +40,13 @@ pub struct Config {
|
|||||||
impl Config {
|
impl Config {
|
||||||
/// Runs logic for the `config` subcommand
|
/// Runs logic for the `config` subcommand
|
||||||
pub fn execute(&self) -> Result<()> {
|
pub fn execute(&self) -> Result<()> {
|
||||||
self.inner_execute()
|
self.inner_execute().context("failed to retrieve the wasmer config".to_string())
|
||||||
.context("failed to retrieve the wasmer config".to_string())
|
|
||||||
}
|
}
|
||||||
fn inner_execute(&self) -> Result<()> {
|
fn inner_execute(&self) -> Result<()> {
|
||||||
let key = "WASMER_DIR";
|
let key = "WASMER_DIR";
|
||||||
let wasmer_dir = env::var(key)
|
let wasmer_dir = env::var(key)
|
||||||
.or_else(|e| {
|
.or_else(|e| option_env!("WASMER_INSTALL_PREFIX").map(str::to_string).ok_or(e))
|
||||||
option_env!("WASMER_INSTALL_PREFIX")
|
.context(format!("failed to retrieve the {} environment variables", key))?;
|
||||||
.map(str::to_string)
|
|
||||||
.ok_or(e)
|
|
||||||
})
|
|
||||||
.context(format!(
|
|
||||||
"failed to retrieve the {} environment variables",
|
|
||||||
key
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let prefix = PathBuf::from(wasmer_dir);
|
let prefix = PathBuf::from(wasmer_dir);
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,8 @@ impl CreateExe {
|
|||||||
.target_triple
|
.target_triple
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|target_triple| {
|
.map(|target_triple| {
|
||||||
let mut features = self
|
let mut features =
|
||||||
.cpu_features
|
self.cpu_features.clone().into_iter().fold(CpuFeature::set(), |a, b| a | b);
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.fold(CpuFeature::set(), |a, b| a | b);
|
|
||||||
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
|
// Cranelift requires SSE2, so we have this "hack" for now to facilitate
|
||||||
// usage
|
// usage
|
||||||
features |= CpuFeature::SSE2;
|
features |= CpuFeature::SSE2;
|
||||||
@@ -57,9 +54,8 @@ impl CreateExe {
|
|||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let engine_type = EngineType::ObjectFile;
|
let engine_type = EngineType::ObjectFile;
|
||||||
let (store, compiler_type) = self
|
let (store, compiler_type) =
|
||||||
.compiler
|
self.compiler.get_store_for_target_and_engine(target.clone(), engine_type)?;
|
||||||
.get_store_for_target_and_engine(target.clone(), engine_type)?;
|
|
||||||
|
|
||||||
println!("Engine: {}", engine_type.to_string());
|
println!("Engine: {}", engine_type.to_string());
|
||||||
println!("Compiler: {}", compiler_type.to_string());
|
println!("Compiler: {}", compiler_type.to_string());
|
||||||
@@ -97,10 +93,7 @@ impl CreateExe {
|
|||||||
generate_header(header_file_src.as_bytes())?;
|
generate_header(header_file_src.as_bytes())?;
|
||||||
self.compile_c(wasm_object_path, output_path)?;
|
self.compile_c(wasm_object_path, output_path)?;
|
||||||
|
|
||||||
eprintln!(
|
eprintln!("✔ Native executable compiled successfully to `{}`.", self.output.display(),);
|
||||||
"✔ Native executable compiled successfully to `{}`.",
|
|
||||||
self.output.display(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -156,11 +149,7 @@ fn generate_header(header_file_src: &[u8]) -> anyhow::Result<()> {
|
|||||||
fn get_wasmer_dir() -> anyhow::Result<PathBuf> {
|
fn get_wasmer_dir() -> anyhow::Result<PathBuf> {
|
||||||
Ok(PathBuf::from(
|
Ok(PathBuf::from(
|
||||||
env::var("WASMER_DIR")
|
env::var("WASMER_DIR")
|
||||||
.or_else(|e| {
|
.or_else(|e| option_env!("WASMER_INSTALL_PREFIX").map(str::to_string).ok_or(e))
|
||||||
option_env!("WASMER_INSTALL_PREFIX")
|
|
||||||
.map(str::to_string)
|
|
||||||
.ok_or(e)
|
|
||||||
})
|
|
||||||
.context("Trying to read env var `WASMER_DIR`")?,
|
.context("Trying to read env var `WASMER_DIR`")?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -268,17 +257,8 @@ impl LinkCode {
|
|||||||
let mut command = Command::new(&self.linker_path);
|
let mut command = Command::new(&self.linker_path);
|
||||||
let command = command
|
let command = command
|
||||||
.arg(&self.optimization_flag)
|
.arg(&self.optimization_flag)
|
||||||
.args(
|
.args(self.object_paths.iter().map(|path| path.canonicalize().unwrap()))
|
||||||
self.object_paths
|
.arg(&self.libwasmer_path.canonicalize().context("Failed to find libwasmer")?);
|
||||||
.iter()
|
|
||||||
.map(|path| path.canonicalize().unwrap()),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
&self
|
|
||||||
.libwasmer_path
|
|
||||||
.canonicalize()
|
|
||||||
.context("Failed to find libwasmer")?,
|
|
||||||
);
|
|
||||||
let command = if let Some(target) = &self.target {
|
let command = if let Some(target) = &self.target {
|
||||||
command.arg("-target").arg(format!("{}", target))
|
command.arg("-target").arg(format!("{}", target))
|
||||||
} else {
|
} else {
|
||||||
@@ -287,18 +267,12 @@ impl LinkCode {
|
|||||||
// Add libraries required per platform.
|
// Add libraries required per platform.
|
||||||
// We need userenv, sockets (Ws2_32), advapi32 for some system calls and bcrypt for random numbers.
|
// We need userenv, sockets (Ws2_32), advapi32 for some system calls and bcrypt for random numbers.
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let command = command
|
let command = command.arg("-luserenv").arg("-lWs2_32").arg("-ladvapi32").arg("-lbcrypt");
|
||||||
.arg("-luserenv")
|
|
||||||
.arg("-lWs2_32")
|
|
||||||
.arg("-ladvapi32")
|
|
||||||
.arg("-lbcrypt");
|
|
||||||
// On unix we need dlopen-related symbols, libmath for a few things, and pthreads.
|
// On unix we need dlopen-related symbols, libmath for a few things, and pthreads.
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let command = command.arg("-ldl").arg("-lm").arg("-pthread");
|
let command = command.arg("-ldl").arg("-lm").arg("-pthread");
|
||||||
let link_aganist_extra_libs = self
|
let link_aganist_extra_libs =
|
||||||
.additional_libraries
|
self.additional_libraries.iter().map(|lib| format!("-l{}", lib));
|
||||||
.iter()
|
|
||||||
.map(|lib| format!("-l{}", lib));
|
|
||||||
let command = command.args(link_aganist_extra_libs);
|
let command = command.args(link_aganist_extra_libs);
|
||||||
let output = command.arg("-o").arg(&self.output_path).output()?;
|
let output = command.arg("-o").arg(&self.output_path).output()?;
|
||||||
|
|
||||||
|
|||||||
@@ -19,21 +19,13 @@ pub struct Inspect {
|
|||||||
impl Inspect {
|
impl Inspect {
|
||||||
/// Runs logic for the `validate` subcommand
|
/// Runs logic for the `validate` subcommand
|
||||||
pub fn execute(&self) -> Result<()> {
|
pub fn execute(&self) -> Result<()> {
|
||||||
self.inner_execute()
|
self.inner_execute().context(format!("failed to inspect `{}`", self.path.display()))
|
||||||
.context(format!("failed to inspect `{}`", self.path.display()))
|
|
||||||
}
|
}
|
||||||
fn inner_execute(&self) -> Result<()> {
|
fn inner_execute(&self) -> Result<()> {
|
||||||
let (store, _engine_type, _compiler_type) = self.store.get_store()?;
|
let (store, _engine_type, _compiler_type) = self.store.get_store()?;
|
||||||
let module_contents = std::fs::read(&self.path)?;
|
let module_contents = std::fs::read(&self.path)?;
|
||||||
let module = Module::new(&store, &module_contents)?;
|
let module = Module::new(&store, &module_contents)?;
|
||||||
println!(
|
println!("Type: {}", if !is_wasm(&module_contents) { "wat" } else { "wasm" });
|
||||||
"Type: {}",
|
|
||||||
if !is_wasm(&module_contents) {
|
|
||||||
"wat"
|
|
||||||
} else {
|
|
||||||
"wasm"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
println!("Size: {}", ByteSize(module_contents.len() as _));
|
println!("Size: {}", ByteSize(module_contents.len() as _));
|
||||||
println!("Imports:");
|
println!("Imports:");
|
||||||
println!(" Functions:");
|
println!(" Functions:");
|
||||||
|
|||||||
@@ -80,11 +80,7 @@ impl Run {
|
|||||||
format!(
|
format!(
|
||||||
"failed to run `{}`{}",
|
"failed to run `{}`{}",
|
||||||
self.path.display(),
|
self.path.display(),
|
||||||
if CompilerType::enabled().is_empty() {
|
if CompilerType::enabled().is_empty() { " (no compilers enabled)" } else { "" }
|
||||||
" (no compilers enabled)"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -98,11 +94,7 @@ impl Run {
|
|||||||
let result = self.invoke_function(&instance, &invoke, &self.args)?;
|
let result = self.invoke_function(&instance, &invoke, &self.args)?;
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
result
|
result.iter().map(|val| val.to_string()).collect::<Vec<String>>().join(" ")
|
||||||
.iter()
|
|
||||||
.map(|val| val.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(" ")
|
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -157,11 +149,7 @@ impl Run {
|
|||||||
let program_name = self
|
let program_name = self
|
||||||
.command_name
|
.command_name
|
||||||
.clone()
|
.clone()
|
||||||
.or_else(|| {
|
.or_else(|| self.path.file_name().map(|f| f.to_string_lossy().to_string()))
|
||||||
self.path
|
|
||||||
.file_name()
|
|
||||||
.map(|f| f.to_string_lossy().to_string())
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
return self
|
return self
|
||||||
.wasi
|
.wasi
|
||||||
@@ -359,31 +347,19 @@ impl Run {
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(func_ty.params().iter())
|
.zip(func_ty.params().iter())
|
||||||
.map(|(arg, param_type)| match param_type {
|
.map(|(arg, param_type)| match param_type {
|
||||||
ValType::I32 => {
|
ValType::I32 => Ok(Val::I32(
|
||||||
Ok(Val::I32(arg.parse().map_err(|_| {
|
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a i32", arg))?,
|
||||||
anyhow!("Can't convert `{}` into a i32", arg)
|
|
||||||
})?))
|
|
||||||
}
|
|
||||||
ValType::I64 => {
|
|
||||||
Ok(Val::I64(arg.parse().map_err(|_| {
|
|
||||||
anyhow!("Can't convert `{}` into a i64", arg)
|
|
||||||
})?))
|
|
||||||
}
|
|
||||||
ValType::F32 => {
|
|
||||||
Ok(Val::F32(arg.parse().map_err(|_| {
|
|
||||||
anyhow!("Can't convert `{}` into a f32", arg)
|
|
||||||
})?))
|
|
||||||
}
|
|
||||||
ValType::F64 => {
|
|
||||||
Ok(Val::F64(arg.parse().map_err(|_| {
|
|
||||||
anyhow!("Can't convert `{}` into a f64", arg)
|
|
||||||
})?))
|
|
||||||
}
|
|
||||||
_ => Err(anyhow!(
|
|
||||||
"Don't know how to convert {} into {:?}",
|
|
||||||
arg,
|
|
||||||
param_type
|
|
||||||
)),
|
)),
|
||||||
|
ValType::I64 => Ok(Val::I64(
|
||||||
|
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a i64", arg))?,
|
||||||
|
)),
|
||||||
|
ValType::F32 => Ok(Val::F32(
|
||||||
|
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a f32", arg))?,
|
||||||
|
)),
|
||||||
|
ValType::F64 => Ok(Val::F64(
|
||||||
|
arg.parse().map_err(|_| anyhow!("Can't convert `{}` into a f64", arg))?,
|
||||||
|
)),
|
||||||
|
_ => Err(anyhow!("Don't know how to convert {} into {:?}", arg, param_type)),
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
Ok(func.call(&invoke_args)?)
|
Ok(func.call(&invoke_args)?)
|
||||||
|
|||||||
@@ -23,10 +23,8 @@ impl SelfUpdate {
|
|||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
|
|
||||||
let mut process = Command::new("sh")
|
let mut process =
|
||||||
.stdin(cmd.stdout.unwrap())
|
Command::new("sh").stdin(cmd.stdout.unwrap()).stdout(Stdio::inherit()).spawn()?;
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.spawn()?;
|
|
||||||
|
|
||||||
process.wait().unwrap();
|
process.wait().unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ pub struct Validate {
|
|||||||
impl Validate {
|
impl Validate {
|
||||||
/// Runs logic for the `validate` subcommand
|
/// Runs logic for the `validate` subcommand
|
||||||
pub fn execute(&self) -> Result<()> {
|
pub fn execute(&self) -> Result<()> {
|
||||||
self.inner_execute()
|
self.inner_execute().context(format!("failed to validate `{}`", self.path.display()))
|
||||||
.context(format!("failed to validate `{}`", self.path.display()))
|
|
||||||
}
|
}
|
||||||
fn inner_execute(&self) -> Result<()> {
|
fn inner_execute(&self) -> Result<()> {
|
||||||
let (store, _engine_type, _compiler_type) = self.store.get_store()?;
|
let (store, _engine_type, _compiler_type) = self.store.get_store()?;
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ pub struct Wast {
|
|||||||
impl Wast {
|
impl Wast {
|
||||||
/// Runs logic for the `validate` subcommand
|
/// Runs logic for the `validate` subcommand
|
||||||
pub fn execute(&self) -> Result<()> {
|
pub fn execute(&self) -> Result<()> {
|
||||||
self.inner_execute()
|
self.inner_execute().context(format!("failed to test the wast `{}`", self.path.display()))
|
||||||
.context(format!("failed to test the wast `{}`", self.path.display()))
|
|
||||||
}
|
}
|
||||||
fn inner_execute(&self) -> Result<()> {
|
fn inner_execute(&self) -> Result<()> {
|
||||||
let (store, _engine_name, _compiler_name) = self.store.get_store()?;
|
let (store, _engine_name, _compiler_name) = self.store.get_store()?;
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ use std::time;
|
|||||||
|
|
||||||
/// Subroutine to instantiate the loggers
|
/// Subroutine to instantiate the loggers
|
||||||
pub fn set_up_logging() -> Result<(), String> {
|
pub fn set_up_logging() -> Result<(), String> {
|
||||||
let colors_line = ColoredLevelConfig::new()
|
let colors_line =
|
||||||
.error(Color::Red)
|
ColoredLevelConfig::new().error(Color::Red).warn(Color::Yellow).trace(Color::BrightBlack);
|
||||||
.warn(Color::Yellow)
|
|
||||||
.trace(Color::BrightBlack);
|
|
||||||
let should_color = wasmer_should_print_color();
|
let should_color = wasmer_should_print_color();
|
||||||
|
|
||||||
let colors_level = colors_line.info(Color::Green);
|
let colors_level = colors_line.info(Color::Green);
|
||||||
|
|||||||
@@ -73,10 +73,7 @@ impl CompilerOptions {
|
|||||||
} else if self.singlepass {
|
} else if self.singlepass {
|
||||||
Ok(CompilerType::Singlepass)
|
Ok(CompilerType::Singlepass)
|
||||||
} else if let Some(backend) = self.backend.clone() {
|
} else if let Some(backend) = self.backend.clone() {
|
||||||
warning!(
|
warning!("the `--backend={0}` flag is deprecated, please use `--{0}` instead", backend);
|
||||||
"the `--backend={0}` flag is deprecated, please use `--{0}` instead",
|
|
||||||
backend
|
|
||||||
);
|
|
||||||
CompilerType::from_str(&backend)
|
CompilerType::from_str(&backend)
|
||||||
} else {
|
} else {
|
||||||
// Auto mode, we choose the best compiler for that platform
|
// Auto mode, we choose the best compiler for that platform
|
||||||
@@ -158,10 +155,7 @@ impl CompilerOptions {
|
|||||||
.engine(),
|
.engine(),
|
||||||
),
|
),
|
||||||
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
|
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
|
||||||
engine => bail!(
|
engine => bail!("The `{}` engine is not included in this binary.", engine.to_string()),
|
||||||
"The `{}` engine is not included in this binary.",
|
|
||||||
engine.to_string()
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(engine)
|
Ok(engine)
|
||||||
@@ -293,10 +287,9 @@ impl CompilerOptions {
|
|||||||
Box::new(config)
|
Box::new(config)
|
||||||
}
|
}
|
||||||
#[cfg(not(all(feature = "singlepass", feature = "cranelift", feature = "llvm",)))]
|
#[cfg(not(all(feature = "singlepass", feature = "cranelift", feature = "llvm",)))]
|
||||||
compiler => bail!(
|
compiler => {
|
||||||
"The `{}` compiler is not included in this binary.",
|
bail!("The `{}` compiler is not included in this binary.", compiler.to_string())
|
||||||
compiler.to_string()
|
}
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
@@ -401,9 +394,7 @@ impl StoreOptions {
|
|||||||
compiler_config: Box<dyn CompilerConfig>,
|
compiler_config: Box<dyn CompilerConfig>,
|
||||||
) -> Result<(Box<dyn Engine + Send + Sync>, EngineType)> {
|
) -> Result<(Box<dyn Engine + Send + Sync>, EngineType)> {
|
||||||
let engine_type = self.get_engine()?;
|
let engine_type = self.get_engine()?;
|
||||||
let engine = self
|
let engine = self.compiler.get_engine_by_type(target, compiler_config, engine_type)?;
|
||||||
.compiler
|
|
||||||
.get_engine_by_type(target, compiler_config, engine_type)?;
|
|
||||||
|
|
||||||
Ok((engine, engine_type))
|
Ok((engine, engine_type))
|
||||||
}
|
}
|
||||||
@@ -448,10 +439,7 @@ impl StoreOptions {
|
|||||||
Arc::new(wasmer_engine_object_file::ObjectFile::headless().engine())
|
Arc::new(wasmer_engine_object_file::ObjectFile::headless().engine())
|
||||||
}
|
}
|
||||||
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
|
#[cfg(not(all(feature = "jit", feature = "native", feature = "object-file")))]
|
||||||
engine => bail!(
|
engine => bail!("The `{}` engine is not included in this binary.", engine.to_string()),
|
||||||
"The `{}` engine is not included in this binary.",
|
|
||||||
engine.to_string()
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
Ok((engine, engine_type))
|
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").unwrap(), ("A".into(), "B".into()));
|
||||||
assert_eq!(parse_envvar(" A=B\t").unwrap(), ("A".into(), "B".into()));
|
assert_eq!(parse_envvar(" A=B\t").unwrap(), ("A".into(), "B".into()));
|
||||||
assert_eq!(
|
assert_eq!(parse_envvar("A=B=C=D").unwrap(), ("A".into(), "B=C=D".into()));
|
||||||
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 start_srcloc = SourceLoc::new(data.module_offset as u32);
|
||||||
let end_srcloc = SourceLoc::new((data.module_offset + data.data.len()) as u32);
|
let end_srcloc = SourceLoc::new((data.module_offset + data.data.len()) as u32);
|
||||||
|
|
||||||
FunctionAddressMap {
|
FunctionAddressMap { instructions, start_srcloc, end_srcloc, body_offset: 0, body_len }
|
||||||
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);
|
let func_jt_offsets = transform_jump_table(context.func.jt_offsets);
|
||||||
|
|
||||||
Ok(CompiledFunction {
|
Ok(CompiledFunction {
|
||||||
body: FunctionBody {
|
body: FunctionBody { body: code_buf, unwind_info },
|
||||||
body: code_buf,
|
|
||||||
unwind_info,
|
|
||||||
},
|
|
||||||
jt_offsets: func_jt_offsets,
|
jt_offsets: func_jt_offsets,
|
||||||
relocations: reloc_sink.func_relocs,
|
relocations: reloc_sink.func_relocs,
|
||||||
frame_info: CompiledFunctionFrameInfo {
|
frame_info: CompiledFunctionFrameInfo { address_map, traps: trap_sink.traps },
|
||||||
address_map,
|
|
||||||
traps: trap_sink.traps,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, CompileError>>()?
|
.collect::<Result<Vec<_>, CompileError>>()?
|
||||||
@@ -199,11 +193,7 @@ impl Compiler for CraneliftCompiler {
|
|||||||
let mut custom_sections = PrimaryMap::new();
|
let mut custom_sections = PrimaryMap::new();
|
||||||
let dwarf = if let Some((dwarf_frametable, _cie_id)) = dwarf_frametable {
|
let dwarf = if let Some((dwarf_frametable, _cie_id)) = dwarf_frametable {
|
||||||
let mut eh_frame = EhFrame(WriterRelocate::new(target.triple().endianness().ok()));
|
let mut eh_frame = EhFrame(WriterRelocate::new(target.triple().endianness().ok()));
|
||||||
dwarf_frametable
|
dwarf_frametable.lock().unwrap().write_eh_frame(&mut eh_frame).unwrap();
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.write_eh_frame(&mut eh_frame)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let eh_frame_section = eh_frame.0.into_section();
|
let eh_frame_section = eh_frame.0.into_section();
|
||||||
custom_sections.push(eh_frame_section);
|
custom_sections.push(eh_frame_section);
|
||||||
|
|||||||
@@ -113,14 +113,10 @@ impl Cranelift {
|
|||||||
builder.enable("has_avx2").expect("should be valid flag");
|
builder.enable("has_avx2").expect("should be valid flag");
|
||||||
}
|
}
|
||||||
if cpu_features.contains(CpuFeature::AVX512DQ) {
|
if cpu_features.contains(CpuFeature::AVX512DQ) {
|
||||||
builder
|
builder.enable("has_avx512dq").expect("should be valid flag");
|
||||||
.enable("has_avx512dq")
|
|
||||||
.expect("should be valid flag");
|
|
||||||
}
|
}
|
||||||
if cpu_features.contains(CpuFeature::AVX512VL) {
|
if cpu_features.contains(CpuFeature::AVX512VL) {
|
||||||
builder
|
builder.enable("has_avx512vl").expect("should be valid flag");
|
||||||
.enable("has_avx512vl")
|
|
||||||
.expect("should be valid flag");
|
|
||||||
}
|
}
|
||||||
if cpu_features.contains(CpuFeature::LZCNT) {
|
if cpu_features.contains(CpuFeature::LZCNT) {
|
||||||
builder.enable("has_lzcnt").expect("should be valid flag");
|
builder.enable("has_lzcnt").expect("should be valid flag");
|
||||||
@@ -135,26 +131,16 @@ impl Cranelift {
|
|||||||
|
|
||||||
// There are two possible traps for division, and this way
|
// There are two possible traps for division, and this way
|
||||||
// we get the proper one if code traps.
|
// we get the proper one if code traps.
|
||||||
flags
|
flags.enable("avoid_div_traps").expect("should be valid flag");
|
||||||
.enable("avoid_div_traps")
|
|
||||||
.expect("should be valid flag");
|
|
||||||
|
|
||||||
if self.enable_pic {
|
if self.enable_pic {
|
||||||
flags.enable("is_pic").expect("should be a valid flag");
|
flags.enable("is_pic").expect("should be a valid flag");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invert cranelift's default-on verification to instead default off.
|
// Invert cranelift's default-on verification to instead default off.
|
||||||
let enable_verifier = if self.enable_verifier {
|
let enable_verifier = if self.enable_verifier { "true" } else { "false" };
|
||||||
"true"
|
flags.set("enable_verifier", enable_verifier).expect("should be valid flag");
|
||||||
} else {
|
flags.set("enable_safepoints", "true").expect("should be valid flag");
|
||||||
"false"
|
|
||||||
};
|
|
||||||
flags
|
|
||||||
.set("enable_verifier", enable_verifier)
|
|
||||||
.expect("should be valid flag");
|
|
||||||
flags
|
|
||||||
.set("enable_safepoints", "true")
|
|
||||||
.expect("should be valid flag");
|
|
||||||
|
|
||||||
let opt_level = if self.enable_simd {
|
let opt_level = if self.enable_simd {
|
||||||
"none"
|
"none"
|
||||||
@@ -166,20 +152,13 @@ impl Cranelift {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
flags
|
flags.set("opt_level", opt_level).expect("should be valid flag");
|
||||||
.set("opt_level", opt_level)
|
|
||||||
.expect("should be valid flag");
|
|
||||||
|
|
||||||
let enable_simd = if self.enable_simd { "true" } else { "false" };
|
let enable_simd = if self.enable_simd { "true" } else { "false" };
|
||||||
flags
|
flags.set("enable_simd", enable_simd).expect("should be valid flag");
|
||||||
.set("enable_simd", enable_simd)
|
|
||||||
.expect("should be valid flag");
|
|
||||||
|
|
||||||
let enable_nan_canonicalization = if self.enable_nan_canonicalization {
|
let enable_nan_canonicalization =
|
||||||
"true"
|
if self.enable_nan_canonicalization { "true" } else { "false" };
|
||||||
} else {
|
|
||||||
"false"
|
|
||||||
};
|
|
||||||
flags
|
flags
|
||||||
.set("enable_nan_canonicalization", enable_nan_canonicalization)
|
.set("enable_nan_canonicalization", enable_nan_canonicalization)
|
||||||
.expect("should be valid flag");
|
.expect("should be valid flag");
|
||||||
|
|||||||
@@ -20,10 +20,7 @@ impl WriterRelocate {
|
|||||||
// We autodetect it, based on the host
|
// We autodetect it, based on the host
|
||||||
None => RunTimeEndian::default(),
|
None => RunTimeEndian::default(),
|
||||||
};
|
};
|
||||||
WriterRelocate {
|
WriterRelocate { relocs: Vec::new(), writer: EndianVec::new(endianness) }
|
||||||
relocs: Vec::new(),
|
|
||||||
writer: EndianVec::new(endianness),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_section(mut self) -> CustomSection {
|
pub fn into_section(mut self) -> CustomSection {
|
||||||
@@ -72,12 +69,7 @@ impl Writer for WriterRelocate {
|
|||||||
_ => unimplemented!("dwarf relocation size not yet supported: {}", size),
|
_ => unimplemented!("dwarf relocation size not yet supported: {}", size),
|
||||||
};
|
};
|
||||||
let addend = 0;
|
let addend = 0;
|
||||||
self.relocs.push(Relocation {
|
self.relocs.push(Relocation { kind, reloc_target, offset, addend });
|
||||||
kind,
|
|
||||||
reloc_target,
|
|
||||||
offset,
|
|
||||||
addend,
|
|
||||||
});
|
|
||||||
self.write_udata(addend as u64, size)
|
self.write_udata(addend as u64, size)
|
||||||
} else {
|
} else {
|
||||||
unreachable!("Symbol {} in DWARF not recognized", symbol);
|
unreachable!("Symbol {} in DWARF not recognized", symbol);
|
||||||
|
|||||||
@@ -223,10 +223,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
) -> (ir::SigRef, VMBuiltinFunctionIndex) {
|
) -> (ir::SigRef, VMBuiltinFunctionIndex) {
|
||||||
(
|
(self.get_externref_inc_sig(func), VMBuiltinFunctionIndex::get_externref_inc_index())
|
||||||
self.get_externref_inc_sig(func),
|
|
||||||
VMBuiltinFunctionIndex::get_externref_inc_index(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_externref_dec_sig(&mut self, func: &mut Function) -> ir::SigRef {
|
fn get_externref_dec_sig(&mut self, func: &mut Function) -> ir::SigRef {
|
||||||
@@ -245,10 +242,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
) -> (ir::SigRef, VMBuiltinFunctionIndex) {
|
) -> (ir::SigRef, VMBuiltinFunctionIndex) {
|
||||||
(
|
(self.get_externref_dec_sig(func), VMBuiltinFunctionIndex::get_externref_dec_index())
|
||||||
self.get_externref_dec_sig(func),
|
|
||||||
VMBuiltinFunctionIndex::get_externref_dec_index(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_func_ref_sig(&mut self, func: &mut Function) -> ir::SigRef {
|
fn get_func_ref_sig(&mut self, func: &mut Function) -> ir::SigRef {
|
||||||
@@ -573,11 +567,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
||||||
let sig = self.get_table_init_sig(func);
|
let sig = self.get_table_init_sig(func);
|
||||||
let table_index = table_index.as_u32() as usize;
|
let table_index = table_index.as_u32() as usize;
|
||||||
(
|
(sig, table_index, VMBuiltinFunctionIndex::get_table_init_index())
|
||||||
sig,
|
|
||||||
table_index,
|
|
||||||
VMBuiltinFunctionIndex::get_table_init_index(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_elem_drop_sig(&mut self, func: &mut Function) -> ir::SigRef {
|
fn get_elem_drop_sig(&mut self, func: &mut Function) -> ir::SigRef {
|
||||||
@@ -630,17 +620,9 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
||||||
let sig = self.get_memory_copy_sig(func);
|
let sig = self.get_memory_copy_sig(func);
|
||||||
if let Some(local_memory_index) = self.module.local_memory_index(memory_index) {
|
if let Some(local_memory_index) = self.module.local_memory_index(memory_index) {
|
||||||
(
|
(sig, local_memory_index.index(), VMBuiltinFunctionIndex::get_memory_copy_index())
|
||||||
sig,
|
|
||||||
local_memory_index.index(),
|
|
||||||
VMBuiltinFunctionIndex::get_memory_copy_index(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
(
|
(sig, memory_index.index(), VMBuiltinFunctionIndex::get_imported_memory_copy_index())
|
||||||
sig,
|
|
||||||
memory_index.index(),
|
|
||||||
VMBuiltinFunctionIndex::get_imported_memory_copy_index(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,17 +655,9 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
) -> (ir::SigRef, usize, VMBuiltinFunctionIndex) {
|
||||||
let sig = self.get_memory_fill_sig(func);
|
let sig = self.get_memory_fill_sig(func);
|
||||||
if let Some(local_memory_index) = self.module.local_memory_index(memory_index) {
|
if let Some(local_memory_index) = self.module.local_memory_index(memory_index) {
|
||||||
(
|
(sig, local_memory_index.index(), VMBuiltinFunctionIndex::get_memory_fill_index())
|
||||||
sig,
|
|
||||||
local_memory_index.index(),
|
|
||||||
VMBuiltinFunctionIndex::get_memory_fill_index(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
(
|
(sig, memory_index.index(), VMBuiltinFunctionIndex::get_imported_memory_fill_index())
|
||||||
sig,
|
|
||||||
memory_index.index(),
|
|
||||||
VMBuiltinFunctionIndex::get_imported_memory_fill_index(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,8 +759,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
let base_offset =
|
let base_offset =
|
||||||
i32::try_from(self.offsets.vmctx_vmtable_definition_base(def_index)).unwrap();
|
i32::try_from(self.offsets.vmctx_vmtable_definition_base(def_index)).unwrap();
|
||||||
let current_elements_offset = i32::try_from(
|
let current_elements_offset = i32::try_from(
|
||||||
self.offsets
|
self.offsets.vmctx_vmtable_definition_current_elements(def_index),
|
||||||
.vmctx_vmtable_definition_current_elements(def_index),
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(vmctx, base_offset, current_elements_offset)
|
(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 (func_sig, index_arg, func_idx) = self.get_table_grow_func(&mut pos.func, table_index);
|
||||||
let table_index = pos.ins().iconst(I32, index_arg as i64);
|
let table_index = pos.ins().iconst(I32, index_arg as i64);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
let call_inst = pos.ins().call_indirect(
|
let call_inst =
|
||||||
func_sig,
|
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, init_value, delta, table_index]);
|
||||||
func_addr,
|
|
||||||
&[vmctx, init_value, delta, table_index],
|
|
||||||
);
|
|
||||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,9 +833,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
self.get_table_get_func(&mut pos.func, table_index);
|
self.get_table_get_func(&mut pos.func, table_index);
|
||||||
let table_index = pos.ins().iconst(I32, table_index_arg as i64);
|
let table_index = pos.ins().iconst(I32, table_index_arg as i64);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
let call_inst = pos
|
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index, index]);
|
||||||
.ins()
|
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, table_index, index]);
|
|
||||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,8 +851,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
self.get_table_set_func(&mut pos.func, table_index);
|
self.get_table_set_func(&mut pos.func, table_index);
|
||||||
let table_index = pos.ins().iconst(I32, table_index_arg as i64);
|
let table_index = pos.ins().iconst(I32, table_index_arg as i64);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
pos.ins()
|
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index, index, value]);
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, table_index, index, value]);
|
|
||||||
Ok(())
|
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 (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
|
|
||||||
let table_index_arg = pos.ins().iconst(I32, table_index_arg as i64);
|
let table_index_arg = pos.ins().iconst(I32, table_index_arg as i64);
|
||||||
pos.ins().call_indirect(
|
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index_arg, dst, val, len]);
|
||||||
func_sig,
|
|
||||||
func_addr,
|
|
||||||
&[vmctx, table_index_arg, dst, val, len],
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -962,8 +925,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
ty if ty.is_ref() => pos.ins().is_null(value),
|
ty if ty.is_ref() => pos.ins().is_null(value),
|
||||||
// `funcref`
|
// `funcref`
|
||||||
ty if ty == self.pointer_type() => {
|
ty if ty == self.pointer_type() => {
|
||||||
pos.ins()
|
pos.ins().icmp_imm(cranelift_codegen::ir::condcodes::IntCC::Equal, value, 0)
|
||||||
.icmp_imm(cranelift_codegen::ir::condcodes::IntCC::Equal, value, 0)
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => 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 (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
|
|
||||||
let func_index_arg = pos.ins().iconst(I32, func_index_arg as i64);
|
let func_index_arg = pos.ins().iconst(I32, func_index_arg as i64);
|
||||||
let call_inst = pos
|
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, func_index_arg]);
|
||||||
.ins()
|
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, func_index_arg]);
|
|
||||||
|
|
||||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||||
}
|
}
|
||||||
@@ -1021,11 +981,9 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
if let Some(def_index) = self.module.local_memory_index(index) {
|
if let Some(def_index) = self.module.local_memory_index(index) {
|
||||||
let base_offset =
|
let base_offset =
|
||||||
i32::try_from(self.offsets.vmctx_vmmemory_definition_base(def_index)).unwrap();
|
i32::try_from(self.offsets.vmctx_vmmemory_definition_base(def_index)).unwrap();
|
||||||
let current_length_offset = i32::try_from(
|
let current_length_offset =
|
||||||
self.offsets
|
i32::try_from(self.offsets.vmctx_vmmemory_definition_current_length(def_index))
|
||||||
.vmctx_vmmemory_definition_current_length(def_index),
|
.unwrap();
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
(vmctx, base_offset, current_length_offset)
|
(vmctx, base_offset, current_length_offset)
|
||||||
} else {
|
} else {
|
||||||
let from_offset = self.offsets.vmctx_vmmemory_import_definition(index);
|
let from_offset = self.offsets.vmctx_vmmemory_import_definition(index);
|
||||||
@@ -1054,20 +1012,13 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
});
|
});
|
||||||
(
|
(
|
||||||
Uimm64::new(offset_guard_size),
|
Uimm64::new(offset_guard_size),
|
||||||
ir::HeapStyle::Dynamic {
|
ir::HeapStyle::Dynamic { bound_gv: heap_bound },
|
||||||
bound_gv: heap_bound,
|
|
||||||
},
|
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
MemoryStyle::Static {
|
MemoryStyle::Static { bound, offset_guard_size } => (
|
||||||
bound,
|
|
||||||
offset_guard_size,
|
|
||||||
} => (
|
|
||||||
Uimm64::new(offset_guard_size),
|
Uimm64::new(offset_guard_size),
|
||||||
ir::HeapStyle::Static {
|
ir::HeapStyle::Static { bound: Uimm64::new(bound.bytes().0 as u64) },
|
||||||
bound: Uimm64::new(bound.bytes().0 as u64),
|
|
||||||
},
|
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -1167,8 +1118,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
);
|
);
|
||||||
|
|
||||||
// check if the funcref is null
|
// check if the funcref is null
|
||||||
pos.ins()
|
pos.ins().trapz(table_entry_addr, ir::TrapCode::IndirectCallToNull);
|
||||||
.trapz(table_entry_addr, ir::TrapCode::IndirectCallToNull);
|
|
||||||
|
|
||||||
let func_addr = pos.ins().load(
|
let func_addr = pos.ins().load(
|
||||||
pointer_type,
|
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 (func_sig, index_arg, func_idx) = self.get_memory_grow_func(&mut pos.func, index);
|
||||||
let memory_index = pos.ins().iconst(I32, index_arg as i64);
|
let memory_index = pos.ins().iconst(I32, index_arg as i64);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
let call_inst = pos
|
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, val, memory_index]);
|
||||||
.ins()
|
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, val, memory_index]);
|
|
||||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 (func_sig, index_arg, func_idx) = self.get_memory_size_func(&mut pos.func, index);
|
||||||
let memory_index = pos.ins().iconst(I32, index_arg as i64);
|
let memory_index = pos.ins().iconst(I32, index_arg as i64);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
let call_inst = pos
|
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, memory_index]);
|
||||||
.ins()
|
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, memory_index]);
|
|
||||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
|
|
||||||
pos.ins()
|
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, src_index_arg, dst, src, len]);
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, src_index_arg, dst, src, len]);
|
|
||||||
|
|
||||||
Ok(())
|
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);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
|
|
||||||
pos.ins().call_indirect(
|
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, memory_index_arg, dst, val, len]);
|
||||||
func_sig,
|
|
||||||
func_addr,
|
|
||||||
&[vmctx, memory_index_arg, dst, val, len],
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
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 (func_sig, func_idx) = self.get_data_drop_func(&mut pos.func);
|
||||||
let seg_index_arg = pos.ins().iconst(I32, seg_index as i64);
|
let seg_index_arg = pos.ins().iconst(I32, seg_index as i64);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
pos.ins()
|
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, seg_index_arg]);
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, seg_index_arg]);
|
|
||||||
Ok(())
|
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 (func_sig, index_arg, func_idx) = self.get_table_size_func(&mut pos.func, table_index);
|
||||||
let table_index = pos.ins().iconst(I32, index_arg as i64);
|
let table_index = pos.ins().iconst(I32, index_arg as i64);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
let call_inst = pos
|
let call_inst = pos.ins().call_indirect(func_sig, func_addr, &[vmctx, table_index]);
|
||||||
.ins()
|
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, table_index]);
|
|
||||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1424,14 +1362,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
pos.ins().call_indirect(
|
pos.ins().call_indirect(
|
||||||
func_sig,
|
func_sig,
|
||||||
func_addr,
|
func_addr,
|
||||||
&[
|
&[vmctx, dst_table_index_arg, src_table_index_arg, dst, src, len],
|
||||||
vmctx,
|
|
||||||
dst_table_index_arg,
|
|
||||||
src_table_index_arg,
|
|
||||||
dst,
|
|
||||||
src,
|
|
||||||
len,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -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);
|
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
||||||
|
|
||||||
pos.ins()
|
pos.ins().call_indirect(func_sig, func_addr, &[vmctx, elem_index_arg]);
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, elem_index_arg]);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1486,9 +1416,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
_expected: ir::Value,
|
_expected: ir::Value,
|
||||||
_timeout: ir::Value,
|
_timeout: ir::Value,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported("wasm atomics (fn translate_atomic_wait)".to_string()))
|
||||||
"wasm atomics (fn translate_atomic_wait)".to_string(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_atomic_notify(
|
fn translate_atomic_notify(
|
||||||
@@ -1499,9 +1427,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro
|
|||||||
_addr: ir::Value,
|
_addr: ir::Value,
|
||||||
_count: ir::Value,
|
_count: ir::Value,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
Err(WasmError::Unsupported(
|
Err(WasmError::Unsupported("wasm atomics (fn translate_atomic_notify)".to_string()))
|
||||||
"wasm atomics (fn translate_atomic_notify)".to_string(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_global_type(&self, global_index: GlobalIndex) -> Option<WasmerType> {
|
fn get_global_type(&self, global_index: GlobalIndex) -> Option<WasmerType> {
|
||||||
|
|||||||
@@ -75,14 +75,9 @@ impl<'a> binemit::RelocSink for RelocSink<'a> {
|
|||||||
impl<'a> RelocSink<'a> {
|
impl<'a> RelocSink<'a> {
|
||||||
/// Return a new `RelocSink` instance.
|
/// Return a new `RelocSink` instance.
|
||||||
pub fn new(module: &'a ModuleInfo, func_index: FunctionIndex) -> Self {
|
pub fn new(module: &'a ModuleInfo, func_index: FunctionIndex) -> Self {
|
||||||
let local_func_index = module
|
let local_func_index =
|
||||||
.local_func_index(func_index)
|
module.local_func_index(func_index).expect("The provided function should be local");
|
||||||
.expect("The provided function should be local");
|
Self { module, local_func_index, func_relocs: Vec::new() }
|
||||||
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 signature = signature_to_cranelift_ir(func_type, frontend_config);
|
||||||
let mut stub_sig = ir::Signature::new(frontend_config.default_call_conv);
|
let mut stub_sig = ir::Signature::new(frontend_config.default_call_conv);
|
||||||
// Add the caller `vmctx` parameter.
|
// Add the caller `vmctx` parameter.
|
||||||
stub_sig.params.push(ir::AbiParam::special(
|
stub_sig.params.push(ir::AbiParam::special(pointer_type, ir::ArgumentPurpose::VMContext));
|
||||||
pointer_type,
|
|
||||||
ir::ArgumentPurpose::VMContext,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Add the `values_vec` parameter.
|
// Add the `values_vec` parameter.
|
||||||
stub_sig.params.push(ir::AbiParam::new(pointer_type));
|
stub_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||||
@@ -48,10 +45,9 @@ pub fn make_trampoline_dynamic_function(
|
|||||||
let mut context = Context::new();
|
let mut context = Context::new();
|
||||||
context.func = Function::with_name_signature(ExternalName::user(0, 0), signature.clone());
|
context.func = Function::with_name_signature(ExternalName::user(0, 0), signature.clone());
|
||||||
|
|
||||||
let ss = context.func.create_stack_slot(StackSlotData::new(
|
let ss = context
|
||||||
StackSlotKind::ExplicitSlot,
|
.func
|
||||||
values_vec_len,
|
.create_stack_slot(StackSlotData::new(StackSlotKind::ExplicitSlot, values_vec_len));
|
||||||
));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut builder = FunctionBuilder::new(&mut context.func, fn_builder_ctx);
|
let mut builder = FunctionBuilder::new(&mut context.func, fn_builder_ctx);
|
||||||
@@ -66,12 +62,7 @@ pub fn make_trampoline_dynamic_function(
|
|||||||
// We only get the non-vmctx arguments
|
// We only get the non-vmctx arguments
|
||||||
for i in 1..signature.params.len() {
|
for i in 1..signature.params.len() {
|
||||||
let val = builder.func.dfg.block_params(block0)[i];
|
let val = builder.func.dfg.block_params(block0)[i];
|
||||||
builder.ins().store(
|
builder.ins().store(mflags, val, values_vec_ptr_val, ((i - 1) * value_size) as i32);
|
||||||
mflags,
|
|
||||||
val,
|
|
||||||
values_vec_ptr_val,
|
|
||||||
((i - 1) * value_size) as i32,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let block_params = builder.func.dfg.block_params(block0);
|
let block_params = builder.func.dfg.block_params(block0);
|
||||||
@@ -88,9 +79,7 @@ pub fn make_trampoline_dynamic_function(
|
|||||||
offsets.vmdynamicfunction_import_context_address() as i32,
|
offsets.vmdynamicfunction_import_context_address() as i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
builder
|
builder.ins().call_indirect(new_sig, callee_value, &callee_args);
|
||||||
.ins()
|
|
||||||
.call_indirect(new_sig, callee_value, &callee_args);
|
|
||||||
|
|
||||||
let mflags = MemFlags::trusted();
|
let mflags = MemFlags::trusted();
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
@@ -112,19 +101,10 @@ pub fn make_trampoline_dynamic_function(
|
|||||||
let mut trap_sink = binemit::NullTrapSink {};
|
let mut trap_sink = binemit::NullTrapSink {};
|
||||||
let mut stackmap_sink = binemit::NullStackMapSink {};
|
let mut stackmap_sink = binemit::NullStackMapSink {};
|
||||||
context
|
context
|
||||||
.compile_and_emit(
|
.compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink, &mut stackmap_sink)
|
||||||
isa,
|
|
||||||
&mut code_buf,
|
|
||||||
&mut reloc_sink,
|
|
||||||
&mut trap_sink,
|
|
||||||
&mut stackmap_sink,
|
|
||||||
)
|
|
||||||
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
|
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
|
||||||
|
|
||||||
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
|
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
|
||||||
|
|
||||||
Ok(FunctionBody {
|
Ok(FunctionBody { body: code_buf, unwind_info })
|
||||||
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);
|
let mut wrapper_sig = ir::Signature::new(frontend_config.default_call_conv);
|
||||||
|
|
||||||
// Add the callee `vmctx` parameter.
|
// Add the callee `vmctx` parameter.
|
||||||
wrapper_sig.params.push(ir::AbiParam::special(
|
wrapper_sig.params.push(ir::AbiParam::special(pointer_type, ir::ArgumentPurpose::VMContext));
|
||||||
pointer_type,
|
|
||||||
ir::ArgumentPurpose::VMContext,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Add the `callee_address` parameter.
|
// Add the `callee_address` parameter.
|
||||||
wrapper_sig.params.push(ir::AbiParam::new(pointer_type));
|
wrapper_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||||
@@ -87,18 +84,14 @@ pub fn make_trampoline_function_call(
|
|||||||
|
|
||||||
let new_sig = builder.import_signature(signature);
|
let new_sig = builder.import_signature(signature);
|
||||||
|
|
||||||
let call = builder
|
let call = builder.ins().call_indirect(new_sig, callee_value, &callee_args);
|
||||||
.ins()
|
|
||||||
.call_indirect(new_sig, callee_value, &callee_args);
|
|
||||||
|
|
||||||
let results = builder.func.dfg.inst_results(call).to_vec();
|
let results = builder.func.dfg.inst_results(call).to_vec();
|
||||||
|
|
||||||
// Store the return values into `values_vec`.
|
// Store the return values into `values_vec`.
|
||||||
let mflags = ir::MemFlags::trusted();
|
let mflags = ir::MemFlags::trusted();
|
||||||
for (i, r) in results.iter().enumerate() {
|
for (i, r) in results.iter().enumerate() {
|
||||||
builder
|
builder.ins().store(mflags, *r, values_vec_ptr_val, (i * value_size) as i32);
|
||||||
.ins()
|
|
||||||
.store(mflags, *r, values_vec_ptr_val, (i * value_size) as i32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.ins().return_(&[]);
|
builder.ins().return_(&[]);
|
||||||
@@ -111,13 +104,7 @@ pub fn make_trampoline_function_call(
|
|||||||
let mut stackmap_sink = binemit::NullStackMapSink {};
|
let mut stackmap_sink = binemit::NullStackMapSink {};
|
||||||
|
|
||||||
context
|
context
|
||||||
.compile_and_emit(
|
.compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink, &mut stackmap_sink)
|
||||||
isa,
|
|
||||||
&mut code_buf,
|
|
||||||
&mut reloc_sink,
|
|
||||||
&mut trap_sink,
|
|
||||||
&mut stackmap_sink,
|
|
||||||
)
|
|
||||||
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
|
.map_err(|error| CompileError::Codegen(pretty_error(&context.func, Some(isa), error)))?;
|
||||||
|
|
||||||
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
|
let unwind_info = compiled_function_unwind_info(isa, &context)?.maybe_into_to_windows_unwind();
|
||||||
|
|||||||
@@ -80,13 +80,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
let val = builder.use_var(Variable::with_u32(*local_index));
|
let val = builder.use_var(Variable::with_u32(*local_index));
|
||||||
let local_type = environ.get_local_type(*local_index).unwrap();
|
let local_type = environ.get_local_type(*local_index).unwrap();
|
||||||
let ref_counted = local_type == WasmerType::ExternRef;
|
let ref_counted = local_type == WasmerType::ExternRef;
|
||||||
state.push1_extra((
|
state.push1_extra((val, ValueExtraInfo { ref_counted, ..Default::default() }));
|
||||||
val,
|
|
||||||
ValueExtraInfo {
|
|
||||||
ref_counted,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
));
|
|
||||||
let label = ValueLabel::from_u32(*local_index);
|
let label = ValueLabel::from_u32(*local_index);
|
||||||
builder.set_val_label(val, label);
|
builder.set_val_label(val, label);
|
||||||
|
|
||||||
@@ -151,13 +145,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
environ.translate_externref_inc(builder.cursor(), value)?;
|
environ.translate_externref_inc(builder.cursor(), value)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(value, ValueExtraInfo { ref_counted, ..Default::default() })
|
||||||
value,
|
|
||||||
ValueExtraInfo {
|
|
||||||
ref_counted,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
GlobalVariable::Custom => (
|
GlobalVariable::Custom => (
|
||||||
environ.translate_custom_global_get(builder.cursor(), global_index)?,
|
environ.translate_custom_global_get(builder.cursor(), global_index)?,
|
||||||
@@ -216,10 +204,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
let not_selected_ref = builder.ins().select(cond, arg2, arg1);
|
let not_selected_ref = builder.ins().select(cond, arg2, arg1);
|
||||||
state.push1_extra((
|
state.push1_extra((
|
||||||
selected_ref,
|
selected_ref,
|
||||||
ValueExtraInfo {
|
ValueExtraInfo { ref_counted, ..Default::default() },
|
||||||
ref_counted,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
environ.translate_externref_dec(builder.cursor(), not_selected_ref)?;
|
environ.translate_externref_dec(builder.cursor(), not_selected_ref)?;
|
||||||
} else {
|
} else {
|
||||||
@@ -262,9 +247,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
// Pop the initial `Block` actuals and replace them with the `Block`'s
|
// Pop the initial `Block` actuals and replace them with the `Block`'s
|
||||||
// params since control flow joins at the top of the loop.
|
// params since control flow joins at the top of the loop.
|
||||||
state.popn(params.len());
|
state.popn(params.len());
|
||||||
state
|
state.stack.extend_from_slice(builder.block_params(loop_body));
|
||||||
.stack
|
|
||||||
.extend_from_slice(builder.block_params(loop_body));
|
|
||||||
|
|
||||||
builder.switch_to_block(loop_body);
|
builder.switch_to_block(loop_body);
|
||||||
environ.translate_loop_header(builder.cursor())?;
|
environ.translate_loop_header(builder.cursor())?;
|
||||||
@@ -402,9 +385,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame.truncate_value_stack_to_original_size(&mut state.stack);
|
frame.truncate_value_stack_to_original_size(&mut state.stack);
|
||||||
state
|
state.stack.extend_from_slice(builder.block_params(next_block));
|
||||||
.stack
|
|
||||||
.extend_from_slice(builder.block_params(next_block));
|
|
||||||
}
|
}
|
||||||
/**************************** Branch instructions *********************************
|
/**************************** Branch instructions *********************************
|
||||||
* The branch instructions all have as arguments a target nesting level, which
|
* The branch instructions all have as arguments a target nesting level, which
|
||||||
@@ -586,10 +567,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
let mut results_metadata = Vec::with_capacity(func_type.results().len());
|
let mut results_metadata = Vec::with_capacity(func_type.results().len());
|
||||||
for result in func_type.results() {
|
for result in func_type.results() {
|
||||||
results_metadata.push(if *result == WasmerType::ExternRef {
|
results_metadata.push(if *result == WasmerType::ExternRef {
|
||||||
ValueExtraInfo {
|
ValueExtraInfo { ref_counted: true, ..Default::default() }
|
||||||
ref_counted: true,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
});
|
});
|
||||||
@@ -634,10 +612,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
let mut results_metadata = Vec::with_capacity(func_type.results().len());
|
let mut results_metadata = Vec::with_capacity(func_type.results().len());
|
||||||
for result in func_type.results() {
|
for result in func_type.results() {
|
||||||
results_metadata.push(if *result == WasmerType::ExternRef {
|
results_metadata.push(if *result == WasmerType::ExternRef {
|
||||||
ValueExtraInfo {
|
ValueExtraInfo { ref_counted: true, ..Default::default() }
|
||||||
ref_counted: true,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
});
|
});
|
||||||
@@ -1386,10 +1361,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
let (index, _) = state.pop1();
|
let (index, _) = state.pop1();
|
||||||
environ.translate_table_set(builder, table_index, table, value, index)?;
|
environ.translate_table_set(builder, table_index, table, value, index)?;
|
||||||
}
|
}
|
||||||
Operator::TableCopy {
|
Operator::TableCopy { dst_table: dst_table_index, src_table: src_table_index } => {
|
||||||
dst_table: dst_table_index,
|
|
||||||
src_table: src_table_index,
|
|
||||||
} => {
|
|
||||||
let dst_table = state.get_or_create_table(builder.func, *dst_table_index, environ)?;
|
let dst_table = state.get_or_create_table(builder.func, *dst_table_index, environ)?;
|
||||||
let src_table = state.get_or_create_table(builder.func, *src_table_index, environ)?;
|
let src_table = state.get_or_create_table(builder.func, *src_table_index, environ)?;
|
||||||
let (len, _) = state.pop1();
|
let (len, _) = state.pop1();
|
||||||
@@ -1413,10 +1385,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
let (dest, _) = state.pop1();
|
let (dest, _) = state.pop1();
|
||||||
environ.translate_table_fill(builder.cursor(), table_index, dest, val, len)?;
|
environ.translate_table_fill(builder.cursor(), table_index, dest, val, len)?;
|
||||||
}
|
}
|
||||||
Operator::TableInit {
|
Operator::TableInit { segment, table: table_index } => {
|
||||||
segment,
|
|
||||||
table: table_index,
|
|
||||||
} => {
|
|
||||||
let table = state.get_or_create_table(builder.func, *table_index, environ)?;
|
let table = state.get_or_create_table(builder.func, *table_index, environ)?;
|
||||||
let (len, _) = state.pop1();
|
let (len, _) = state.pop1();
|
||||||
let (src, _) = state.pop1();
|
let (src, _) = state.pop1();
|
||||||
@@ -1443,9 +1412,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
state.push1(value)
|
state.push1(value)
|
||||||
}
|
}
|
||||||
Operator::I8x16Splat | Operator::I16x8Splat => {
|
Operator::I8x16Splat | Operator::I16x8Splat => {
|
||||||
let reduced = builder
|
let reduced = builder.ins().ireduce(type_of(op).lane_type(), state.pop1().0);
|
||||||
.ins()
|
|
||||||
.ireduce(type_of(op).lane_type(), state.pop1().0);
|
|
||||||
let splatted = builder.ins().splat(type_of(op), reduced);
|
let splatted = builder.ins().splat(type_of(op), reduced);
|
||||||
state.push1(splatted)
|
state.push1(splatted)
|
||||||
}
|
}
|
||||||
@@ -1686,12 +1653,9 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
Operator::I8x16LeS | Operator::I16x8LeS | Operator::I32x4LeS => {
|
Operator::I8x16LeS | Operator::I16x8LeS | Operator::I32x4LeS => {
|
||||||
translate_vector_icmp(IntCC::SignedLessThanOrEqual, type_of(op), builder, state)
|
translate_vector_icmp(IntCC::SignedLessThanOrEqual, type_of(op), builder, state)
|
||||||
}
|
}
|
||||||
Operator::I8x16GeU | Operator::I16x8GeU | Operator::I32x4GeU => translate_vector_icmp(
|
Operator::I8x16GeU | Operator::I16x8GeU | Operator::I32x4GeU => {
|
||||||
IntCC::UnsignedGreaterThanOrEqual,
|
translate_vector_icmp(IntCC::UnsignedGreaterThanOrEqual, type_of(op), builder, state)
|
||||||
type_of(op),
|
}
|
||||||
builder,
|
|
||||||
state,
|
|
||||||
),
|
|
||||||
Operator::I8x16LeU | Operator::I16x8LeU | Operator::I32x4LeU => {
|
Operator::I8x16LeU | Operator::I16x8LeU | Operator::I32x4LeU => {
|
||||||
translate_vector_icmp(IntCC::UnsignedLessThanOrEqual, type_of(op), builder, state)
|
translate_vector_icmp(IntCC::UnsignedLessThanOrEqual, type_of(op), builder, state)
|
||||||
}
|
}
|
||||||
@@ -1921,9 +1885,7 @@ fn translate_unreachable_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
// so we don't have any branches anywhere.
|
// so we don't have any branches anywhere.
|
||||||
state.push_if(
|
state.push_if(
|
||||||
ir::Block::reserved_value(),
|
ir::Block::reserved_value(),
|
||||||
ElseData::NoElse {
|
ElseData::NoElse { branch_inst: ir::Inst::reserved_value() },
|
||||||
branch_inst: ir::Inst::reserved_value(),
|
|
||||||
},
|
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ty,
|
ty,
|
||||||
@@ -2128,14 +2090,8 @@ fn prepare_load<FE: FuncEnvironment + ?Sized>(
|
|||||||
let (addr32, _) = state.pop1();
|
let (addr32, _) = state.pop1();
|
||||||
|
|
||||||
let heap = state.get_heap(builder.func, memarg.memory, environ)?;
|
let heap = state.get_heap(builder.func, memarg.memory, environ)?;
|
||||||
let (base, offset) = get_heap_addr(
|
let (base, offset) =
|
||||||
heap,
|
get_heap_addr(heap, addr32, memarg.offset, loaded_bytes, environ.pointer_type(), builder);
|
||||||
addr32,
|
|
||||||
memarg.offset,
|
|
||||||
loaded_bytes,
|
|
||||||
environ.pointer_type(),
|
|
||||||
builder,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Note that we don't set `is_aligned` here, even if the load instruction's
|
// Note that we don't set `is_aligned` here, even if the load instruction's
|
||||||
// alignment immediate says it's aligned, because WebAssembly's immediate
|
// alignment immediate says it's aligned, because WebAssembly's immediate
|
||||||
@@ -2154,13 +2110,8 @@ fn translate_load<FE: FuncEnvironment + ?Sized>(
|
|||||||
state: &mut FuncTranslationState,
|
state: &mut FuncTranslationState,
|
||||||
environ: &mut FE,
|
environ: &mut FE,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
let (flags, base, offset) = prepare_load(
|
let (flags, base, offset) =
|
||||||
memarg,
|
prepare_load(memarg, mem_op_size(opcode, result_ty), builder, state, environ)?;
|
||||||
mem_op_size(opcode, result_ty),
|
|
||||||
builder,
|
|
||||||
state,
|
|
||||||
environ,
|
|
||||||
)?;
|
|
||||||
let (load, dfg) = builder.ins().Load(opcode, result_ty, flags, offset, base);
|
let (load, dfg) = builder.ins().Load(opcode, result_ty, flags, offset, base);
|
||||||
state.push1(dfg.first_result(load));
|
state.push1(dfg.first_result(load));
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -2188,9 +2139,7 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
|
|||||||
);
|
);
|
||||||
// See the comments in `prepare_load` about the flags.
|
// See the comments in `prepare_load` about the flags.
|
||||||
let flags = MemFlags::new();
|
let flags = MemFlags::new();
|
||||||
builder
|
builder.ins().Store(opcode, val_ty, flags, offset.into(), val, base);
|
||||||
.ins()
|
|
||||||
.Store(opcode, val_ty, flags, offset.into(), val, base);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2222,20 +2171,13 @@ fn finalise_atomic_mem_addr<FE: FuncEnvironment + ?Sized>(
|
|||||||
) -> WasmResult<Value> {
|
) -> WasmResult<Value> {
|
||||||
// Check the alignment of `linear_mem_addr`.
|
// Check the alignment of `linear_mem_addr`.
|
||||||
let access_ty_bytes = access_ty.bytes();
|
let access_ty_bytes = access_ty.bytes();
|
||||||
let final_lma = builder
|
let final_lma = builder.ins().iadd_imm(linear_mem_addr, i64::from(memarg.offset));
|
||||||
.ins()
|
|
||||||
.iadd_imm(linear_mem_addr, i64::from(memarg.offset));
|
|
||||||
if access_ty_bytes != 1 {
|
if access_ty_bytes != 1 {
|
||||||
assert!(access_ty_bytes == 2 || access_ty_bytes == 4 || access_ty_bytes == 8);
|
assert!(access_ty_bytes == 2 || access_ty_bytes == 4 || access_ty_bytes == 8);
|
||||||
let final_lma_misalignment = builder
|
let final_lma_misalignment =
|
||||||
.ins()
|
builder.ins().band_imm(final_lma, i64::from(access_ty_bytes - 1));
|
||||||
.band_imm(final_lma, i64::from(access_ty_bytes - 1));
|
let f = builder.ins().ifcmp_imm(final_lma_misalignment, i64::from(0));
|
||||||
let f = builder
|
builder.ins().trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned);
|
||||||
.ins()
|
|
||||||
.ifcmp_imm(final_lma_misalignment, i64::from(0));
|
|
||||||
builder
|
|
||||||
.ins()
|
|
||||||
.trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the final effective address.
|
// Compute the final effective address.
|
||||||
@@ -2269,12 +2211,7 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
|
|||||||
// to type `widened_ty`.
|
// to type `widened_ty`.
|
||||||
match access_ty {
|
match access_ty {
|
||||||
I8 | I16 | I32 | I64 => {}
|
I8 | I16 | I32 | I64 => {}
|
||||||
_ => {
|
_ => return Err(wasm_unsupported!("atomic_rmw: unsupported access type {:?}", access_ty)),
|
||||||
return Err(wasm_unsupported!(
|
|
||||||
"atomic_rmw: unsupported access type {:?}",
|
|
||||||
access_ty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let w_ty_ok = match widened_ty {
|
let w_ty_ok = match widened_ty {
|
||||||
I32 | I64 => true,
|
I32 | I64 => true,
|
||||||
@@ -2292,9 +2229,7 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
|
|||||||
|
|
||||||
// See the comments in `prepare_load` about the flags.
|
// See the comments in `prepare_load` about the flags.
|
||||||
let flags = MemFlags::new();
|
let flags = MemFlags::new();
|
||||||
let mut res = builder
|
let mut res = builder.ins().atomic_rmw(access_ty, flags, op, final_effective_address, arg2);
|
||||||
.ins()
|
|
||||||
.atomic_rmw(access_ty, flags, op, final_effective_address, arg2);
|
|
||||||
if access_ty != widened_ty {
|
if access_ty != widened_ty {
|
||||||
res = builder.ins().uextend(widened_ty, res);
|
res = builder.ins().uextend(widened_ty, res);
|
||||||
}
|
}
|
||||||
@@ -2318,12 +2253,7 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
|
|||||||
// to type `widened_ty`.
|
// to type `widened_ty`.
|
||||||
match access_ty {
|
match access_ty {
|
||||||
I8 | I16 | I32 | I64 => {}
|
I8 | I16 | I32 | I64 => {}
|
||||||
_ => {
|
_ => return Err(wasm_unsupported!("atomic_cas: unsupported access type {:?}", access_ty)),
|
||||||
return Err(wasm_unsupported!(
|
|
||||||
"atomic_cas: unsupported access type {:?}",
|
|
||||||
access_ty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let w_ty_ok = match widened_ty {
|
let w_ty_ok = match widened_ty {
|
||||||
I32 | I64 => true,
|
I32 | I64 => true,
|
||||||
@@ -2345,9 +2275,7 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
|
|||||||
|
|
||||||
// See the comments in `prepare_load` about the flags.
|
// See the comments in `prepare_load` about the flags.
|
||||||
let flags = MemFlags::new();
|
let flags = MemFlags::new();
|
||||||
let mut res = builder
|
let mut res = builder.ins().atomic_cas(flags, final_effective_address, expected, replacement);
|
||||||
.ins()
|
|
||||||
.atomic_cas(flags, final_effective_address, expected, replacement);
|
|
||||||
if access_ty != widened_ty {
|
if access_ty != widened_ty {
|
||||||
res = builder.ins().uextend(widened_ty, res);
|
res = builder.ins().uextend(widened_ty, res);
|
||||||
}
|
}
|
||||||
@@ -2369,12 +2297,7 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
|
|||||||
// to `widened_ty`.
|
// to `widened_ty`.
|
||||||
match access_ty {
|
match access_ty {
|
||||||
I8 | I16 | I32 | I64 => {}
|
I8 | I16 | I32 | I64 => {}
|
||||||
_ => {
|
_ => return Err(wasm_unsupported!("atomic_load: unsupported access type {:?}", access_ty)),
|
||||||
return Err(wasm_unsupported!(
|
|
||||||
"atomic_load: unsupported access type {:?}",
|
|
||||||
access_ty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let w_ty_ok = match widened_ty {
|
let w_ty_ok = match widened_ty {
|
||||||
I32 | I64 => true,
|
I32 | I64 => true,
|
||||||
@@ -2387,9 +2310,7 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
|
|||||||
|
|
||||||
// See the comments in `prepare_load` about the flags.
|
// See the comments in `prepare_load` about the flags.
|
||||||
let flags = MemFlags::new();
|
let flags = MemFlags::new();
|
||||||
let mut res = builder
|
let mut res = builder.ins().atomic_load(access_ty, flags, final_effective_address);
|
||||||
.ins()
|
|
||||||
.atomic_load(access_ty, flags, final_effective_address);
|
|
||||||
if access_ty != widened_ty {
|
if access_ty != widened_ty {
|
||||||
res = builder.ins().uextend(widened_ty, res);
|
res = builder.ins().uextend(widened_ty, res);
|
||||||
}
|
}
|
||||||
@@ -2412,10 +2333,7 @@ fn translate_atomic_store<FE: FuncEnvironment + ?Sized>(
|
|||||||
match access_ty {
|
match access_ty {
|
||||||
I8 | I16 | I32 | I64 => {}
|
I8 | I16 | I32 | I64 => {}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(wasm_unsupported!(
|
return Err(wasm_unsupported!("atomic_store: unsupported access type {:?}", access_ty))
|
||||||
"atomic_store: unsupported access type {:?}",
|
|
||||||
access_ty
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let d_ty_ok = match data_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.
|
// See the comments in `prepare_load` about the flags.
|
||||||
let flags = MemFlags::new();
|
let flags = MemFlags::new();
|
||||||
builder
|
builder.ins().atomic_store(flags, data, final_effective_address);
|
||||||
.ins()
|
|
||||||
.atomic_store(flags, data, final_effective_address);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2495,11 +2411,8 @@ fn translate_br_if_args(
|
|||||||
// The values returned by the branch are still available for the reachable
|
// The values returned by the branch are still available for the reachable
|
||||||
// code that comes after it
|
// code that comes after it
|
||||||
frame.set_branched_to_exit();
|
frame.set_branched_to_exit();
|
||||||
let return_count = if frame.is_loop() {
|
let return_count =
|
||||||
frame.num_param_values()
|
if frame.is_loop() { frame.num_param_values() } else { frame.num_return_values() };
|
||||||
} else {
|
|
||||||
frame.num_return_values()
|
|
||||||
};
|
|
||||||
(return_count, frame.br_destination())
|
(return_count, frame.br_destination())
|
||||||
};
|
};
|
||||||
let inputs = state.peekn_mut(return_count);
|
let inputs = state.peekn_mut(return_count);
|
||||||
@@ -2708,10 +2621,7 @@ fn optionally_bitcast_vector(
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_non_canonical_v128(ty: ir::Type) -> bool {
|
fn is_non_canonical_v128(ty: ir::Type) -> bool {
|
||||||
matches!(
|
matches!(ty, B8X16 | B16X8 | B32X4 | B64X2 | I64X2 | I32X4 | I16X8 | F32X4 | F64X2)
|
||||||
ty,
|
|
||||||
B8X16 | B16X8 | B32X4 | B64X2 | I64X2 | I32X4 | I16X8 | F32X4 | F64X2
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cast to I8X16, any vector values in `values` that are of "non-canonical" type (meaning, not
|
/// Cast to I8X16, any vector values in `values` that are of "non-canonical" type (meaning, not
|
||||||
@@ -2725,9 +2635,8 @@ fn canonicalise_v128_values<'a>(
|
|||||||
) -> &'a [ir::Value] {
|
) -> &'a [ir::Value] {
|
||||||
debug_assert!(tmp_canonicalised.is_empty());
|
debug_assert!(tmp_canonicalised.is_empty());
|
||||||
// First figure out if any of the parameters need to be cast. Mostly they don't need to be.
|
// First figure out if any of the parameters need to be cast. Mostly they don't need to be.
|
||||||
let any_non_canonical = values
|
let any_non_canonical =
|
||||||
.iter()
|
values.iter().any(|v| is_non_canonical_v128(builder.func.dfg.value_type(*v)));
|
||||||
.any(|v| is_non_canonical_v128(builder.func.dfg.value_type(*v)));
|
|
||||||
// Hopefully we take this exit most of the time, hence doing no heap allocation.
|
// Hopefully we take this exit most of the time, hence doing no heap allocation.
|
||||||
if !any_non_canonical {
|
if !any_non_canonical {
|
||||||
return values;
|
return values;
|
||||||
|
|||||||
@@ -95,28 +95,16 @@ pub enum ControlStackFrame {
|
|||||||
impl ControlStackFrame {
|
impl ControlStackFrame {
|
||||||
pub fn num_return_values(&self) -> usize {
|
pub fn num_return_values(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Self::If {
|
Self::If { num_return_values, .. }
|
||||||
num_return_values, ..
|
| Self::Block { num_return_values, .. }
|
||||||
}
|
| Self::Loop { num_return_values, .. } => num_return_values,
|
||||||
| Self::Block {
|
|
||||||
num_return_values, ..
|
|
||||||
}
|
|
||||||
| Self::Loop {
|
|
||||||
num_return_values, ..
|
|
||||||
} => num_return_values,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn num_param_values(&self) -> usize {
|
pub fn num_param_values(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Self::If {
|
Self::If { num_param_values, .. }
|
||||||
num_param_values, ..
|
| Self::Block { num_param_values, .. }
|
||||||
}
|
| Self::Loop { num_param_values, .. } => num_param_values,
|
||||||
| Self::Block {
|
|
||||||
num_param_values, ..
|
|
||||||
}
|
|
||||||
| Self::Loop {
|
|
||||||
num_param_values, ..
|
|
||||||
} => num_param_values,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn following_code(&self) -> Block {
|
pub fn following_code(&self) -> Block {
|
||||||
@@ -136,18 +124,9 @@ impl ControlStackFrame {
|
|||||||
/// `truncate_value_stack_to_original_size()` to restore value-stack state.
|
/// `truncate_value_stack_to_original_size()` to restore value-stack state.
|
||||||
fn original_stack_size(&self) -> usize {
|
fn original_stack_size(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Self::If {
|
Self::If { original_stack_size, .. }
|
||||||
original_stack_size,
|
| Self::Block { original_stack_size, .. }
|
||||||
..
|
| Self::Loop { original_stack_size, .. } => original_stack_size,
|
||||||
}
|
|
||||||
| Self::Block {
|
|
||||||
original_stack_size,
|
|
||||||
..
|
|
||||||
}
|
|
||||||
| Self::Loop {
|
|
||||||
original_stack_size,
|
|
||||||
..
|
|
||||||
} => original_stack_size,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_loop(&self) -> bool {
|
pub fn is_loop(&self) -> bool {
|
||||||
@@ -159,28 +138,17 @@ impl ControlStackFrame {
|
|||||||
|
|
||||||
pub fn exit_is_branched_to(&self) -> bool {
|
pub fn exit_is_branched_to(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Self::If {
|
Self::If { exit_is_branched_to, .. } | Self::Block { exit_is_branched_to, .. } => {
|
||||||
exit_is_branched_to,
|
exit_is_branched_to
|
||||||
..
|
|
||||||
}
|
}
|
||||||
| Self::Block {
|
|
||||||
exit_is_branched_to,
|
|
||||||
..
|
|
||||||
} => exit_is_branched_to,
|
|
||||||
Self::Loop { .. } => false,
|
Self::Loop { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_branched_to_exit(&mut self) {
|
pub fn set_branched_to_exit(&mut self) {
|
||||||
match *self {
|
match *self {
|
||||||
Self::If {
|
Self::If { ref mut exit_is_branched_to, .. }
|
||||||
ref mut exit_is_branched_to,
|
| Self::Block { ref mut exit_is_branched_to, .. } => *exit_is_branched_to = true,
|
||||||
..
|
|
||||||
}
|
|
||||||
| Self::Block {
|
|
||||||
ref mut exit_is_branched_to,
|
|
||||||
..
|
|
||||||
} => *exit_is_branched_to = true,
|
|
||||||
Self::Loop { .. } => {}
|
Self::Loop { .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,9 +169,7 @@ impl ControlStackFrame {
|
|||||||
// block can see the same number of parameters as the consequent block. As a matter of
|
// block can see the same number of parameters as the consequent block. As a matter of
|
||||||
// fact, we need to substract an extra number of parameter values for if blocks.
|
// fact, we need to substract an extra number of parameter values for if blocks.
|
||||||
let num_duplicated_params = match self {
|
let num_duplicated_params = match self {
|
||||||
&ControlStackFrame::If {
|
&ControlStackFrame::If { num_param_values, .. } => {
|
||||||
num_param_values, ..
|
|
||||||
} => {
|
|
||||||
debug_assert!(num_param_values <= self.original_stack_size());
|
debug_assert!(num_param_values <= self.original_stack_size());
|
||||||
num_param_values
|
num_param_values
|
||||||
}
|
}
|
||||||
@@ -302,10 +268,7 @@ impl FuncTranslationState {
|
|||||||
self.push_block(
|
self.push_block(
|
||||||
exit_block,
|
exit_block,
|
||||||
0,
|
0,
|
||||||
sig.returns
|
sig.returns.iter().filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal).count(),
|
||||||
.iter()
|
|
||||||
.filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
|
|
||||||
.count(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,20 +296,14 @@ impl FuncTranslationState {
|
|||||||
|
|
||||||
/// Pop one value.
|
/// Pop one value.
|
||||||
pub(crate) fn pop1(&mut self) -> (Value, ValueExtraInfo) {
|
pub(crate) fn pop1(&mut self) -> (Value, ValueExtraInfo) {
|
||||||
let val = self
|
let val = self.stack.pop().expect("attempted to pop a value from an empty stack");
|
||||||
.stack
|
|
||||||
.pop()
|
|
||||||
.expect("attempted to pop a value from an empty stack");
|
|
||||||
let val_metadata = Default::default();
|
let val_metadata = Default::default();
|
||||||
(val, val_metadata)
|
(val, val_metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Peek at the top of the stack without popping it.
|
/// Peek at the top of the stack without popping it.
|
||||||
pub(crate) fn peek1(&self) -> (Value, ValueExtraInfo) {
|
pub(crate) fn peek1(&self) -> (Value, ValueExtraInfo) {
|
||||||
let val = *self
|
let val = *self.stack.last().expect("attempted to peek at a value on an empty stack");
|
||||||
.stack
|
|
||||||
.last()
|
|
||||||
.expect("attempted to peek at a value on an empty stack");
|
|
||||||
let val_metadata = Default::default();
|
let val_metadata = Default::default();
|
||||||
(val, val_metadata)
|
(val, val_metadata)
|
||||||
}
|
}
|
||||||
@@ -361,11 +318,7 @@ impl FuncTranslationState {
|
|||||||
/// Pop three values. Return them in the order they were pushed.
|
/// Pop three values. Return them in the order they were pushed.
|
||||||
pub(crate) fn pop3(
|
pub(crate) fn pop3(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> (
|
) -> ((Value, ValueExtraInfo), (Value, ValueExtraInfo), (Value, ValueExtraInfo)) {
|
||||||
(Value, ValueExtraInfo),
|
|
||||||
(Value, ValueExtraInfo),
|
|
||||||
(Value, ValueExtraInfo),
|
|
||||||
) {
|
|
||||||
let v3 = self.pop1();
|
let v3 = self.pop1();
|
||||||
let v2 = self.pop1();
|
let v2 = self.pop1();
|
||||||
let v1 = self.pop1();
|
let v1 = self.pop1();
|
||||||
@@ -577,10 +530,7 @@ impl FuncTranslationState {
|
|||||||
Vacant(entry) => {
|
Vacant(entry) => {
|
||||||
let fref = environ.make_direct_func(func, index)?;
|
let fref = environ.make_direct_func(func, index)?;
|
||||||
let sig = func.dfg.ext_funcs[fref].signature;
|
let sig = func.dfg.ext_funcs[fref].signature;
|
||||||
Ok(*entry.insert((
|
Ok(*entry.insert((fref, num_wasm_parameters(environ, &func.dfg.signatures[sig]))))
|
||||||
fref,
|
|
||||||
num_wasm_parameters(environ, &func.dfg.signatures[sig]),
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -590,7 +540,5 @@ fn num_wasm_parameters<FE: FuncEnvironment + ?Sized>(
|
|||||||
environ: &FE,
|
environ: &FE,
|
||||||
signature: &ir::Signature,
|
signature: &ir::Signature,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
(0..signature.params.len())
|
(0..signature.params.len()).filter(|index| environ.is_wasm_parameter(signature, *index)).count()
|
||||||
.filter(|index| environ.is_wasm_parameter(signature, *index))
|
|
||||||
.count()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,10 +37,7 @@ pub struct FuncTranslator {
|
|||||||
impl FuncTranslator {
|
impl FuncTranslator {
|
||||||
/// Create a new translator.
|
/// Create a new translator.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self { func_ctx: FunctionBuilderContext::new(), state: FuncTranslationState::new() }
|
||||||
func_ctx: FunctionBuilderContext::new(),
|
|
||||||
state: FuncTranslationState::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translate a binary WebAssembly function.
|
/// Translate a binary WebAssembly function.
|
||||||
@@ -73,9 +70,7 @@ impl FuncTranslator {
|
|||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
let mut reader = MiddlewareBinaryReader::new_with_offset(code, code_offset);
|
let mut reader = MiddlewareBinaryReader::new_with_offset(code, code_offset);
|
||||||
reader.set_middleware_chain(
|
reader.set_middleware_chain(
|
||||||
config
|
config.middlewares.generate_function_middleware_chain(local_function_index),
|
||||||
.middlewares
|
|
||||||
.generate_function_middleware_chain(local_function_index),
|
|
||||||
);
|
);
|
||||||
environ.push_params_on_stack(local_function_index);
|
environ.push_params_on_stack(local_function_index);
|
||||||
self.translate_from_reader(module_translation_state, reader, func, environ)
|
self.translate_from_reader(module_translation_state, reader, func, environ)
|
||||||
@@ -90,12 +85,7 @@ impl FuncTranslator {
|
|||||||
environ: &mut FE,
|
environ: &mut FE,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
let _tt = timing::wasm_translate_function();
|
let _tt = timing::wasm_translate_function();
|
||||||
info!(
|
info!("translate({} bytes, {}{})", reader.bytes_remaining(), func.name, func.signature);
|
||||||
"translate({} bytes, {}{})",
|
|
||||||
reader.bytes_remaining(),
|
|
||||||
func.name,
|
|
||||||
func.signature
|
|
||||||
);
|
|
||||||
debug_assert_eq!(func.dfg.num_blocks(), 0, "Function must be empty");
|
debug_assert_eq!(func.dfg.num_blocks(), 0, "Function must be empty");
|
||||||
debug_assert_eq!(func.dfg.num_insts(), 0, "Function must be empty");
|
debug_assert_eq!(func.dfg.num_insts(), 0, "Function must be empty");
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,8 @@ pub fn signature_to_cranelift_ir(
|
|||||||
AbiParam::new(cret_arg)
|
AbiParam::new(cret_arg)
|
||||||
}));
|
}));
|
||||||
// The Vmctx signature
|
// The Vmctx signature
|
||||||
sig.params.insert(
|
sig.params
|
||||||
0,
|
.insert(0, AbiParam::special(target_config.pointer_type(), ir::ArgumentPurpose::VMContext));
|
||||||
AbiParam::special(target_config.pointer_type(), ir::ArgumentPurpose::VMContext),
|
|
||||||
);
|
|
||||||
sig
|
sig
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,9 +43,7 @@ pub fn reference_type(target_config: TargetFrontendConfig) -> WasmResult<ir::Typ
|
|||||||
match target_config.pointer_type() {
|
match target_config.pointer_type() {
|
||||||
ir::types::I32 => Ok(ir::types::R32),
|
ir::types::I32 => Ok(ir::types::R32),
|
||||||
ir::types::I64 => Ok(ir::types::R64),
|
ir::types::I64 => Ok(ir::types::R64),
|
||||||
_ => Err(WasmError::Unsupported(
|
_ => Err(WasmError::Unsupported("unsupported pointer type".to_string())),
|
||||||
"unsupported pointer type".to_string(),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,9 +72,7 @@ impl Abi for Aarch64SystemV {
|
|||||||
(
|
(
|
||||||
context.create_enum_attribute(
|
context.create_enum_attribute(
|
||||||
Attribute::get_named_enum_kind_id("align"),
|
Attribute::get_named_enum_kind_id("align"),
|
||||||
std::mem::align_of::<wasmer_vm::VMContext>()
|
std::mem::align_of::<wasmer_vm::VMContext>().try_into().unwrap(),
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
),
|
),
|
||||||
AttributeLoc::Param(i),
|
AttributeLoc::Param(i),
|
||||||
),
|
),
|
||||||
@@ -83,9 +81,7 @@ impl Abi for Aarch64SystemV {
|
|||||||
|
|
||||||
Ok(match sig.results() {
|
Ok(match sig.results() {
|
||||||
[] => (
|
[] => (
|
||||||
intrinsics
|
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||||
.void_ty
|
|
||||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
|
||||||
vmctx_attributes(0),
|
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());
|
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
|
||||||
|
|
||||||
if let Some(sret) = sret {
|
if let Some(sret) = sret {
|
||||||
std::iter::once(sret.as_basic_value_enum())
|
std::iter::once(sret.as_basic_value_enum()).chain(values).collect()
|
||||||
.chain(values)
|
|
||||||
.collect()
|
|
||||||
} else {
|
} else {
|
||||||
values.collect()
|
values.collect()
|
||||||
}
|
}
|
||||||
@@ -308,14 +302,9 @@ impl Abi for Aarch64SystemV {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
}
|
}
|
||||||
let array_value = basic_value.into_array_value();
|
let array_value = basic_value.into_array_value();
|
||||||
let low = builder
|
let low = builder.build_extract_value(array_value, 0, "").unwrap().into_int_value();
|
||||||
.build_extract_value(array_value, 0, "")
|
let high =
|
||||||
.unwrap()
|
builder.build_extract_value(array_value, 1, "").unwrap().into_int_value();
|
||||||
.into_int_value();
|
|
||||||
let high = builder
|
|
||||||
.build_extract_value(array_value, 1, "")
|
|
||||||
.unwrap()
|
|
||||||
.into_int_value();
|
|
||||||
let func_sig_returns_bitwidths = func_sig
|
let func_sig_returns_bitwidths = func_sig
|
||||||
.results()
|
.results()
|
||||||
.iter()
|
.iter()
|
||||||
@@ -473,9 +462,7 @@ impl Abi for Aarch64SystemV {
|
|||||||
if v.is_float_value() {
|
if v.is_float_value() {
|
||||||
let v = v.into_float_value();
|
let v = v.into_float_value();
|
||||||
if v.get_type() == intrinsics.f32_ty {
|
if v.get_type() == intrinsics.f32_ty {
|
||||||
let v = builder
|
let v = builder.build_bitcast(v, intrinsics.i32_ty, "").into_int_value();
|
||||||
.build_bitcast(v, intrinsics.i32_ty, "")
|
|
||||||
.into_int_value();
|
|
||||||
let v = builder.build_int_z_extend(v, intrinsics.i64_ty, "");
|
let v = builder.build_int_z_extend(v, intrinsics.i64_ty, "");
|
||||||
v.as_basic_value_enum()
|
v.as_basic_value_enum()
|
||||||
} else {
|
} else {
|
||||||
@@ -522,10 +509,7 @@ impl Abi for Aarch64SystemV {
|
|||||||
&& v2.is_float_value()
|
&& v2.is_float_value()
|
||||||
&& v1.into_float_value().get_type() == v2.into_float_value().get_type() =>
|
&& v1.into_float_value().get_type() == v2.into_float_value().get_type() =>
|
||||||
{
|
{
|
||||||
build_struct(
|
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2])
|
||||||
func_type.get_return_type().unwrap().into_struct_type(),
|
|
||||||
&[v1, v2],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
[v1, v2] if is_32(v1) && is_32(v2) => {
|
[v1, v2] if is_32(v1) && is_32(v2) => {
|
||||||
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
||||||
@@ -541,10 +525,7 @@ impl Abi for Aarch64SystemV {
|
|||||||
&& v2.is_float_value()
|
&& v2.is_float_value()
|
||||||
&& v3.is_float_value() =>
|
&& v3.is_float_value() =>
|
||||||
{
|
{
|
||||||
build_struct(
|
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2, v3])
|
||||||
func_type.get_return_type().unwrap().into_struct_type(),
|
|
||||||
&[v1, v2, v3],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
[v1, v2, v3] if is_32(v1) && is_32(v2) => {
|
[v1, v2, v3] if is_32(v1) && is_32(v2) => {
|
||||||
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
let v1 = builder.build_bitcast(v1, intrinsics.i32_ty, "");
|
||||||
|
|||||||
@@ -25,12 +25,7 @@ use aarch64_systemv::Aarch64SystemV;
|
|||||||
use x86_64_systemv::X86_64SystemV;
|
use x86_64_systemv::X86_64SystemV;
|
||||||
|
|
||||||
pub fn get_abi(target_machine: &TargetMachine) -> Box<dyn Abi> {
|
pub fn get_abi(target_machine: &TargetMachine) -> Box<dyn Abi> {
|
||||||
if target_machine
|
if target_machine.get_triple().as_str().to_string_lossy().starts_with("aarch64") {
|
||||||
.get_triple()
|
|
||||||
.as_str()
|
|
||||||
.to_string_lossy()
|
|
||||||
.starts_with("aarch64")
|
|
||||||
{
|
|
||||||
Box::new(Aarch64SystemV {})
|
Box::new(Aarch64SystemV {})
|
||||||
} else {
|
} else {
|
||||||
Box::new(X86_64SystemV {})
|
Box::new(X86_64SystemV {})
|
||||||
|
|||||||
@@ -76,9 +76,7 @@ impl Abi for X86_64SystemV {
|
|||||||
(
|
(
|
||||||
context.create_enum_attribute(
|
context.create_enum_attribute(
|
||||||
Attribute::get_named_enum_kind_id("align"),
|
Attribute::get_named_enum_kind_id("align"),
|
||||||
std::mem::align_of::<wasmer_vm::VMContext>()
|
std::mem::align_of::<wasmer_vm::VMContext>().try_into().unwrap(),
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
),
|
),
|
||||||
AttributeLoc::Param(i),
|
AttributeLoc::Param(i),
|
||||||
),
|
),
|
||||||
@@ -98,9 +96,7 @@ impl Abi for X86_64SystemV {
|
|||||||
|
|
||||||
Ok(match sig_returns_bitwidths.as_slice() {
|
Ok(match sig_returns_bitwidths.as_slice() {
|
||||||
[] => (
|
[] => (
|
||||||
intrinsics
|
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||||
.void_ty
|
|
||||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
|
||||||
vmctx_attributes(0),
|
vmctx_attributes(0),
|
||||||
),
|
),
|
||||||
[_] => {
|
[_] => {
|
||||||
@@ -133,9 +129,7 @@ impl Abi for X86_64SystemV {
|
|||||||
vmctx_attributes(0),
|
vmctx_attributes(0),
|
||||||
),
|
),
|
||||||
[32, 32] => (
|
[32, 32] => (
|
||||||
intrinsics
|
intrinsics.i64_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||||
.i64_ty
|
|
||||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
|
||||||
vmctx_attributes(0),
|
vmctx_attributes(0),
|
||||||
),
|
),
|
||||||
[32, 32, _] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => (
|
[32, 32, _] if sig.results()[0] == Type::F32 && sig.results()[1] == Type::F32 => (
|
||||||
@@ -213,9 +207,7 @@ impl Abi for X86_64SystemV {
|
|||||||
.map(|&ty| type_to_llvm(intrinsics, ty))
|
.map(|&ty| type_to_llvm(intrinsics, ty))
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
let sret = context
|
let sret = context.struct_type(&basic_types, false).ptr_type(AddressSpace::Generic);
|
||||||
.struct_type(&basic_types, false)
|
|
||||||
.ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
let param_types = std::iter::once(Ok(sret.as_basic_type_enum())).chain(param_types);
|
let param_types = std::iter::once(Ok(sret.as_basic_type_enum())).chain(param_types);
|
||||||
|
|
||||||
@@ -226,9 +218,7 @@ impl Abi for X86_64SystemV {
|
|||||||
attributes.append(&mut vmctx_attributes(1));
|
attributes.append(&mut vmctx_attributes(1));
|
||||||
|
|
||||||
(
|
(
|
||||||
intrinsics
|
intrinsics.void_ty.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
||||||
.void_ty
|
|
||||||
.fn_type(¶m_types.collect::<Result<Vec<_>, _>>()?, false),
|
|
||||||
attributes,
|
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());
|
let values = std::iter::once(ctx_ptr.as_basic_value_enum()).chain(values.iter().copied());
|
||||||
|
|
||||||
if let Some(sret) = sret {
|
if let Some(sret) = sret {
|
||||||
std::iter::once(sret.as_basic_value_enum())
|
std::iter::once(sret.as_basic_value_enum()).chain(values).collect()
|
||||||
.chain(values)
|
|
||||||
.collect()
|
|
||||||
} else {
|
} else {
|
||||||
values.collect()
|
values.collect()
|
||||||
}
|
}
|
||||||
@@ -541,10 +529,7 @@ impl Abi for X86_64SystemV {
|
|||||||
}
|
}
|
||||||
[v1, v2] => {
|
[v1, v2] => {
|
||||||
assert!(!(is_32(v1) && is_32(v2)));
|
assert!(!(is_32(v1) && is_32(v2)));
|
||||||
build_struct(
|
build_struct(func_type.get_return_type().unwrap().into_struct_type(), &[v1, v2])
|
||||||
func_type.get_return_type().unwrap().into_struct_type(),
|
|
||||||
&[v1, v2],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
[v1, v2, v3] if is_f32(v1) && is_f32(v2) => build_struct(
|
[v1, v2, v3] if is_f32(v1) && is_f32(v2) => build_struct(
|
||||||
func_type.get_return_type().unwrap().into_struct_type(),
|
func_type.get_return_type().unwrap().into_struct_type(),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user