wasmer 0.1.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.cargo/config +1 -1
  3. data/.github/workflows/documentation.yml +50 -0
  4. data/.github/workflows/test.yml +73 -0
  5. data/.gitignore +3 -1
  6. data/CHANGELOG.md +225 -0
  7. data/Cargo.lock +747 -708
  8. data/Cargo.toml +7 -21
  9. data/Gemfile +2 -3
  10. data/LICENSE +21 -0
  11. data/README.md +1 -0
  12. data/Rakefile +4 -3
  13. data/bors.toml +6 -0
  14. data/crates/rutie-derive-macros/Cargo.toml +19 -0
  15. data/crates/rutie-derive-macros/README.md +4 -0
  16. data/crates/rutie-derive-macros/src/class.rs +156 -0
  17. data/crates/rutie-derive-macros/src/function.rs +178 -0
  18. data/crates/rutie-derive-macros/src/lib.rs +27 -0
  19. data/crates/rutie-derive-macros/src/methods.rs +282 -0
  20. data/crates/rutie-derive/Cargo.toml +14 -0
  21. data/crates/rutie-derive/README.md +97 -0
  22. data/crates/rutie-derive/src/lib.rs +4 -0
  23. data/crates/rutie-derive/src/upcast.rs +47 -0
  24. data/crates/rutie-test/Cargo.toml +10 -0
  25. data/crates/rutie-test/src/lib.rs +38 -0
  26. data/crates/wasmer/Cargo.toml +27 -0
  27. data/crates/wasmer/README.md +229 -0
  28. data/crates/wasmer/src/doc.rs +1512 -0
  29. data/crates/wasmer/src/error.rs +55 -0
  30. data/crates/wasmer/src/exports.rs +107 -0
  31. data/crates/wasmer/src/externals/function.rs +159 -0
  32. data/crates/wasmer/src/externals/global.rs +62 -0
  33. data/crates/wasmer/src/externals/memory.rs +117 -0
  34. data/crates/wasmer/src/externals/mod.rs +9 -0
  35. data/crates/wasmer/src/externals/table.rs +41 -0
  36. data/crates/wasmer/src/import_object.rs +78 -0
  37. data/crates/wasmer/src/instance.rs +45 -0
  38. data/crates/wasmer/src/lib.rs +307 -0
  39. data/crates/wasmer/src/memory/mod.rs +1 -0
  40. data/crates/wasmer/src/memory/views.rs +112 -0
  41. data/crates/wasmer/src/module.rs +106 -0
  42. data/crates/wasmer/src/prelude.rs +3 -0
  43. data/crates/wasmer/src/store.rs +22 -0
  44. data/crates/wasmer/src/types.rs +396 -0
  45. data/crates/wasmer/src/values.rs +84 -0
  46. data/crates/wasmer/src/wasi.rs +226 -0
  47. data/crates/wasmer/src/wat.rs +20 -0
  48. data/justfile +20 -2
  49. data/lib/wasmer.rb +29 -3
  50. data/wasmer.gemspec +8 -12
  51. metadata +53 -49
  52. data/.circleci/config.yml +0 -70
  53. data/README.md +0 -279
  54. data/lib/wasmer/version.rb +0 -3
  55. data/src/instance.rs +0 -282
  56. data/src/lib.rs +0 -98
  57. data/src/memory/mod.rs +0 -120
  58. data/src/memory/view.rs +0 -127
  59. data/src/module.rs +0 -28
@@ -0,0 +1,10 @@
1
+ [package]
2
+ name = "rutie-test"
3
+ version = "0.1.0"
4
+ authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
5
+ edition = "2018"
6
+ description = "Helpers to test code written with `rutie`."
7
+ readme = "README.md"
8
+ repository = "https://github.com/wasmerio/wasmer-ruby"
9
+ keywords = ["ruby", "extension"]
10
+ publish = false
@@ -0,0 +1,38 @@
1
+ #[macro_export]
2
+ macro_rules! test_ruby {
3
+ ($code:expr) => {
4
+ use rutie::VM;
5
+
6
+ let code = format!(
7
+ r#"
8
+ root = File.expand_path("../..", ENV["CARGO_MANIFEST_DIR"])
9
+
10
+ Dir.chdir(root)
11
+
12
+ $LOAD_PATH.unshift(File.expand_path("lib", root))
13
+
14
+ require "wasmer"
15
+
16
+ class AssertionError < RuntimeError
17
+ end
18
+
19
+ def assert &block
20
+ raise AssertionError unless yield
21
+ end
22
+
23
+ {code}
24
+ "#,
25
+ code = $code
26
+ );
27
+
28
+ VM::init();
29
+ VM::init_loadpath();
30
+
31
+ match VM::eval(&code) {
32
+ Ok(value) => assert!(true),
33
+ Err(err) => panic!("{:?}", err),
34
+ }
35
+ };
36
+ }
37
+
38
+ pub fn foo() {}
@@ -0,0 +1,27 @@
1
+ [package]
2
+ name = "wasmer"
3
+ version = "1.0.0"
4
+ authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
5
+ edition = "2018"
6
+ description = "Ruby extension to run WebAssembly binaries"
7
+ readme = "README.md"
8
+ repository = "https://github.com/wasmerio/wasmer-ruby"
9
+ keywords = ["ruby", "extension", "webassembly"]
10
+ categories = ["wasm"]
11
+ publish = false
12
+
13
+ [lib]
14
+ name = "wasmer_ruby"
15
+ crate-type = ["dylib", "rlib"]
16
+
17
+ [dependencies]
18
+ wasmer = "2.0"
19
+ wasmer-wasi = "2.0"
20
+ rutie = "0.8"
21
+ rutie-derive = { path = "../rutie-derive", version = "0.1.0" }
22
+ lazy_static = "1.4"
23
+ wat = "1.0"
24
+ wasmprinter = "0.2"
25
+
26
+ [dev-dependencies]
27
+ rutie-test = { path = "../rutie-test", version = "0.1.0" }
@@ -0,0 +1,229 @@
1
+ <div align="center">
2
+ <a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
3
+ <img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
4
+ </a>
5
+
6
+ <h1>Wasmer Ruby</h1>
7
+
8
+ <p>
9
+ <a href="https://github.com/wasmerio/wasmer-ruby/actions?query=workflow%3A%22Build+and+Test%22">
10
+ <img src="https://github.com/wasmerio/wasmer-ruby/workflows/Build%20and%20Test/badge.svg" alt="Build Status">
11
+ </a>
12
+ <a href="https://github.com/wasmerio/wasmer-ruby/blob/master/LICENSE">
13
+ <img src="https://img.shields.io/github/license/wasmerio/wasmer-ruby.svg" alt="License">
14
+ </a>
15
+ <a href="https://rubygems.org/gems/wasmer">
16
+ <img src="https://img.shields.io/gem/v/wasmer.svg" alt="Wasmer on RubyGem">
17
+ </a>
18
+ <a href="https://rubygems.org/gems/wasmer">
19
+ <img src="https://img.shields.io/gem/dt/wasmer.svg" alt="Number of downloads">
20
+ </a>
21
+ <a href="https://wasmerio.github.io/wasmer-ruby/wasmer_ruby/index.html">
22
+ <img src="https://img.shields.io/badge/documentation-API-f06" alt="API Documentation">
23
+ </a>
24
+ </p>
25
+
26
+ <h3>
27
+ <a href="https://wasmer.io/">Website</a>
28
+ <span> • </span>
29
+ <a href="https://wasmerio.github.io/wasmer-ruby/wasmer_ruby/index.html">Docs</a>
30
+ <span> • </span>
31
+ <a href="https://slack.wasmer.io/">Slack Channel</a>
32
+ </h3>
33
+ </div>
34
+
35
+ <hr/>
36
+
37
+ A complete and mature WebAssembly runtime for Ruby based on
38
+ [Wasmer](https://github.com/wasmerio/wasmer).
39
+
40
+ Features
41
+
42
+ * **Easy to use**: The `wasmer` API mimics the standard WebAssembly API,
43
+ * **Fast**: `wasmer` executes the WebAssembly modules as fast as
44
+ possible, close to **native speed**,
45
+ * **Safe**: All calls to WebAssembly will be fast, but more
46
+ importantly, completely safe and sandboxed.
47
+
48
+ **Documentation**: [browse the detailed API
49
+ documentation](https://wasmerio.github.io/wasmer-ruby/wasmer_ruby/index.html)
50
+ full of examples.
51
+
52
+ **Examples** as tutorials: [browser the `examples/`
53
+ directory](https://github.com/wasmerio/wasmer-ruby/tree/master/examples),
54
+ it's the best place for a complete introduction!
55
+
56
+ # Quick Introduction
57
+
58
+ The `wasmer` package brings the required API to execute WebAssembly
59
+ modules. In a nutshell, `wasmer` compiles the WebAssembly module into
60
+ compiled code, and then executes it. `wasmer` is designed to work in
61
+ various environments and platforms. To achieve this, Wasmer (the
62
+ original runtime) provides multiple engines and multiple
63
+ compilers.
64
+
65
+ Succinctly, an _engine_ is responsible to drive the _compilation_ (by
66
+ using a _compiler_) and the _execution_ of a WebAssembly
67
+ module. Wasmer comes with many engines and compilers, but for the Ruby
68
+ extension, it only provides the JIT engine with the Cranelift
69
+ compiler. It is subject to change in the future where the user will
70
+ have the choice to select its own engine and compiler.
71
+
72
+ ## Install
73
+
74
+ To install the `wasmer` Ruby gem, just run this command in your shell:
75
+
76
+ ```sh
77
+ $ gem install wasmer
78
+ ```
79
+
80
+ And you're ready to get fun!
81
+
82
+ [View the `wasmer` gem on RubyGems][wasmer-gem].
83
+
84
+ > Note: [Rust][rust] is required to install the Ruby library (Cargo
85
+ —the build tool for Rust— is used to compile the extension). See [how
86
+ to install Rust][install-rust].
87
+
88
+ ## Example
89
+
90
+ We highly recommend to read the
91
+ [`examples/`](https://github.com/wasmerio/wasmer-ruby/tree/master/examples)
92
+ directory, which contains a sequence of examples/tutorials. It's the
93
+ best place to learn by reading examples.
94
+
95
+ But for the most eager of you, and we know you're numerous you
96
+ mischievous, there is a quick toy program in
97
+ `examples/appendices/simple.rs`, written in Rust:
98
+
99
+ ```rust
100
+ #[no_mangle]
101
+ pub extern fn sum(x: i32, y: i32) -> i32 {
102
+ x + y
103
+ }
104
+ ```
105
+
106
+ After compilation to WebAssembly, the
107
+ [`examples/appendices/simple.wasm`](https://github.com/wasmerio/wasmer-ruby/blob/master/examples/appendices/simple.wasm)
108
+ binary file is generated.
109
+
110
+ Then, we can execute it in Ruby:
111
+
112
+ ```ruby
113
+ require "wasmer"
114
+
115
+ # Let's define the store, that holds the engine, that holds the compiler.
116
+ store = Wasmer::Store.new
117
+
118
+ # Let's compile the module to be able to execute it!
119
+ module_ = Wasmer::Module.new store, IO.read("simple.wasm", mode: "rb")
120
+
121
+ # Now the module is compiled, we can instantiate it.
122
+ instance = Wasmer::Instance.new module_, nil
123
+
124
+ # Call the exported `sum` function.
125
+ result = instance.exports.sum.(5, 37)
126
+
127
+ puts result # 42!
128
+ ```
129
+
130
+ And then, finally, enjoy by running:
131
+
132
+ ```sh
133
+ $ ruby examples/appendices/simple.rb
134
+ ```
135
+
136
+ ## Development
137
+
138
+ The Ruby extension is written in [Rust][rust], with [`rutie`][rutie].
139
+
140
+ First, you need to install Rust and Ruby. We will not make you the
141
+ affront to explain to you how to install Ruby (if you really need,
142
+ check [`rbenv`][rbenv]). For Rust though, we advice to use
143
+ [`rustup`][rustup], then:
144
+
145
+ ```sh
146
+ $ rustup install stable
147
+ ```
148
+
149
+ Then, after installing [`just`][just], you can simply run:
150
+
151
+ ```sh
152
+ $ just build
153
+ ```
154
+
155
+ The supported Ruby versions are:
156
+
157
+ * Ruby 2.6,
158
+ * Ruby 2.7,
159
+ * Ruby 3.0.
160
+
161
+ ### Extensions to `rutie`
162
+
163
+ This project provides extensions to `rutie`, through the
164
+ `rutie-derive` and `rutie-derive-macros` crates (see the `crates/`
165
+ directory). Those crates aim at enhancing `rutie` by providing a
166
+ better “Domain Specific Language” (DSL for short) to declare Ruby
167
+ modules, classes, methods and functions. It's not perfect but it does
168
+ a good job for the moment. Contributions on that front are welcomed
169
+ too!
170
+
171
+ ### Testing
172
+
173
+ Running the `test-all` recipe will automatically build and run all the
174
+ tests. It includes library tests, along with documentation tests and
175
+ the examples:
176
+
177
+ ```sh
178
+ $ just test-all
179
+ ```
180
+
181
+ ### Documentation
182
+
183
+ To generate the documentation, run the following command:
184
+
185
+ ```sh
186
+ $ just doc
187
+ ```
188
+
189
+ All the examples in the documentation are automatically run as tests,
190
+ called doctests. To run the doctests, run `just test`.
191
+
192
+ ## What is WebAssembly?
193
+
194
+ Quoting [the WebAssembly site][wasm]:
195
+
196
+ > WebAssembly (abbreviated Wasm) is a binary instruction format for a
197
+ > stack-based virtual machine. Wasm is designed as a portable target
198
+ > for compilation of high-level languages like C/C++/Rust, enabling
199
+ > deployment on the web for client and server applications.
200
+
201
+ About speed:
202
+
203
+ > WebAssembly aims to execute at native speed by taking advantage of
204
+ > [common hardware
205
+ > capabilities](https://webassembly.org/docs/portability/#assumptions-for-efficient-execution)
206
+ > available on a wide range of platforms.
207
+
208
+ About safety:
209
+
210
+ > WebAssembly describes a memory-safe, sandboxed [execution
211
+ > environment](https://webassembly.org/docs/semantics/#linear-memory) […].
212
+
213
+ [wasm]: https://webassembly.org/
214
+
215
+ ## License
216
+
217
+ The entire project is under the MIT License. Please read [the
218
+ `LICENSE` file][license].
219
+
220
+ [license]: https://github.com/wasmerio/wasmer/blob/master/LICENSE
221
+
222
+ [Wasmer]: https://github.com/wasmerio/wasmer
223
+ [rust]: https://www.rust-lang.org/
224
+ [install-rust]: https://www.rust-lang.org/tools/install
225
+ [wasmer-gem]: https://rubygems.org/gems/wasmer
226
+ [rutie]: https://github.com/danielpclark/rutie
227
+ [rbenv]: https://github.com/rbenv/rbenv
228
+ [rustup]: https://rustup.rs/
229
+ [just]: https://github.com/casey/just/
@@ -0,0 +1,1512 @@
1
+ macro_rules! x {
2
+ () => {
3
+ unimplemented!("This code exists only for documentation purposes");
4
+ };
5
+ }
6
+
7
+ /// Declare Ruby native types. It's only for documentation purposes.
8
+ pub mod Ruby {
9
+ /// A native Ruby boolean.
10
+ ///
11
+ /// # Example
12
+ ///
13
+ /// ```rust
14
+ /// # fn main() { rutie_test::test_ruby!(r#"
15
+ /// true
16
+ /// # "#); }
17
+ /// ```
18
+ pub struct Boolean;
19
+
20
+ /// A native Ruby integer.
21
+ ///
22
+ /// # Example
23
+ ///
24
+ /// ```rust
25
+ /// # fn main() { rutie_test::test_ruby!(r#"
26
+ /// 42
27
+ /// # "#); }
28
+ /// ```
29
+ pub struct Integer;
30
+
31
+ /// A native Ruby float.
32
+ ///
33
+ /// # Example
34
+ ///
35
+ /// ```rust
36
+ /// # fn main() { rutie_test::test_ruby!(r#"
37
+ /// 4.2
38
+ /// # "#); }
39
+ /// ```
40
+ pub struct Float;
41
+
42
+ /// A native Ruby string.
43
+ ///
44
+ /// # Example
45
+ ///
46
+ /// ```rust
47
+ /// # fn main() { rutie_test::test_ruby!(r#"
48
+ /// "hello"
49
+ /// # "#); }
50
+ /// ```
51
+ pub struct String;
52
+
53
+ /// A native Ruby array.
54
+ ///
55
+ /// # Example
56
+ ///
57
+ /// ```rust
58
+ /// # fn main() { rutie_test::test_ruby!(r#"
59
+ /// [1, "two", 3.0]
60
+ /// # "#); }
61
+ /// ```
62
+ pub struct Array<T>;
63
+
64
+ /// A native Ruby hash.
65
+ ///
66
+ /// # Example
67
+ ///
68
+ /// ```rust
69
+ /// # fn main() { rutie_test::test_ruby!(r#"
70
+ /// {"foo": 42, "bar": 153}
71
+ /// # "#); }
72
+ /// ```
73
+ pub struct Hash<K, V>;
74
+
75
+ /// Represents any kind of object.
76
+ pub struct Any;
77
+ }
78
+
79
+ /// The `Wasmer` module provides the entire Wasmer API to manipulate
80
+ /// the WebAssembly runtime.
81
+ pub mod Wasmer {
82
+ use crate::doc::Ruby::*;
83
+
84
+ /// A WebAssembly type.
85
+ ///
86
+ /// # Example
87
+ ///
88
+ /// ```rust
89
+ /// # fn main() { rutie_test::test_ruby!(r#"
90
+ /// Wasmer::Type::I32
91
+ /// # "#); }
92
+ /// ```
93
+ #[allow(non_camel_case_types)]
94
+ pub enum Type {
95
+ I32,
96
+ I64,
97
+ F32,
98
+ F64,
99
+ V128,
100
+ EXTERN_REF,
101
+ FUNC_REF,
102
+ }
103
+
104
+ /// Represents the signature of a function that is either
105
+ /// implemented in WebAssembly module or exposed to WebAssembly by
106
+ /// the host.
107
+ ///
108
+ /// WebAssembly functions can have 0 or more parameters and results.
109
+ pub struct FunctionType;
110
+
111
+ impl FunctionType {
112
+ /// Creates a new `FunctionType`.
113
+ ///
114
+ /// # Example
115
+ ///
116
+ /// ```rust
117
+ /// # fn main() { rutie_test::test_ruby!(r#"
118
+ /// function_type = Wasmer::FunctionType.new(
119
+ /// [Wasmer::Type::I32, Wasmer::Type::I64],
120
+ /// [Wasmer::Type::I32]
121
+ /// )
122
+ /// # "#); }
123
+ /// ```
124
+ pub fn new(params: Array<Type>, results: Array<Type>) -> Self {
125
+ x!()
126
+ }
127
+
128
+ /// Returns the parameters.
129
+ ///
130
+ /// # Example
131
+ ///
132
+ /// ```rust
133
+ /// # fn main() { rutie_test::test_ruby!(r#"
134
+ /// function_type = Wasmer::FunctionType.new(
135
+ /// [Wasmer::Type::I32, Wasmer::Type::I64],
136
+ /// [Wasmer::Type::I32]
137
+ /// )
138
+ ///
139
+ /// assert { function_type.params == [Wasmer::Type::I32, Wasmer::Type::I64] }
140
+ /// # "#); }
141
+ /// ```
142
+ pub fn params(&self) -> Array<Type> {
143
+ x!()
144
+ }
145
+
146
+ /// Returns the results.
147
+ ///
148
+ /// # Example
149
+ ///
150
+ /// ```rust
151
+ /// # fn main() { rutie_test::test_ruby!(r#"
152
+ /// function_type = Wasmer::FunctionType.new(
153
+ /// [Wasmer::Type::I32, Wasmer::Type::I64],
154
+ /// [Wasmer::Type::I32]
155
+ /// )
156
+ ///
157
+ /// assert { function_type.results == [Wasmer::Type::I32] }
158
+ /// # "#); }
159
+ /// ```
160
+ pub fn results(&self) -> Array<Type> {
161
+ x!()
162
+ }
163
+ }
164
+
165
+ /// A descriptor for a WebAssembly memory type.
166
+ ///
167
+ /// Memories are described in units of pages (64Kb) and represent
168
+ /// contiguous chunks of addressable memory.
169
+ pub struct MemoryType;
170
+
171
+ impl MemoryType {
172
+ /// Creates a new `MemoryType`.
173
+ ///
174
+ /// # Example
175
+ ///
176
+ /// ```rust
177
+ /// # fn main() { rutie_test::test_ruby!(r#"
178
+ /// memory_type = Wasmer::MemoryType.new 1, 3, true
179
+ /// # "#); }
180
+ /// ```
181
+ pub fn new(minimum: Integer, maximum: Option<Integer>, shared: Boolean) -> Self {
182
+ x!()
183
+ }
184
+
185
+ /// Returns the minimum size of the memory.
186
+ ///
187
+ /// # Example
188
+ ///
189
+ /// ```rust
190
+ /// # fn main() { rutie_test::test_ruby!(r#"
191
+ /// memory_type = Wasmer::MemoryType.new 1, 3, true
192
+ ///
193
+ /// assert { memory_type.minimum == 1 }
194
+ /// # "#); }
195
+ /// ```
196
+ pub fn minimum(&self) -> Integer {
197
+ x!()
198
+ }
199
+
200
+ /// Returns the maximum size of the memory of any.
201
+ ///
202
+ /// # Example
203
+ ///
204
+ /// ```rust
205
+ /// # fn main() { rutie_test::test_ruby!(r#"
206
+ /// memory_type = Wasmer::MemoryType.new 1, 3, true
207
+ ///
208
+ /// assert { memory_type.maximum == 3 }
209
+ /// # "#); }
210
+ /// ```
211
+ pub fn maximum(&self) -> Option<Integer> {
212
+ x!()
213
+ }
214
+
215
+ /// Returns whether the memory is shared or not.
216
+ ///
217
+ /// # Example
218
+ ///
219
+ /// ```rust
220
+ /// # fn main() { rutie_test::test_ruby!(r#"
221
+ /// memory_type = Wasmer::MemoryType.new 1, 3, true
222
+ ///
223
+ /// assert { memory_type.shared? }
224
+ /// # "#); }
225
+ /// ```
226
+ pub fn shared(&self) -> Integer {
227
+ x!()
228
+ }
229
+ }
230
+
231
+ /// A descriptor for a WebAssembly global.
232
+ pub struct GlobalType;
233
+
234
+ impl GlobalType {
235
+ /// Creates a new `GlobalType`.
236
+ ///
237
+ /// # Example
238
+ ///
239
+ /// ```rust
240
+ /// # fn main() { rutie_test::test_ruby!(r#"
241
+ /// global_type = Wasmer::GlobalType.new Wasmer::Type::I32, true
242
+ /// # "#); }
243
+ /// ```
244
+ pub fn new(r#type: Type, mutable: Boolean) -> Self {
245
+ x!()
246
+ }
247
+
248
+ /// Returns the type of the global.
249
+ ///
250
+ /// # Example
251
+ ///
252
+ /// ```rust
253
+ /// # fn main() { rutie_test::test_ruby!(r#"
254
+ /// global_type = Wasmer::GlobalType.new Wasmer::Type::I32, true
255
+ ///
256
+ /// assert { global_type.type == Wasmer::Type::I32 }
257
+ /// # "#); }
258
+ /// ```
259
+ pub fn r#type(&self) -> Type {
260
+ x!()
261
+ }
262
+
263
+ /// Returns whether the global is mutable.
264
+ ///
265
+ /// # Example
266
+ ///
267
+ /// ```rust
268
+ /// # fn main() { rutie_test::test_ruby!(r#"
269
+ /// global_type = Wasmer::GlobalType.new Wasmer::Type::I32, true
270
+ ///
271
+ /// assert { global_type.mutable? }
272
+ /// # "#); }
273
+ /// ```
274
+ pub fn mutable(&self) -> Boolean {
275
+ x!()
276
+ }
277
+ }
278
+
279
+ /// A descriptor for a table in a WebAssembly module.
280
+ ///
281
+ /// Tables are contiguous chunks of a specific element, typically
282
+ /// a funcref or externref. The most common use for tables is a
283
+ /// function table through which call_indirect can invoke other
284
+ /// functions.
285
+ pub struct TableType;
286
+
287
+ impl TableType {
288
+ /// Creates a new `TableType`.
289
+ ///
290
+ /// # Example
291
+ ///
292
+ /// ```rust
293
+ /// # fn main() { rutie_test::test_ruby!(r#"
294
+ /// table_type = Wasmer::TableType.new Wasmer::Type::I32, 7, 42
295
+ /// # "#); }
296
+ /// ```
297
+ pub fn new(r#type: Type, minimum: Integer, maximum: Option<Integer>) -> Self {
298
+ x!()
299
+ }
300
+
301
+ /// Returns the type of table.
302
+ ///
303
+ /// # Example
304
+ ///
305
+ /// ```rust
306
+ /// # fn main() { rutie_test::test_ruby!(r#"
307
+ /// table_type = Wasmer::TableType.new Wasmer::Type::I32, 7, 42
308
+ ///
309
+ /// assert { table_type.type == Wasmer::Type::I32 }
310
+ /// # "#); }
311
+ /// ```
312
+ pub fn r#type(&self) -> Type {
313
+ x!()
314
+ }
315
+
316
+ /// Returns the minimum size of the table.
317
+ ///
318
+ /// # Example
319
+ ///
320
+ /// ```rust
321
+ /// # fn main() { rutie_test::test_ruby!(r#"
322
+ /// table_type = Wasmer::TableType.new Wasmer::Type::I32, 7, 42
323
+ ///
324
+ /// assert { table_type.minimum == 7 }
325
+ /// # "#); }
326
+ /// ```
327
+ pub fn minimum(&self) -> Integer {
328
+ x!()
329
+ }
330
+
331
+ /// Returns the maximum size of the table if any.
332
+ ///
333
+ /// # Example
334
+ ///
335
+ /// ```rust
336
+ /// # fn main() { rutie_test::test_ruby!(r#"
337
+ /// table_type = Wasmer::TableType.new Wasmer::Type::I32, 7, 42
338
+ ///
339
+ /// assert { table_type.maximum == 42 }
340
+ /// # "#); }
341
+ /// ```
342
+ pub fn maximum(&self) -> Option<Integer> {
343
+ x!()
344
+ }
345
+ }
346
+
347
+ /// Represents the type of a module's export (not to be confused
348
+ /// with an export of an instance). It is usually built from the
349
+ /// [`Module::exports`] getter.
350
+ pub struct ExportType;
351
+
352
+ impl ExportType {
353
+ /// Creates a new `ExportType`.
354
+ ///
355
+ /// `type` must be of type [`FunctionType`], [`MemoryType`],
356
+ /// [`GlobalType`] or [`TableType`].
357
+ ///
358
+ /// # Example
359
+ ///
360
+ /// ```rust,ignore
361
+ /// # fn main() { rutie_test::test_ruby!(r#"
362
+ /// export_type = Wasmer::ExportType.new "foo", Wasmer::Function.new([Wasmer::Type::I32], [])
363
+ /// # "#); }
364
+ /// ```
365
+ pub fn new(name: String, r#type: Any) -> Self {
366
+ x!()
367
+ }
368
+
369
+ /// Returns the name of the export.
370
+ ///
371
+ /// # Example
372
+ ///
373
+ /// ```rust,ignore
374
+ /// # fn main() { rutie_test::test_ruby!(r#"
375
+ /// export_type = Wasmer::ExportType.new "foo", Wasmer::Function.new([Wasmer::Type::I32], [])
376
+ ///
377
+ /// assert { export_type.name == "foo" }
378
+ /// # "#); }
379
+ /// ```
380
+ pub fn name(&self) -> String {
381
+ x!()
382
+ }
383
+
384
+ /// Returns the type of the export.
385
+ ///
386
+ /// # Example
387
+ ///
388
+ /// ```rust,ignore
389
+ /// # fn main() { rutie_test::test_ruby!(r#"
390
+ /// export_type = Wasmer::ExportType.new "foo", Wasmer::Function.new([Wasmer::Type::I32], [])
391
+ ///
392
+ /// assert { export_type.type == Wasmer::Type::I32 }
393
+ /// # "#); }
394
+ /// ```
395
+ pub fn r#type(&self) -> Type {
396
+ x!()
397
+ }
398
+ }
399
+
400
+ /// Represents the type of a module's import. It is usually built
401
+ /// from the [`Module::imports`] getter.
402
+ pub struct ImportType;
403
+
404
+ impl ImportType {
405
+ /// Creates a new `ImportType`.
406
+ ///
407
+ /// `type` must be of type [`FunctionType`], [`MemoryType`],
408
+ /// [`GlobalType`] or [`TableType`].
409
+ ///
410
+ /// # Example
411
+ ///
412
+ /// ```rust,ignore
413
+ /// # fn main() { rutie_test::test_ruby!(r#"
414
+ /// import_type = Wasmer::ImportType.new "foo", "bar", Wasmer::Function.new([Wasmer::Type::I32], [])
415
+ /// # "#); }
416
+ /// ```
417
+ pub fn new(module: String, name: String, r#type: Any) -> Self {
418
+ x!()
419
+ }
420
+
421
+ /// Returns the module's name of the import.
422
+ ///
423
+ /// # Example
424
+ ///
425
+ /// ```rust,ignore
426
+ /// # fn main() { rutie_test::test_ruby!(r#"
427
+ /// import_type = Wasmer::ImportType.new "foo", "bar", Wasmer::Function.new([Wasmer::Type::I32], [])
428
+ /// # "#); }
429
+ ///
430
+ /// assert { import_type.module == "foo" }
431
+ /// ```
432
+ pub fn module(&self) -> String {
433
+ x!()
434
+ }
435
+
436
+ /// Returns the name of the import.
437
+ ///
438
+ /// # Example
439
+ ///
440
+ /// ```rust,ignore
441
+ /// # fn main() { rutie_test::test_ruby!(r#"
442
+ /// import_type = Wasmer::ImportType.new "foo", "bar", Wasmer::Function.new([Wasmer::Type::I32], [])
443
+ /// # "#); }
444
+ ///
445
+ /// assert { import_type.name == "bar" }
446
+ /// ```
447
+ pub fn name(&self) -> String {
448
+ x!()
449
+ }
450
+
451
+ /// Returns the type of the import.
452
+ ///
453
+ /// # Example
454
+ ///
455
+ /// ```rust,ignore
456
+ /// # fn main() { rutie_test::test_ruby!(r#"
457
+ /// import_type = Wasmer::ImportType.new "foo", "bar", Wasmer::Function.new([Wasmer::Type::I32], [])
458
+ /// # "#); }
459
+ ///
460
+ /// assert { import_type.type == Wasmer::Type::I32 }
461
+ /// ```
462
+ pub fn r#type(&self) -> Type {
463
+ x!()
464
+ }
465
+ }
466
+
467
+ /// The store represents all global state that can be manipulated
468
+ /// by WebAssembly programs. It consists of the runtime
469
+ /// representation of all instances of functions, tables,
470
+ /// memories, and globals that have been allocated during the
471
+ /// lifetime of the abstract machine.
472
+ ///
473
+ /// The `Store` holds the engine (that is —amongst many things— used
474
+ /// to compile the WebAssembly bytes into a valid module
475
+ /// artifact), in addition to the Tunables (that are used to
476
+ /// create the memories, tables and globals). For the moment, it's
477
+ /// not possible to tweak the engines and the compilers.
478
+ ///
479
+ /// Specification: <https://webassembly.github.io/spec/core/exec/runtime.html#store>
480
+ ///
481
+ /// # Example
482
+ ///
483
+ /// Use the store with the default engine and the default compiler:
484
+ ///
485
+ /// ```rust
486
+ /// # fn main() { rutie_test::test_ruby!(r#"
487
+ /// store = Wasmer::Store.new
488
+ /// # "#); }
489
+ /// ```
490
+ pub struct Store;
491
+
492
+ impl Store {
493
+ /// Creates a new `Store`.
494
+ pub fn new() -> Self {
495
+ x!()
496
+ }
497
+ }
498
+
499
+ /// A WebAssembly module contains stateless WebAssembly code that has
500
+ /// already been compiled and can be instantiated multiple times.
501
+ ///
502
+ /// Creates a new WebAssembly `Module` given the configuration in the
503
+ /// store.
504
+ ///
505
+ /// If the provided bytes are not WebAssembly-like (start with
506
+ /// b"\0asm"), this function will try to to convert the bytes assuming
507
+ /// they correspond to the WebAssembly text format.
508
+ ///
509
+ /// # Security
510
+ ///
511
+ /// Before the code is compiled, it will be validated using the store
512
+ /// features.
513
+ ///
514
+ /// # Example
515
+ ///
516
+ /// ```rust
517
+ /// # fn main() { rutie_test::test_ruby!(r#"
518
+ /// store = Wasmer::Store.new
519
+ ///
520
+ /// ## Let's compile WebAssembly from bytes.
521
+ /// wasm_bytes = "\x00asm\x01\x00\x00\x00";
522
+ /// module_ = Wasmer::Module.new store, wasm_bytes
523
+ ///
524
+ /// ## Let's compile WebAssembly from WAT.
525
+ /// module_ = Wasmer::Module.new store, "(module)"
526
+ /// # "#); }
527
+ /// ```
528
+ pub struct Module;
529
+
530
+ impl Module {
531
+ /// Validates a new WebAssembly Module given the configuration
532
+ /// in the [`Store`].
533
+ ///
534
+ /// This validation is normally pretty fast and checks the
535
+ /// enabled WebAssembly features in the Store engine to assure
536
+ /// deterministic validation of the `Module`.
537
+ ///
538
+ /// # Example
539
+ ///
540
+ /// ```rust
541
+ /// # fn main() { rutie_test::test_ruby!(r#"
542
+ /// wasm_bytes = "\x00asm\x01\x00\x00\x00";
543
+ /// Wasmer::Module.validate Wasmer::Store.new, wasm_bytes
544
+ /// # "#); }
545
+ /// ```
546
+ pub fn validate(store: Store, bytes: String) -> Boolean {
547
+ x!()
548
+ }
549
+
550
+ /// Creates a new [`Module`].
551
+ pub fn new(store: Store, bytes: String) -> Self {
552
+ x!()
553
+ }
554
+
555
+ /// Get or set the current name of the module.
556
+ ///
557
+ /// This name is normally set in the WebAssembly bytecode by
558
+ /// some compilers, but can be also overwritten.
559
+ ///
560
+ /// Not all modules have a name.
561
+ ///
562
+ /// # Example
563
+ ///
564
+ /// ```rust
565
+ /// # fn main() { rutie_test::test_ruby!(r#"
566
+ /// store = Wasmer::Store.new
567
+ ///
568
+ /// ## Module with an existing name.
569
+ /// assert { Wasmer::Module.new(store, "(module $moduleName)").name == "moduleName" }
570
+ ///
571
+ /// ## Module with no name.
572
+ /// assert { Wasmer::Module.new(store, "(module)").name.nil? }
573
+ ///
574
+ /// ## Change the module's name.
575
+ /// module_ = Wasmer::Module.new store, "(module $moduleName)"
576
+ /// module_.name = "hello"
577
+ ///
578
+ /// assert { module_.name == "hello" }
579
+ /// # "#); }
580
+ /// ```
581
+ pub fn name(&self, name: String) {
582
+ x!()
583
+ }
584
+
585
+ /// Returns a list of [`ExportType`] objects, which represents
586
+ /// all the exports of this module.
587
+ ///
588
+ /// The order of the exports is guaranteed to be the same as
589
+ /// in the WebAssembly bytecode.
590
+ ///
591
+ /// # Example
592
+ ///
593
+ /// See the [`ExportType`] class to learn more.
594
+ pub fn exports(&self) -> Array<ExportType> {
595
+ x!()
596
+ }
597
+
598
+ /// Returns a list of [`ImportType`] objects, which represents
599
+ /// all the imports of this module.
600
+ ///
601
+ /// The order of the imports is guaranteed to be the same as
602
+ /// in the WebAssembly bytecode.
603
+ ///
604
+ /// # Example
605
+ ///
606
+ /// See the [`ImportType`] class to learn more.
607
+ pub fn imports(&self) -> Array<ImportType> {
608
+ x!()
609
+ }
610
+
611
+ /// Get the custom sections of the module given a `name`.
612
+ ///
613
+ /// # Important
614
+ ///
615
+ /// Following the WebAssembly specification, one name can have
616
+ /// multiple custom sections. That's why a list of bytes is
617
+ /// returned rather than bytes.
618
+ ///
619
+ /// Consequently, the empty list represents the absence of a
620
+ /// custom section for the given name.
621
+ ///
622
+ /// # Example
623
+ ///
624
+ /// ```rust,ignore
625
+ /// # fn main() { rutie_test::test_ruby!(r#"
626
+ /// bytes = IO.read "custom_sections.wasm", mode: "rb"
627
+ /// module_ = Wasmer::Module.new Wasmer::Store.new, bytes
628
+ ///
629
+ /// assert { module_.custom_sections("easter_egg") == ["Wasmer"] }
630
+ /// assert { module_.custom_sections("hello") == ["World!"] }
631
+ /// assert { module_.custom_sections("foo") == [] }
632
+ /// # "#); }
633
+ /// ```
634
+ pub fn custom_sections(&self, name: String) -> Array<String> {
635
+ x!()
636
+ }
637
+
638
+ /// Serializes a module into a binary representation that the
639
+ /// engine can later process via [`Module::deserialize`].
640
+ ///
641
+ /// # Example
642
+ ///
643
+ /// ```rust
644
+ /// # fn main() { rutie_test::test_ruby!(r#"
645
+ /// module_ = Wasmer::Module.new Wasmer::Store.new, "(module)"
646
+ /// assert { module_.serialize.is_a?(String) }
647
+ /// # "#); }
648
+ /// ```
649
+ pub fn serialize(&self) -> String {
650
+ x!()
651
+ }
652
+
653
+ /// Deserializes a serialized module binary into a Module.
654
+ ///
655
+ /// **Note**: the module has to be serialized before with the
656
+ /// serialize method.
657
+ ///
658
+ /// # Safety
659
+ ///
660
+ /// This function is inherently unsafe as the provided bytes:
661
+ ///
662
+ /// 1. Are going to be deserialized directly into Rust objects.
663
+ /// 2. Contains the function assembly bodies and, if
664
+ /// intercepted, a malicious actor could inject code into
665
+ /// executable memory.
666
+ ///
667
+ /// And as such, the deserialize method is unsafe.
668
+ ///
669
+ /// # Example
670
+ ///
671
+ /// ```rust
672
+ /// # fn main() { rutie_test::test_ruby!(r#"
673
+ /// store = Wasmer::Store.new
674
+ ///
675
+ /// serialized_module = Wasmer::Module.new(
676
+ /// store,
677
+ /// (<<~WAST)
678
+ /// (module
679
+ /// (func (export "function") (param i32 i64)))
680
+ /// WAST
681
+ /// ).serialize
682
+ ///
683
+ /// module_ = Wasmer::Module.deserialize store, serialized_module
684
+ /// serialized_module = nil
685
+ ///
686
+ /// exports = module_.exports
687
+ ///
688
+ /// assert { exports.length() == 1 }
689
+ /// assert { exports[0].name == "function" }
690
+ /// assert { exports[0].type.is_a?(Wasmer::FunctionType) }
691
+ /// assert { exports[0].type.params == [Wasmer::Type::I32, Wasmer::Type::I64] }
692
+ /// assert { exports[0].type.results == [] }
693
+ /// # "#); }
694
+ /// ```
695
+ pub fn deserialize(bytes: String) -> Self {
696
+ x!()
697
+ }
698
+ }
699
+
700
+ /// A WebAssembly instance is a stateful, executable instance of a
701
+ /// WebAssembly [`Module`].
702
+ ///
703
+ /// Instance objects contain all the exported WebAssembly
704
+ /// functions, memories, tables and globals that allow interacting
705
+ /// with WebAssembly.
706
+ ///
707
+ /// Specification:
708
+ /// <https://webassembly.github.io/spec/core/exec/runtime.html#module-instances>
709
+ ///
710
+ /// # Examples
711
+ ///
712
+ /// Example without an import object. The following creates a
713
+ /// module with a sum exported function that sum two integers.
714
+ ///
715
+ /// ```rust
716
+ /// # fn main() { rutie_test::test_ruby!(r#"
717
+ /// module_ = Wasmer::Module.new(
718
+ /// Wasmer::Store.new,
719
+ /// (<<~WAST)
720
+ /// (module
721
+ /// (type (func (param i32 i32) (result i32)))
722
+ /// (func (type 0)
723
+ /// local.get 0
724
+ /// local.get 1
725
+ /// i32.add)
726
+ /// (export "sum" (func 0)))
727
+ /// WAST
728
+ /// )
729
+ /// instance = Wasmer::Instance.new module_, nil
730
+ ///
731
+ /// assert { instance.exports.sum.(1, 2) == 3 }
732
+ /// # "#); }
733
+ /// ```
734
+ ///
735
+ /// Example with an import object. The following creates a module
736
+ /// that (i) imports a sum function from the `math` namespace, and
737
+ /// (ii) exports an `add_one` function that adds 1 to any given
738
+ /// integer (by using the `math.sum` function).
739
+ ///
740
+ /// ```rust
741
+ /// # fn main() { rutie_test::test_ruby!(r#"
742
+ /// def sum(x, y)
743
+ /// x + y
744
+ /// end
745
+ ///
746
+ /// store = Wasmer::Store.new
747
+ /// module_ = Wasmer::Module.new(
748
+ /// store,
749
+ /// (<<~WAST)
750
+ /// (module
751
+ /// (import "math" "sum" (func $sum (param i32 i32) (result i32)))
752
+ /// (func (export "add_one") (param i32) (result i32)
753
+ /// local.get 0
754
+ /// i32.const 1
755
+ /// call $sum))
756
+ /// WAST
757
+ /// )
758
+ ///
759
+ /// import_object = Wasmer::ImportObject.new
760
+ /// import_object.register(
761
+ /// "math",
762
+ /// {
763
+ /// :sum => Wasmer::Function.new(
764
+ /// store,
765
+ /// method(:sum),
766
+ /// Wasmer::FunctionType.new([Wasmer::Type::I32, Wasmer::Type::I32], [Wasmer::Type::I32])
767
+ /// )
768
+ /// }
769
+ /// )
770
+ ///
771
+ /// instance = Wasmer::Instance.new module_, import_object
772
+ ///
773
+ /// assert { instance.exports.add_one.(1) == 2 }
774
+ /// # "#); }
775
+ /// ```
776
+ pub struct Instance;
777
+
778
+ impl Instance {
779
+ /// Creates a new `Instance`.
780
+ pub fn new(module: Module, import_object: ImportObject) -> Self {
781
+ x!()
782
+ }
783
+
784
+ /// Returns all the exported entities.
785
+ pub fn exports(&self) -> Exports {
786
+ x!()
787
+ }
788
+ }
789
+
790
+ /// Represents all the exports of an instance. It is built by [`Instance::exports`].
791
+ ///
792
+ /// Exports can be of kind [`Function`], [`Global`], [`Table`], or [`Memory`].
793
+ pub struct Exports;
794
+
795
+ impl Exports {
796
+ /// Returns the number of exports.
797
+ pub fn length(&self) -> Integer {
798
+ x!()
799
+ }
800
+
801
+ /// Returns either a [`Function`], a [`Memory`], a [`Global`],
802
+ /// or a [`Table`] if the name for the export exists.
803
+ ///
804
+ /// # Example
805
+ ///
806
+ /// ```rust
807
+ /// # fn main() { rutie_test::test_ruby!(r#"
808
+ /// module_ = Wasmer::Module.new(
809
+ /// Wasmer::Store.new,
810
+ /// (<<~WAST)
811
+ /// (module
812
+ /// (func (export "func") (param i32 i64))
813
+ /// (global (export "glob") i32 (i32.const 7))
814
+ /// (table (export "tab") 0 funcref)
815
+ /// (memory (export "mem") 1))
816
+ /// WAST
817
+ /// )
818
+ /// instance = Wasmer::Instance.new module_, nil
819
+ /// exports = instance.exports
820
+ ///
821
+ /// assert { exports.respond_to? :func }
822
+ /// assert { exports.respond_to? :glob }
823
+ /// assert { exports.respond_to? :tab }
824
+ /// assert { exports.respond_to? :mem }
825
+ /// assert { not(exports.respond_to? :foo) }
826
+ ///
827
+ /// assert { exports.func.is_a?(Wasmer::Function) }
828
+ /// assert { exports.mem.is_a?(Wasmer::Memory) }
829
+ /// assert { exports.glob.is_a?(Wasmer::Global) }
830
+ /// assert { exports.tab.is_a?(Wasmer::Table) }
831
+ /// # "#); }
832
+ /// ```
833
+ pub fn method_missing(name: String) -> Any {
834
+ x!()
835
+ }
836
+ }
837
+
838
+ /// An `ImportObject` represents all of the import data used when
839
+ /// instantiating a WebAssembly module.
840
+ ///
841
+ /// # Example
842
+ ///
843
+ /// Importing a function, `math.sum`, and call it through the
844
+ /// exported `add_one` function:
845
+ ///
846
+ /// ```rust
847
+ /// # fn main() { rutie_test::test_ruby!(r#"
848
+ /// def sum(x, y)
849
+ /// x + y
850
+ /// end
851
+ ///
852
+ /// store = Wasmer::Store.new
853
+ /// module_ = Wasmer::Module.new(
854
+ /// store,
855
+ /// (<<~WAST)
856
+ /// (module
857
+ /// (import "math" "sum" (func $sum (param i32 i32) (result i32)))
858
+ /// (func (export "add_one") (param i32) (result i32)
859
+ /// local.get 0
860
+ /// i32.const 1
861
+ /// call $sum))
862
+ /// WAST
863
+ /// )
864
+ ///
865
+ /// import_object = Wasmer::ImportObject.new
866
+ /// import_object.register(
867
+ /// "math",
868
+ /// {
869
+ /// :sum => Wasmer::Function.new(
870
+ /// store,
871
+ /// method(:sum),
872
+ /// Wasmer::FunctionType.new([Wasmer::Type::I32, Wasmer::Type::I32], [Wasmer::Type::I32])
873
+ /// )
874
+ /// }
875
+ /// )
876
+ ///
877
+ /// instance = Wasmer::Instance.new module_, import_object
878
+ ///
879
+ /// assert { instance.exports.add_one.(1) == 2 }
880
+ /// # "#); }
881
+ /// ```
882
+ ///
883
+ /// Importing a memory:
884
+ ///
885
+ /// ```rust
886
+ /// # fn main() { rutie_test::test_ruby!(r#"
887
+ /// store = Wasmer::Store.new
888
+ /// module_ = Wasmer::Module.new(
889
+ /// store,
890
+ /// (<<~WAST)
891
+ /// (module
892
+ /// (import "env" "memory" (memory $memory 1))
893
+ /// (func (export "increment")
894
+ /// i32.const 0
895
+ /// i32.const 0
896
+ /// i32.load ;; load 0
897
+ /// i32.const 1
898
+ /// i32.add ;; add 1
899
+ /// i32.store ;; store at 0
900
+ /// ))
901
+ /// WAST
902
+ /// )
903
+ ///
904
+ /// memory = Wasmer::Memory.new store, Wasmer::MemoryType.new(1, nil, false)
905
+ /// view = memory.uint8_view(0)
906
+ ///
907
+ /// import_object = Wasmer::ImportObject.new
908
+ /// import_object.register(
909
+ /// "env",
910
+ /// {
911
+ /// :memory => memory,
912
+ /// }
913
+ /// )
914
+ ///
915
+ /// instance = Wasmer::Instance.new module_, import_object
916
+ ///
917
+ /// assert { view[0] == 0 }
918
+ ///
919
+ /// instance.exports.increment.()
920
+ /// assert { view[0] == 1 }
921
+ ///
922
+ /// instance.exports.increment.()
923
+ /// assert { view[0] == 2 }
924
+ /// # "#); }
925
+ /// ```
926
+ ///
927
+ /// Importing a global:
928
+ ///
929
+ /// ```rust
930
+ /// # fn main() { rutie_test::test_ruby!(r#"
931
+ /// store = Wasmer::Store.new
932
+ /// module_ = Wasmer::Module.new(
933
+ /// store,
934
+ /// (<<~WAST)
935
+ /// (module
936
+ /// (import "env" "global" (global $global (mut i32)))
937
+ /// (func (export "read_g") (result i32)
938
+ /// global.get $global)
939
+ /// (func (export "write_g") (param i32)
940
+ /// local.get 0
941
+ /// global.set $global))
942
+ /// WAST
943
+ /// )
944
+ ///
945
+ /// global = Wasmer::Global.new store, Wasmer::Value.i32(7), true
946
+ ///
947
+ /// import_object = Wasmer::ImportObject.new
948
+ /// import_object.register(
949
+ /// "env",
950
+ /// {
951
+ /// :global => global
952
+ /// }
953
+ /// )
954
+ ///
955
+ /// instance = Wasmer::Instance.new module_, import_object
956
+ ///
957
+ /// assert { instance.exports.read_g.() == 7 }
958
+ ///
959
+ /// global.value = 153
960
+ /// assert { instance.exports.read_g.() == 153 }
961
+ ///
962
+ /// instance.exports.write_g.(11)
963
+ /// assert { global.value == 11 }
964
+ /// # "#); }
965
+ /// ```
966
+ ///
967
+ /// etc.
968
+ pub struct ImportObject;
969
+
970
+ impl ImportObject {
971
+ /// Creates a new `ImportObject`.
972
+ pub fn new() -> Self {
973
+ x!()
974
+ }
975
+
976
+ /// Checks whether the import object contains a specific
977
+ /// namespace.
978
+ pub fn contains_namespace(&self, namespace_name: String) -> Boolean {
979
+ x!()
980
+ }
981
+
982
+ /// Registers a set of [`Function`], [`Memory`], [`Global`] or
983
+ /// [`Table`] to a particular namespace.
984
+ ///
985
+ /// See the [`ImportObject`]'s documentation to see more
986
+ /// examples.
987
+ pub fn register(&self, namespace_name: String, namespace: Hash<String, Any>) {
988
+ x!()
989
+ }
990
+ }
991
+
992
+ /// Represents a WebAssembly function instance.
993
+ ///
994
+ /// A function instance is the runtime representation of a
995
+ /// function. It effectively is a closure of the original function
996
+ /// (defined in either the host or the WebAssembly module) over
997
+ /// the runtime [`Instance`] of its originating [`Module`].
998
+ ///
999
+ /// The module instance is used to resolve references to other
1000
+ /// definitions during executing of the function.
1001
+ ///
1002
+ /// Specification:
1003
+ /// <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
1004
+ ///
1005
+ /// Note that the function can be invoked/called by the host only
1006
+ /// when it is an exported function (see [`Exports`] to see an
1007
+ /// example).
1008
+ ///
1009
+ /// # Example
1010
+ ///
1011
+ /// To build a `Function`, we need its type. `Function`
1012
+ /// understands `Symbol`, `Proc`, and `Lambda`.
1013
+ ///
1014
+ /// First, a function through a symbol:
1015
+ ///
1016
+ /// ```rust
1017
+ /// # fn main() { rutie_test::test_ruby!(r#"
1018
+ /// def foo(x)
1019
+ /// x + 1
1020
+ /// end
1021
+ ///
1022
+ /// function = Wasmer::Function.new(
1023
+ /// Wasmer::Store.new,
1024
+ /// ## A symbol.
1025
+ /// method(:foo),
1026
+ /// Wasmer::FunctionType.new([Wasmer::Type::I32], [])
1027
+ /// )
1028
+ /// # "#); }
1029
+ /// ```
1030
+ ///
1031
+ /// Second, a function through a proc as a lambda:
1032
+ ///
1033
+ /// ```rust
1034
+ /// # fn main() { rutie_test::test_ruby!(r#"
1035
+ /// function = Wasmer::Function.new(
1036
+ /// Wasmer::Store.new,
1037
+ /// ## A lambda.
1038
+ /// -> (x) { x + 1 },
1039
+ /// Wasmer::FunctionType.new([Wasmer::Type::I32], [])
1040
+ /// )
1041
+ /// # "#); }
1042
+ /// ```
1043
+ ///
1044
+ /// Third, a function through a proc:
1045
+ ///
1046
+ /// ```rust
1047
+ /// # fn main() { rutie_test::test_ruby!(r#"
1048
+ /// function = Wasmer::Function.new(
1049
+ /// Wasmer::Store.new,
1050
+ /// ## A proc.
1051
+ /// Proc.new { |x| x + 1 },
1052
+ /// Wasmer::FunctionType.new([Wasmer::Type::I32], [])
1053
+ /// )
1054
+ /// # "#); }
1055
+ /// ```
1056
+ pub struct Function;
1057
+
1058
+ impl Function {
1059
+ /// Creates a new `Function`. The `function` can be of kind
1060
+ /// `Symbol`, `Proc` or `Lambda`.
1061
+ pub fn new(store: Store, function: Any, function_type: FunctionType) -> Self {
1062
+ x!()
1063
+ }
1064
+
1065
+ /// Calls the function with arguments. It returns zero or more results.
1066
+ pub fn call(x0: Any, x1: Any, x2: Any, etc: Any) -> Any {
1067
+ x!()
1068
+ }
1069
+
1070
+ /// Returns the function type.
1071
+ pub fn r#type(&self) -> FunctionType {
1072
+ x!()
1073
+ }
1074
+ }
1075
+
1076
+ /// A WebAssembly memory instance.
1077
+ ///
1078
+ /// A memory instance is the runtime representation of a linear
1079
+ /// memory. It consists of a vector of bytes and an optional
1080
+ /// maximum size.
1081
+ ///
1082
+ /// The length of the vector always is a multiple of the
1083
+ /// WebAssembly page size, which is defined to be the constant
1084
+ /// 65536 – abbreviated 64Ki. Like in a memory type, the maximum
1085
+ /// size in a memory instance is given in units of this page size.
1086
+ ///
1087
+ /// A memory created by the host or in WebAssembly code will be
1088
+ /// accessible and mutable from both host and WebAssembly.
1089
+ ///
1090
+ /// Specification: <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
1091
+ ///
1092
+ /// # Example
1093
+ ///
1094
+ /// Creates a [`Memory`] from scratch:
1095
+ ///
1096
+ /// ```rust
1097
+ /// # fn main() { rutie_test::test_ruby!(r#"
1098
+ /// store = Wasmer::Store.new
1099
+ /// memory_type = Wasmer::MemoryType.new 3, 10, true
1100
+ /// memory = Wasmer::Memory.new store, memory_type
1101
+ ///
1102
+ /// assert { memory.size == 3 }
1103
+ /// # "#); }
1104
+ /// ```
1105
+ ///
1106
+ /// Gets a memory from the exports of an instance:
1107
+ ///
1108
+ /// ```rust,ignore
1109
+ /// # fn main() { rutie_test::test_ruby!(r#"
1110
+ /// module_ = Wasmer::Module.new Wasmer::Store.new, wasm_bytes
1111
+ /// instance = Wasmer::Instance.new module, nil
1112
+ ///
1113
+ /// memory = instance.exports.memory
1114
+ /// # "#); }
1115
+ /// ```
1116
+ pub struct Memory;
1117
+
1118
+ impl Memory {
1119
+ /// Creates a new `Memory`.
1120
+ pub fn new(store: Store, memory_type: MemoryType) -> Self {
1121
+ x!()
1122
+ }
1123
+
1124
+ /// Returns the memory type.
1125
+ pub fn r#type(&self) -> MemoryType {
1126
+ x!()
1127
+ }
1128
+
1129
+ /// Returns the size (in pages) of the memory.
1130
+ pub fn size(&self) -> Integer {
1131
+ x!()
1132
+ }
1133
+
1134
+ /// Returns the size (in bytes) of the memory.
1135
+ pub fn data_size(&self) -> Integer {
1136
+ x!()
1137
+ }
1138
+
1139
+ /// Grows memory by the specified amount of WebAssembly pages.
1140
+ ///
1141
+ /// # Example
1142
+ ///
1143
+ /// ```rust,ignore
1144
+ /// # fn main() { rutie_test::test_ruby!(r#"
1145
+ /// memory = instance.exports.memory
1146
+ /// old_memory_size = memory.data_size
1147
+ ///
1148
+ /// memory.grow 1
1149
+ ///
1150
+ /// memory_size = memory.data_size
1151
+ ///
1152
+ /// assert { memory_size == 1179648 }
1153
+ /// assert { memory_size - old_memory_size == 65536 }
1154
+ /// # "#); }
1155
+ /// ```
1156
+ pub fn grow(&self, number_of_pages: Integer) -> Integer {
1157
+ x!()
1158
+ }
1159
+
1160
+ /// Creates a read-and-write view over the memory data where
1161
+ /// elements are of kind `uint8`.
1162
+ pub fn uint8_view(&self) -> Uint8View {
1163
+ x!()
1164
+ }
1165
+
1166
+ /// Creates a read-and-write view over the memory data where
1167
+ /// elements are of kind `int8`.
1168
+ pub fn int8_view(&self) -> Int8View {
1169
+ x!()
1170
+ }
1171
+
1172
+ /// Creates a read-and-write view over the memory data where
1173
+ /// elements are of kind `uint16`.
1174
+ pub fn uint16_view(&self) -> Uint16View {
1175
+ x!()
1176
+ }
1177
+
1178
+ /// Creates a read-and-write view over the memory data where
1179
+ /// elements are of kind `int16`.
1180
+ pub fn int16_view(&self) -> Int16View {
1181
+ x!()
1182
+ }
1183
+
1184
+ /// Creates a read-and-write view over the memory data where
1185
+ /// elements are of kind `uint32`.
1186
+ pub fn uint32_view(&self) -> Uint32View {
1187
+ x!()
1188
+ }
1189
+
1190
+ /// Creates a read-and-write view over the memory data where
1191
+ /// elements are of kind `int32`.
1192
+ pub fn int32_view(&self) -> Int32View {
1193
+ x!()
1194
+ }
1195
+ }
1196
+
1197
+ pub struct Uint8View;
1198
+ pub struct Int8View;
1199
+ pub struct Uint16View;
1200
+ pub struct Int16View;
1201
+ pub struct Uint32View;
1202
+ pub struct Int32View;
1203
+
1204
+ /// Represents a WebAssembly global instance.
1205
+ ///
1206
+ /// A global instance is the runtime representation of a global
1207
+ /// variable. It consists of an individual value and a flag
1208
+ /// indicating whether it is mutable.
1209
+ ///
1210
+ /// Specification: <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
1211
+ ///
1212
+ /// # Example
1213
+ ///
1214
+ /// ```rust
1215
+ /// # fn main() { rutie_test::test_ruby!(r#"
1216
+ /// store = Wasmer::Store.new
1217
+ /// global = Wasmer::Global.new store, Wasmer::Value.i32(42), false
1218
+ ///
1219
+ /// assert { global.value == 42 }
1220
+ ///
1221
+ /// type = global.type
1222
+ ///
1223
+ /// assert { type.type == Wasmer::Type::I32 }
1224
+ /// assert { type.mutable? == false }
1225
+ /// # "#); }
1226
+ /// ```
1227
+ pub struct Global;
1228
+
1229
+ impl Global {
1230
+ /// Creates a new `Global`.
1231
+ pub fn new(store: Store, value: Value, mutable: Boolean) -> Self {
1232
+ x!()
1233
+ }
1234
+
1235
+ /// Returns whether the global is muable.
1236
+ pub fn mutable(&self) -> Boolean {
1237
+ x!()
1238
+ }
1239
+
1240
+ /// Get or set a new value to the global if mutable.
1241
+ ///
1242
+ /// # Example
1243
+ ///
1244
+ /// ```rust
1245
+ /// # fn main() { rutie_test::test_ruby!(r#"
1246
+ /// store = Wasmer::Store.new
1247
+ /// global = Wasmer::Global.new store, Wasmer::Value.i32(42), true
1248
+ ///
1249
+ /// assert { global.value == 42 }
1250
+ ///
1251
+ /// type = global.type
1252
+ ///
1253
+ /// assert { type.type == Wasmer::Type::I32 }
1254
+ /// assert { type.mutable? == true }
1255
+ ///
1256
+ /// global.value = 153
1257
+ ///
1258
+ /// assert { global.value == 153 }
1259
+ /// # "#); }
1260
+ /// ```
1261
+ pub fn value(&self, value: Any) -> Any {
1262
+ x!()
1263
+ }
1264
+
1265
+ /// Returns the global type.
1266
+ pub fn r#type(&self) -> GlobalType {
1267
+ x!()
1268
+ }
1269
+ }
1270
+
1271
+ /// A WebAssembly table instance.
1272
+ ///
1273
+ /// The Table class is an array-like structure representing a
1274
+ /// WebAssembly table, which stores function references.
1275
+ ///
1276
+ /// A table created by the host or in WebAssembly code will be
1277
+ /// accessible and mutable from both host and WebAssembly.
1278
+ ///
1279
+ /// Specification: <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
1280
+ pub struct Table;
1281
+
1282
+ impl Table {
1283
+ /// Creates a new `Table`.
1284
+ pub fn new(store: Store, table_type: TableType, initia_value: Value) -> Self {
1285
+ x!()
1286
+ }
1287
+ }
1288
+
1289
+ /// Represents a WebAssembly value of a specific type.
1290
+ ///
1291
+ /// Most of the time, the types for WebAssembly values will be
1292
+ /// inferred. When it's not possible, the `Value` class is
1293
+ /// necessary.
1294
+ pub struct Value;
1295
+
1296
+ impl Value {
1297
+ /// Creates a new `Value` containing a `int32`.
1298
+ ///
1299
+ /// # Example
1300
+ ///
1301
+ /// ```rust
1302
+ /// # fn main() { rutie_test::test_ruby!(r#"
1303
+ /// Wasmer::Value.i32(7)
1304
+ /// # "#); }
1305
+ /// ```
1306
+ pub fn i32(value: Integer) -> Self {
1307
+ x!()
1308
+ }
1309
+
1310
+ /// Creates a new `Value` containing a `int64`.
1311
+ ///
1312
+ /// # Example
1313
+ ///
1314
+ /// ```rust
1315
+ /// # fn main() { rutie_test::test_ruby!(r#"
1316
+ /// Wasmer::Value.i64(7)
1317
+ /// # "#); }
1318
+ /// ```
1319
+ pub fn i64(value: Integer) -> Self {
1320
+ x!()
1321
+ }
1322
+
1323
+ /// Creates a new `Value` containing a `float32`.
1324
+ ///
1325
+ /// # Example
1326
+ ///
1327
+ /// ```rust
1328
+ /// # fn main() { rutie_test::test_ruby!(r#"
1329
+ /// Wasmer::Value.f32(4.2)
1330
+ /// # "#); }
1331
+ /// ```
1332
+ pub fn f32(value: Float) -> Self {
1333
+ x!()
1334
+ }
1335
+
1336
+ /// Creates a new `Value` containing a `float64`.
1337
+ ///
1338
+ /// # Example
1339
+ ///
1340
+ /// ```rust
1341
+ /// # fn main() { rutie_test::test_ruby!(r#"
1342
+ /// Wasmer::Value.f64(4.2)
1343
+ /// # "#); }
1344
+ /// ```
1345
+ pub fn f64(value: Float) -> Self {
1346
+ x!()
1347
+ }
1348
+ }
1349
+
1350
+ /// Wasmer's [WASI] implementation.
1351
+ ///
1352
+ /// From the user perspective, WASI is a bunch of imports. To
1353
+ /// generate the appropriated imports, you can use
1354
+ /// [`StateBuilder`](Wasi::StateBuilder) to build an
1355
+ /// [`Environment`](Wasi::Environment). This environment holds the
1356
+ /// WASI memory, and can be used to generate a valid
1357
+ /// [`ImportObject`]. This last one can be passed to [`Instance`]
1358
+ /// to instantiate a [`Module`] that needs WASI support.
1359
+ ///
1360
+ /// [WASI]: https://github.com/WebAssembly/WASI
1361
+ ///
1362
+ /// # Example
1363
+ ///
1364
+ /// ```rust,ignore
1365
+ /// # fn main() { rutie_test::test_ruby!(r#"
1366
+ /// store = Wasmer::Store.new
1367
+ /// module_ = Wasmer::Module.new store, bytes
1368
+ ///
1369
+ /// ## Get the WASI version.
1370
+ /// wasi_version = Wasmer::Wasi::get_version module_, true
1371
+ ///
1372
+ /// ## Build a WASI environment for the imports.
1373
+ /// wasi_env = Wasmer::Wasi::StateBuilder.new("test-program")
1374
+ /// .argument("--foo")
1375
+ /// .environments({"ABC" => "DEF", "X" => "YZ"})
1376
+ /// .map_directory("the_host_directory", ".")
1377
+ /// .finalize
1378
+ ///
1379
+ /// ## Generate an `ImportObject` for the WASI environment.
1380
+ /// import_object = wasi_env.generate_import_object store, wasi_version
1381
+ ///
1382
+ /// ## Now we are ready to instantiate the module.
1383
+ /// instance = Wasmer::Instance.new module_, import_object
1384
+ ///
1385
+ /// # Here we go, let's start the program.
1386
+ /// instance.exports._start.()
1387
+ /// # "#); }
1388
+ /// ```
1389
+ pub mod Wasi {
1390
+ use super::*;
1391
+ use crate::doc::Ruby::*;
1392
+
1393
+ /// Represents a WASI version.
1394
+ #[allow(non_camel_case_types)]
1395
+ pub enum Version {
1396
+ LATEST_VERSION,
1397
+ SNAPSHOT0,
1398
+ SNAPSHOT1,
1399
+ }
1400
+
1401
+ /// Convenient builder API for configuring WASI.
1402
+ ///
1403
+ /// Use the constructor to pass the arguments, environments,
1404
+ /// preopen directories and map directories, or use the
1405
+ /// associated methods to build the state step-by-steps.
1406
+ pub struct StateBuilder;
1407
+
1408
+ impl StateBuilder {
1409
+ pub fn new(program_name: String) -> Self {
1410
+ x!()
1411
+ }
1412
+
1413
+ /// Adds an argument.
1414
+ ///
1415
+ /// Arguments must not contain the nul (`0x0`) byte.
1416
+ pub fn argument(&mut self, argument: String) -> Self {
1417
+ x!()
1418
+ }
1419
+
1420
+ /// Adds multiple arguments.
1421
+ ///
1422
+ /// Arguments must not contain the nul (`0x0`) byte.
1423
+ pub fn arguments(&mut self, arguments: Array<String>) -> Self {
1424
+ x!()
1425
+ }
1426
+
1427
+ /// Add an environment variable pair.
1428
+ ///
1429
+ /// Environment variable keys and values must not contain
1430
+ /// the byte `=` (`0x3d`) or null (`0x0`).
1431
+ pub fn environment(&mut self, key: String, value: String) -> Self {
1432
+ x!()
1433
+ }
1434
+
1435
+ /// Add environment variable pairs.
1436
+ ///
1437
+ /// Environment variable keys and values must not contain
1438
+ /// the byte `=` (`0x3d`) or null (`0x0`).
1439
+ pub fn environments(&mut self, pairs: Hash<String, String>) -> Self {
1440
+ x!()
1441
+ }
1442
+
1443
+ /// Preopen a directory with a different name exposed to the WASI.
1444
+ ///
1445
+ /// This opens the given directories at the virtual root,
1446
+ /// `/`, and allows the WASI module to read and write to the
1447
+ /// given directories.
1448
+ pub fn preopen_directory(&mut self, alias: String, value: String) -> Self {
1449
+ x!()
1450
+ }
1451
+
1452
+ /// Preopen directories with a different name exposed to the WASI.
1453
+ ///
1454
+ /// This opens the given directories at the virtual root,
1455
+ /// `/`, and allows the WASI module to read and write to the
1456
+ /// given directories.
1457
+ pub fn preopen_directories(&mut self, pairs: Hash<String, String>) -> Self {
1458
+ x!()
1459
+ }
1460
+
1461
+ /// Preopen a directory with a different name exposed to the WASI.
1462
+ pub fn map_directory(&mut self, alias: String, value: String) -> Self {
1463
+ x!()
1464
+ }
1465
+
1466
+ /// Preopen directories with a different name exposed to the WASI.
1467
+ pub fn map_directories(&mut self, pairs: Hash<String, String>) -> Self {
1468
+ x!()
1469
+ }
1470
+
1471
+ /// Produces a WASI [`Environment`] based on this state builder.
1472
+ pub fn finalize(&mut self) -> Environment {
1473
+ x!()
1474
+ }
1475
+ }
1476
+
1477
+ /// The environment provided to the WASI imports.
1478
+ ///
1479
+ /// To build it, use [`StateBuilder`]. See
1480
+ /// [`StateBuilder::finalize`] to learn more.
1481
+ pub struct Environment;
1482
+
1483
+ impl Environment {
1484
+ /// Create an [`ImportObject`] with an existing
1485
+ /// [`Environment`]. The import object will be different
1486
+ /// according to the WASI version.
1487
+ ///
1488
+ /// Use the [`Version`] enum to use a specific WASI
1489
+ /// version, or use [`get_version`] to read the WASI
1490
+ /// version from a [`Module`].
1491
+ pub fn generate_import_object(
1492
+ &self,
1493
+ store: Store,
1494
+ wasi_version: Version,
1495
+ ) -> ImportObject {
1496
+ x!()
1497
+ }
1498
+ }
1499
+
1500
+ /// Detect the version of WASI being used based on the import
1501
+ /// namespaces.
1502
+ ///
1503
+ /// A strict detection expects that all imports live in a
1504
+ /// single WASI namespace. A non-strict detection expects that
1505
+ /// at least one WASI namespace exits to detect the
1506
+ /// version. Note that the strict detection is faster than the
1507
+ /// non-strict one.
1508
+ pub fn get_version(module: Module, strict: Boolean) -> Version {
1509
+ x!()
1510
+ }
1511
+ }
1512
+ }