1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#![deny(clippy::complexity)]
#![deny(clippy::correctness)]
#![warn(clippy::nursery)]
#![warn(clippy::pedantic)]
#![deny(clippy::perf)]
#![deny(clippy::style)]
#![deny(clippy::suspicious)]
#![warn(missing_docs)]

//! [![CI Status]][workflow] [![MSRV]][repo] [![Latest Version]][crates.io]
//! [![Rust Doc Crate]][docs.rs] [![Rust Doc Main]][docs]
//!
//! [CI Status]: https://img.shields.io/github/actions/workflow/status/juntyr/pyodide-webassembly-runtime-layer/ci.yml?branch=main
//! [workflow]: https://github.com/juntyr/pyodide-webassembly-runtime-layer/actions/workflows/ci.yml?query=branch%3Amain
//!
//! [MSRV]: https://img.shields.io/badge/MSRV-1.71.0-blue
//! [repo]: https://github.com/juntyr/pyodide-webassembly-runtime-layer
//!
//! [Latest Version]: https://img.shields.io/crates/v/pyodide-webassembly-runtime-layer
//! [crates.io]: https://crates.io/crates/pyodide-webassembly-runtime-layer
//!
//! [Rust Doc Crate]: https://img.shields.io/docsrs/pyodide-webassembly-runtime-layer
//! [docs.rs]: https://docs.rs/pyodide-webassembly-runtime-layer/
//!
//! [Rust Doc Main]: https://img.shields.io/badge/docs-main-blue
//! [docs]: https://juntyr.github.io/pyodide-webassembly-runtime-layer/pyodide_webassembly_runtime_layer
//!
//! `pyodide-webassembly-runtime-layer` implements the [`wasm_runtime_layer`]
//! backend API to provide access to the web browser's [`WebAssembly`] runtime
//! using [`Pyodide`].
//!
//! The implementation of this crate is heavily inspired by the
//! [`js_wasm_runtime_layer`] backend for the [`wasm_runtime_layer`]. Instead of
//! relying on the [`js-sys`] and [`wasm-bindgen`] crates to generate
//! JavaScript-based bindings to the [`WebAssembly`] JavaScript API, this crate
//! uses [`Pyodide`]'s [`js`] FFI layer to interact with [`WebAssembly`] through
//! Python running inside WASM. `pyodide-webassembly-runtime-layer` is therefore
//! useful when developing a Python module in Rust, e.g. using [`PyO3`], which
//! requires access to some WASM runtime using the [`wasm_runtime_layer`] API
//! and may be deployed to the web itself using [`Pyodide`].
//!
//! ## Memory Management
//!
//! `pyodide-webassembly-runtime-layer` generally tries to keep memory
//! management intuitive by relying primarily on Python's reference counting to
//! drop objects once they are no longer needed by both the user-written Rust
//! code and the [`WebAssembly`] runtime. As this crate coordinates interop
//! across Rust, Python, and JavaScript, it takes extra care to avoid reference
//! cycles across the different memory management strategies of the languages
//! which would otherwise lead to memory leakage. If using this crate produces a
//! memory leak that is avoided with a different [`wasm_runtime_layer`] backend,
//! please [report it as a bug][new-issue].
//!
//! There is one exception to the intuitive memory management strategy:
//!
//! - [`Func::new`] creates a host function, which may capture arbitrary data.
//!   To avoid cross-language reference cycles, it is stored using [`wobbly`]
//!   references inside the [`Func`] and its associated [`Store`]. Even though
//!   the host function and its data are dropped once either the [`Store`] is
//!   dropped or references to the [`Func`] are dropped, additional bookkeeping
//!   data is required until both have been dropped.
//!
//! [`wasm_runtime_layer`]: https://docs.rs/wasm_runtime_layer/0.4/
//! [`WebAssembly`]: https://developer.mozilla.org/en-US/docs/WebAssembly
//! [`Pyodide`]: https://pyodide.org/en/stable/
//! [`js_wasm_runtime_layer`]: https://docs.rs/js_wasm_runtime_layer/0.4/
//! [`js-sys`]: https://docs.rs/js-sys/
//! [`wasm-bindgen`]: https://docs.rs/wasm-bindgen/
//! [`js`]: https://pyodide.org/en/stable/usage/api/python-api.html
//! [`PyO3`]: https://docs.rs/pyo3/0.21/
//! [new-issue]: https://github.com/juntyr/pyodide-webassembly-runtime-layer/issues/new
//! [`Func::new`]: https://docs.rs/wasm_runtime_layer/0.4/wasm_runtime_layer/struct.Func.html#method.new
//! [`wobbly`]: https://docs.rs/wobbly/0.1/
//! [`Func`]: https://docs.rs/wasm_runtime_layer/0.4/wasm_runtime_layer/struct.Func.html
//! [`Store`]: https://docs.rs/wasm_runtime_layer/0.4/wasm_runtime_layer/struct.Store.html

use wasm_runtime_layer::backend::WasmEngine;

mod conversion;
mod externref;
mod features;
mod func;
mod global;
mod instance;
mod memory;
mod module;
mod store;
mod table;

pub use externref::ExternRef;
pub use func::Func;
pub use global::Global;
pub use instance::Instance;
pub use memory::Memory;
pub use module::Module;
pub use store::{Store, StoreContext, StoreContextMut};
pub use table::Table;

#[derive(Default, Debug, Clone)]
/// Runtime for [`WebAssembly`] web runtime.
///
/// [`WebAssembly`]: https://developer.mozilla.org/en-US/docs/WebAssembly
pub struct Engine {
    _private: (),
}

impl WasmEngine for Engine {
    type ExternRef = ExternRef;
    type Func = Func;
    type Global = Global;
    type Instance = Instance;
    type Memory = Memory;
    type Module = Module;
    type Store<T> = Store<T>;
    type StoreContext<'a, T: 'a> = StoreContext<'a, T>;
    type StoreContextMut<'a, T: 'a> = StoreContextMut<'a, T>;
    type Table = Table;
}