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,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
+ }