Skip to content

Commit

Permalink
some fixing going on
Browse files Browse the repository at this point in the history
  • Loading branch information
tessi committed Aug 13, 2024
1 parent 40b4cfb commit 6f83e90
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 130 deletions.
26 changes: 26 additions & 0 deletions native/wasmex/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion native/wasmex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ crate-type = ["dylib"]

[dependencies]
rustler = { version = "0.34", features = ["big_integer"] }
futures-lite = "2.3.0"
once_cell = "1.19.0"
rand = "0.8.5"
wasmtime = "23.0.2"
wasmtime = { version = "23.0.2", features = ["async"] }
wasmtime-wasi = "23.0.1"
wasi-common = "23.0.1"
wiggle = "23.0.1"
Expand Down
1 change: 1 addition & 0 deletions native/wasmex/src/atoms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ rustler::atoms! {
// calls to erlang processes
returned_function_call,
invoke_callback,
async_nif_result,

// engine config - cranelift_opt_level
none,
Expand Down
124 changes: 72 additions & 52 deletions native/wasmex/src/environment.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::{
atoms,
caller::{remove_caller, set_caller},
instance::{map_wasm_values_to_vals, LinkedModule, WasmValue},
instance::{map_wasm_values_to_vals, ImportDefinition, LinkedModule, WasmValue},
memory::MemoryResource,
store::{StoreData, StoreOrCaller, StoreOrCallerResource},
};
use rustler::{
types::tuple, Atom, Encoder, Error, ListIterator, MapIterator, OwnedEnv, ResourceArc, Term,
types::tuple, Atom, Encoder, Error, ListIterator, LocalPid, MapIterator, OwnedEnv, ResourceArc, Term
};
use std::sync::{Condvar, Mutex};
use wasmtime::{Caller, Engine, FuncType, Linker, Val, ValType};
Expand Down Expand Up @@ -52,49 +52,82 @@ pub fn link_modules(
Ok(())
}

pub fn link_imports(
engine: &Engine,
linker: &mut Linker<StoreData>,
pub fn imports_from_map_iterator(
imports: MapIterator,
) -> Result<(), Error> {
) -> Result<Vec<ImportDefinition>, Error> {
let mut result = Vec::new();
for (namespace_name, namespace_definition) in imports {
let namespace_name = namespace_name.decode::<String>()?;
let definition: MapIterator = namespace_definition.decode()?;

for (import_name, import) in definition {
let import_name = import_name.decode::<String>()?;
link_import(engine, linker, &namespace_name, &import_name, import)?;
let import_tuple = tuple::get_tuple(import)?;

let import_type = import_tuple
.first()
.ok_or(Error::Atom("missing_import_type"))?;
let import_type =
Atom::from_term(*import_type).map_err(|_| Error::Atom("import type must be an atom"))?;

if atoms::__fn__().eq(&import_type) {
let param_term = import_tuple
.get(1)
.ok_or(Error::Atom("missing_import_params"))?;
let results_term = import_tuple
.get(2)
.ok_or(Error::Atom("missing_import_results"))?;

let params_signature = param_term
.decode::<ListIterator>()?
.map(term_to_arg_type)
.collect::<Result<Vec<ValType>, _>>()?;

let results_signature = results_term
.decode::<ListIterator>()?
.map(term_to_arg_type)
.collect::<Result<Vec<ValType>, _>>()?;

result.push(ImportDefinition::Function {
namespace: namespace_name.clone(),
name: import_name.clone(),
params: params_signature,
results: results_signature,
});
} else {
return Err(Error::Atom("unknown import type"));
}
}
}
Ok(result)
}

pub fn link_imports(
engine: &Engine,
linker: &mut Linker<StoreData>,
imports: &Vec<ImportDefinition>,
pid: &LocalPid,
) -> Result<(), Error> {
for import_definition in imports {
link_import(engine, linker, import_definition, pid)?;
}
Ok(())
}

fn link_import(
engine: &Engine,
linker: &mut Linker<StoreData>,
namespace_name: &str,
import_name: &str,
definition: Term,
import_definition: &ImportDefinition,
pid: &LocalPid,
) -> Result<(), Error> {
let import_tuple = tuple::get_tuple(definition)?;

let import_type = import_tuple
.first()
.ok_or(Error::Atom("missing_import_type"))?;
let import_type =
Atom::from_term(*import_type).map_err(|_| Error::Atom("import type must be an atom"))?;

if atoms::__fn__().eq(&import_type) {
return link_imported_function(
engine,
linker,
namespace_name.to_string(),
import_name.to_string(),
definition,
);
match import_definition {
ImportDefinition::Function {
namespace,
name,
params,
results,
} => link_imported_function(engine, linker, namespace, name, params, results, pid),
}

Err(Error::Atom("unknown import type"))
}

// Creates a wrapper function used in a Wasm import object.
Expand All @@ -112,32 +145,19 @@ fn link_import(
fn link_imported_function(
engine: &Engine,
linker: &mut Linker<StoreData>,
namespace_name: String,
import_name: String,
definition: Term,
namespace_name: &String,
import_name: &String,
params_signature: &Vec<ValType>,
results_signature: &Vec<ValType>,
pid: &LocalPid,
) -> Result<(), Error> {
let pid = definition.get_env().pid();

let import_tuple = tuple::get_tuple(definition)?;

let param_term = import_tuple
.get(1)
.ok_or(Error::Atom("missing_import_params"))?;
let results_term = import_tuple
.get(2)
.ok_or(Error::Atom("missing_import_results"))?;

let params_signature = param_term
.decode::<ListIterator>()?
.map(term_to_arg_type)
.collect::<Result<Vec<ValType>, _>>()?;

let results_signature = results_term
.decode::<ListIterator>()?
.map(term_to_arg_type)
.collect::<Result<Vec<ValType>, _>>()?;
let namespace_name = namespace_name.clone();
let import_name = import_name.clone();
let params_signature = params_signature.clone();
let results_signature = results_signature.clone();
let signature = FuncType::new(engine, params_signature.clone(), results_signature.clone());
let pid = pid.clone();

let signature = FuncType::new(engine, params_signature, results_signature.clone());
linker
.func_new(
&namespace_name.clone(),
Expand Down
Loading

0 comments on commit 6f83e90

Please sign in to comment.