wasmer 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/documentation.yml +50 -0
  3. data/.github/workflows/test.yml +34 -61
  4. data/CHANGELOG.md +89 -29
  5. data/Cargo.lock +812 -380
  6. data/Cargo.toml +7 -20
  7. data/Gemfile +2 -3
  8. data/README.md +1 -0
  9. data/Rakefile +4 -3
  10. data/crates/rutie-derive-macros/Cargo.toml +19 -0
  11. data/crates/rutie-derive-macros/README.md +4 -0
  12. data/crates/rutie-derive-macros/src/class.rs +156 -0
  13. data/crates/rutie-derive-macros/src/function.rs +178 -0
  14. data/crates/rutie-derive-macros/src/lib.rs +27 -0
  15. data/crates/rutie-derive-macros/src/methods.rs +282 -0
  16. data/crates/rutie-derive/Cargo.toml +14 -0
  17. data/crates/rutie-derive/README.md +97 -0
  18. data/crates/rutie-derive/src/lib.rs +4 -0
  19. data/crates/rutie-derive/src/upcast.rs +47 -0
  20. data/crates/rutie-test/Cargo.toml +10 -0
  21. data/crates/rutie-test/src/lib.rs +38 -0
  22. data/crates/wasmer/Cargo.toml +27 -0
  23. data/crates/wasmer/README.md +228 -0
  24. data/crates/wasmer/src/doc.rs +1512 -0
  25. data/crates/wasmer/src/error.rs +55 -0
  26. data/crates/wasmer/src/exports.rs +107 -0
  27. data/crates/wasmer/src/externals/function.rs +159 -0
  28. data/crates/wasmer/src/externals/global.rs +62 -0
  29. data/crates/wasmer/src/externals/memory.rs +117 -0
  30. data/crates/wasmer/src/externals/mod.rs +9 -0
  31. data/crates/wasmer/src/externals/table.rs +41 -0
  32. data/crates/wasmer/src/import_object.rs +78 -0
  33. data/crates/wasmer/src/instance.rs +45 -0
  34. data/crates/wasmer/src/lib.rs +307 -0
  35. data/crates/wasmer/src/memory/mod.rs +1 -0
  36. data/crates/wasmer/src/memory/views.rs +112 -0
  37. data/crates/wasmer/src/module.rs +106 -0
  38. data/crates/wasmer/src/prelude.rs +3 -0
  39. data/crates/wasmer/src/store.rs +22 -0
  40. data/crates/wasmer/src/types.rs +390 -0
  41. data/crates/wasmer/src/values.rs +84 -0
  42. data/crates/wasmer/src/wasi.rs +226 -0
  43. data/crates/wasmer/src/wat.rs +20 -0
  44. data/justfile +7 -1
  45. data/lib/wasmer.rb +29 -3
  46. data/wasmer.gemspec +6 -10
  47. metadata +45 -47
  48. data/README.md +0 -332
  49. data/lib/wasmer/version.rb +0 -3
  50. data/src/error.rs +0 -16
  51. data/src/instance/exports.rs +0 -215
  52. data/src/instance/globals.rs +0 -234
  53. data/src/instance/mod.rs +0 -141
  54. data/src/lib.rs +0 -162
  55. data/src/memory/mod.rs +0 -158
  56. data/src/memory/view.rs +0 -145
  57. data/src/module.rs +0 -28
@@ -0,0 +1,9 @@
1
+ pub mod function;
2
+ pub mod global;
3
+ pub mod memory;
4
+ pub mod table;
5
+
6
+ pub use function::Function;
7
+ pub use global::Global;
8
+ pub use memory::Memory;
9
+ pub use table::Table;
@@ -0,0 +1,41 @@
1
+ use crate::{
2
+ error::{to_ruby_err, RuntimeError},
3
+ prelude::*,
4
+ store::Store,
5
+ types::TableType,
6
+ values::Value,
7
+ };
8
+ use rutie::AnyObject;
9
+
10
+ #[rubyclass(module = "Wasmer")]
11
+ pub struct Table {
12
+ inner: wasmer::Table,
13
+ }
14
+
15
+ impl Table {
16
+ pub fn raw_new(inner: wasmer::Table) -> Self {
17
+ Self { inner }
18
+ }
19
+
20
+ pub(crate) fn inner(&self) -> &wasmer::Table {
21
+ &self.inner
22
+ }
23
+ }
24
+
25
+ #[rubymethods]
26
+ impl Table {
27
+ pub fn new(
28
+ store: &Store,
29
+ table_type: &TableType,
30
+ initial_value: &Value,
31
+ ) -> RubyResult<AnyObject> {
32
+ Ok(Table::ruby_new(Table::raw_new(
33
+ wasmer::Table::new(
34
+ store.inner(),
35
+ table_type.into(),
36
+ initial_value.inner().clone(),
37
+ )
38
+ .map_err(to_ruby_err::<RuntimeError, _>)?,
39
+ )))
40
+ }
41
+ }
@@ -0,0 +1,78 @@
1
+ use crate::{
2
+ error::{to_ruby_err, unwrap_or_raise, TypeError},
3
+ externals::{function::RubyFunction, global::RubyGlobal, memory::RubyMemory, table::RubyTable},
4
+ prelude::*,
5
+ };
6
+ use rutie::{AnyObject, Boolean, Hash, NilClass, Object, RString, Symbol};
7
+
8
+ #[rubyclass(module = "Wasmer")]
9
+ pub struct ImportObject {
10
+ inner: wasmer::ImportObject,
11
+ }
12
+
13
+ impl ImportObject {
14
+ pub(crate) fn raw_new(inner: wasmer::ImportObject) -> Self {
15
+ Self { inner }
16
+ }
17
+
18
+ pub(crate) fn inner(&self) -> &wasmer::ImportObject {
19
+ &self.inner
20
+ }
21
+ }
22
+
23
+ #[rubymethods]
24
+ impl ImportObject {
25
+ pub fn new() -> RubyResult<AnyObject> {
26
+ Ok(ImportObject::ruby_new(ImportObject {
27
+ inner: Default::default(),
28
+ }))
29
+ }
30
+
31
+ pub fn contains_namespace(&self, namespace_name: &RString) -> RubyResult<Boolean> {
32
+ Ok(Boolean::new(
33
+ self.inner().contains_namespace(namespace_name.to_str()),
34
+ ))
35
+ }
36
+
37
+ pub fn register(&mut self, namespace_name: &RString, namespace: &Hash) -> RubyResult<NilClass> {
38
+ let mut wasmer_namespace = wasmer::Exports::new();
39
+
40
+ namespace.each(|key, value| {
41
+ unwrap_or_raise(|| {
42
+ let name = if let Ok(name) = key.try_convert_to::<RString>() {
43
+ name.to_string()
44
+ } else if let Ok(name) = key.try_convert_to::<Symbol>() {
45
+ name.to_string()
46
+ } else {
47
+ return Err(to_ruby_err::<TypeError, _>(format!(
48
+ "`ImportObject` cannot register the name because it has an invalid type `{:?}` (expects `String` or `Symbol`)",
49
+ key.ty()
50
+ )));
51
+ };
52
+
53
+ if let Ok(function) = value.try_convert_to::<RubyFunction>() {
54
+ wasmer_namespace.insert(name, function.upcast().inner().clone());
55
+ } else if let Ok(memory) = value.try_convert_to::<RubyMemory>() {
56
+ wasmer_namespace.insert(name, memory.upcast().inner().clone());
57
+ } else if let Ok(global) = value.try_convert_to::<RubyGlobal>() {
58
+ wasmer_namespace.insert(name, global.upcast().inner().clone());
59
+ } else if let Ok(table) = value.try_convert_to::<RubyTable>() {
60
+ wasmer_namespace.insert(name, table.upcast().inner().clone());
61
+ } else {
62
+ return Err(to_ruby_err::<TypeError, _>(format!(
63
+ "`ImportObject` cannot register the given type `{:?}` associated to `{:?}`",
64
+ value.ty(),
65
+ name,
66
+ )));
67
+ }
68
+
69
+ Ok(())
70
+ });
71
+ });
72
+
73
+ self.inner
74
+ .register(namespace_name.to_str(), wasmer_namespace);
75
+
76
+ Ok(NilClass::new())
77
+ }
78
+ }
@@ -0,0 +1,45 @@
1
+ use crate::{
2
+ error::{to_ruby_err, RuntimeError},
3
+ exports::Exports,
4
+ import_object::RubyImportObject,
5
+ module::Module,
6
+ prelude::*,
7
+ };
8
+ use rutie::{AnyObject, Object};
9
+
10
+ #[rubyclass(module = "Wasmer")]
11
+ pub struct Instance {
12
+ _inner: wasmer::Instance,
13
+ exports: AnyObject,
14
+ }
15
+
16
+ #[rubymethods]
17
+ impl Instance {
18
+ pub fn new(module: &Module, import_object: &AnyObject) -> RubyResult<AnyObject> {
19
+ let module = module.inner();
20
+
21
+ let instance = if import_object.is_nil() {
22
+ wasmer::Instance::new(&module, &wasmer::imports! {})
23
+ } else {
24
+ wasmer::Instance::new(
25
+ &module,
26
+ import_object
27
+ .try_convert_to::<RubyImportObject>()?
28
+ .upcast()
29
+ .inner(),
30
+ )
31
+ };
32
+
33
+ let instance = instance.map_err(to_ruby_err::<RuntimeError, _>)?;
34
+ let exports = Exports::ruby_new(Exports::new(instance.exports.clone()));
35
+
36
+ Ok(Instance::ruby_new(Instance {
37
+ _inner: instance,
38
+ exports,
39
+ }))
40
+ }
41
+
42
+ pub fn exports(&self) -> RubyResult<AnyObject> {
43
+ Ok(self.exports.clone())
44
+ }
45
+ }
@@ -0,0 +1,307 @@
1
+ #![deny(warnings)]
2
+
3
+ //! # The `wasmer` Ruby package
4
+ //!
5
+ //! A complete and mature WebAssembly runtime for Ruby based on [Wasmer].
6
+ //!
7
+ //! ## Features
8
+ //!
9
+ //! * **Easy to use**: The `wasmer` API mimics the standard
10
+ //! WebAssembly API,
11
+ //! * **Fast**: `wasmer` executes the WebAssembly modules as fast as
12
+ //! possible,
13
+ //! * **Safe**: All calls to WebAssembly will be fast, but more
14
+ //! importantly, complete safe and sandboxed.
15
+ //!
16
+ //! [Wasmer]: https://github.com/wasmerio/wasmer
17
+
18
+ #[cfg(doc)]
19
+ mod doc;
20
+ mod error;
21
+ mod exports;
22
+ mod externals;
23
+ mod import_object;
24
+ mod instance;
25
+ mod memory;
26
+ mod module;
27
+ mod prelude;
28
+ mod store;
29
+ mod types;
30
+ mod values;
31
+ mod wasi;
32
+ mod wat;
33
+
34
+ #[cfg(doc)]
35
+ pub use doc::*;
36
+
37
+ use crate::memory::views::{
38
+ Int16Array, Int32Array, Int8Array, Uint16Array, Uint32Array, Uint8Array,
39
+ };
40
+ use rutie::{Class, Integer, Module, Object, RString};
41
+
42
+ macro_rules! ruby_define {
43
+ (in $module:ident
44
+ $( class ( $( $class_rust_module:path ),+ ) $class_name:ident
45
+ $( include $include_name:ident )*
46
+ {
47
+ $( @const $constant_name:ident = $constant_value:expr; )*
48
+ $( $ruby_definition:ident ($method_rust_name:ident) $method_name:expr; )*
49
+ };
50
+ )*
51
+
52
+ $( function ( $function_rust_name:path ) $function_name:expr; )*
53
+ ) => {
54
+ $(
55
+ {
56
+ let data_class = Class::from_existing("Object");
57
+
58
+ $module
59
+ .define_nested_class(stringify!($class_name), Some(&data_class))
60
+ .define(|this| {
61
+ $(
62
+ #[allow(unused_imports)]
63
+ use $class_rust_module::*;
64
+ )+
65
+
66
+ $(
67
+ this.$ruby_definition($method_name, $method_rust_name);
68
+ )*
69
+
70
+ $(
71
+ this.const_set(stringify!($constant_name), &$constant_value);
72
+ )*
73
+ })
74
+ $( .include( stringify!($include_name) ) )*
75
+ ;
76
+ }
77
+ )*
78
+
79
+ $( $module.define_module_function($function_name, $function_rust_name); )*
80
+ }
81
+ }
82
+
83
+ #[doc(hidden)]
84
+ #[allow(non_snake_case)]
85
+ #[no_mangle]
86
+ pub extern "C" fn init() {
87
+ let mut wasmer_module = Module::from_existing("Wasmer");
88
+
89
+ wasmer_module.const_set("VERSION", &RString::new_utf8(env!("CARGO_PKG_VERSION")));
90
+
91
+ ruby_define! {
92
+ in wasmer_module
93
+ class (store::ruby_store) Store {
94
+ def_self (new) "new";
95
+ };
96
+
97
+ class (module::ruby_module) Module {
98
+ def_self (validate) "validate";
99
+ def_self (new) "new";
100
+ def (set_name) "name=";
101
+ def (get_name) "name";
102
+ def (exports) "exports";
103
+ def (imports) "imports";
104
+ def (custom_sections) "custom_sections";
105
+ def (serialize) "serialize";
106
+ def_self (deserialize) "deserialize";
107
+ };
108
+
109
+ class (instance::ruby_instance) Instance {
110
+ def_self (new) "new";
111
+ def (exports) "exports";
112
+ };
113
+
114
+ class (exports::ruby_exports, exports::ruby_exports_extra) Exports {
115
+ def (respond_to_missing) "respond_to_missing?";
116
+ def (method_missing) "method_missing";
117
+ def (length) "length";
118
+ };
119
+
120
+ class (import_object::ruby_importobject) ImportObject {
121
+ def_self (new) "new";
122
+ def (contains_namespace) "contains_namespace?";
123
+ def (register) "register";
124
+ };
125
+
126
+ class (externals::function::ruby_function, externals::function::ruby_function_extra) Function {
127
+ def_self (new) "new";
128
+ def (call) "call";
129
+ def (r#type) "type";
130
+ };
131
+
132
+ class (externals::memory::ruby_memory) Memory {
133
+ def_self (new) "new";
134
+ def (r#type) "type";
135
+ def (size) "size";
136
+ def (data_size) "data_size";
137
+ def (grow) "grow";
138
+ def (uint8_view) "uint8_view";
139
+ def (int8_view) "int8_view";
140
+ def (uint16_view) "uint16_view";
141
+ def (int16_view) "int16_view";
142
+ def (uint32_view) "uint32_view";
143
+ def (int32_view) "int32_view";
144
+ };
145
+
146
+ class (memory::views::ruby_uint8array) Uint8Array
147
+ include Enumerable
148
+ {
149
+ @const BYTES_PER_ELEMENT = Integer::from(Uint8Array::BYTES_PER_ELEMENT);
150
+ def (length) "length";
151
+ def (set) "[]=";
152
+ def (get) "[]";
153
+ def (each) "each";
154
+ };
155
+
156
+ class (memory::views::ruby_int8array) Int8Array
157
+ include Enumerable
158
+ {
159
+ @const BYTES_PER_ELEMENT = Integer::from(Int8Array::BYTES_PER_ELEMENT);
160
+ def (length) "length";
161
+ def (set) "[]=";
162
+ def (get) "[]";
163
+ def (each) "each";
164
+ };
165
+
166
+ class (memory::views::ruby_uint16array) Uint16Array
167
+ include Enumerable
168
+ {
169
+ @const BYTES_PER_ELEMENT = Integer::from(Uint16Array::BYTES_PER_ELEMENT);
170
+ def (length) "length";
171
+ def (set) "[]=";
172
+ def (get) "[]";
173
+ def (each) "each";
174
+ };
175
+
176
+ class (memory::views::ruby_int16array) Int16Array
177
+ include Enumerable
178
+ {
179
+ @const BYTES_PER_ELEMENT = Integer::from(Int16Array::BYTES_PER_ELEMENT);
180
+ def (length) "length";
181
+ def (set) "[]=";
182
+ def (get) "[]";
183
+ def (each) "each";
184
+ };
185
+
186
+ class (memory::views::ruby_uint32array) Uint32Array
187
+ include Enumerable
188
+ {
189
+ @const BYTES_PER_ELEMENT = Integer::from(Uint32Array::BYTES_PER_ELEMENT);
190
+ def (length) "length";
191
+ def (set) "[]=";
192
+ def (get) "[]";
193
+ def (each) "each";
194
+ };
195
+
196
+ class (memory::views::ruby_int32array) Int32Array
197
+ include Enumerable
198
+ {
199
+ @const BYTES_PER_ELEMENT = Integer::from(Int32Array::BYTES_PER_ELEMENT);
200
+ def (length) "length";
201
+ def (set) "[]=";
202
+ def (get) "[]";
203
+ def (each) "each";
204
+ };
205
+
206
+ class (externals::global::ruby_global) Global {
207
+ def_self (new) "new";
208
+ def (mutable) "mutable?";
209
+ def (get_value) "value";
210
+ def (set_value) "value=";
211
+ def (r#type) "type";
212
+ };
213
+
214
+ class (externals::table::ruby_table) Table {
215
+ def_self (new) "new";
216
+ };
217
+
218
+ class (types) Type {
219
+ @const I32 = Integer::new(1);
220
+ @const I64 = Integer::new(2);
221
+ @const F32 = Integer::new(3);
222
+ @const F64 = Integer::new(4);
223
+ @const V128 = Integer::new(5);
224
+ @const EXTERN_REF = Integer::new(6);
225
+ @const FUNC_REF = Integer::new(7);
226
+ };
227
+
228
+ class (types::ruby_functiontype) FunctionType {
229
+ def_self (new) "new";
230
+ def (params) "params";
231
+ def (results) "results";
232
+ };
233
+
234
+ class (types::ruby_memorytype) MemoryType {
235
+ def_self (new) "new";
236
+ def (minimum) "minimum";
237
+ def (maximum) "maximum";
238
+ def (shared) "shared?";
239
+ };
240
+
241
+ class (types::ruby_globaltype) GlobalType {
242
+ def_self (new) "new";
243
+ def (r#type) "type";
244
+ def (mutable) "mutable?";
245
+ };
246
+
247
+ class (types::ruby_tabletype) TableType {
248
+ def_self (new) "new";
249
+ def (r#type) "type";
250
+ def (minimum) "minimum";
251
+ def (maximum) "maximum";
252
+ };
253
+
254
+ class (types::ruby_exporttype) ExportType {
255
+ def_self (new) "new";
256
+ def (name) "name";
257
+ def (r#type) "type";
258
+ };
259
+
260
+ class (types::ruby_importtype) ImportType {
261
+ def_self (new) "new";
262
+ def (module) "module";
263
+ def (name) "name";
264
+ def (r#type) "type";
265
+ };
266
+
267
+ class (values::ruby_value) Value {
268
+ def_self (i32) "i32";
269
+ def_self (i64) "i64";
270
+ def_self (f32) "f32";
271
+ def_self (f64) "f64";
272
+ };
273
+
274
+ function (wat::wat2wasm) "wat2wasm";
275
+ function (wat::wasm2wat) "wasm2wat";
276
+ };
277
+
278
+ let mut wasmer_wasi_module = wasmer_module.define_nested_module("Wasi");
279
+
280
+ ruby_define! {
281
+ in wasmer_wasi_module
282
+ class (wasi) Version {
283
+ @const LATEST = Integer::new(1);
284
+ @const SNAPSHOT0 = Integer::new(2);
285
+ @const SNAPSHOT1 = Integer::new(3);
286
+ };
287
+
288
+ class (wasi::ruby_statebuilder) StateBuilder {
289
+ def_self (new) "new";
290
+ def (arguments) "arguments";
291
+ def (argument) "argument";
292
+ def (environments) "environments";
293
+ def (environment) "environment";
294
+ def (preopen_directories) "preopen_directories";
295
+ def (preopen_directory) "preopen_directory";
296
+ def (map_directories) "map_directories";
297
+ def (map_directory) "map_directory";
298
+ def (finalize) "finalize";
299
+ };
300
+
301
+ class (wasi::ruby_environment) Environment {
302
+ def (generate_import_object) "generate_import_object";
303
+ };
304
+
305
+ function (wasi::get_version) "get_version";
306
+ };
307
+ }