wasmer 0.4.0 → 0.5.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 (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
@@ -1,234 +0,0 @@
1
- //! The `ExportedGlobals` WebAssembly class.
2
-
3
- use crate::error::unwrap_or_raise;
4
- use lazy_static::lazy_static;
5
- use rutie::{
6
- class, methods,
7
- rubysys::class,
8
- types::{Argc, Value},
9
- util::str_to_cstring,
10
- wrappable_struct, AnyException, AnyObject, Array, Boolean, Exception, Fixnum, Float, Module,
11
- NilClass, Object, Symbol,
12
- };
13
- use std::rc::Rc;
14
- use wasmer_runtime::{
15
- self as runtime, types::Type as WasmType, Export, Global, Value as WasmValue,
16
- };
17
-
18
- /// The `ExportedGlobals` Ruby class.
19
- pub struct ExportedGlobals {
20
- /// The WebAssembly runtime.
21
- instance: Rc<runtime::Instance>,
22
- }
23
-
24
- impl ExportedGlobals {
25
- /// Create a new instance of the `ExportedGlobals` Ruby class.
26
- pub fn new(instance: Rc<runtime::Instance>) -> Self {
27
- Self { instance }
28
- }
29
-
30
- /// Check that an exported function exists.
31
- pub fn respond_to_missing(&self, method_name: &str) -> bool {
32
- self.instance
33
- .exports()
34
- .any(|(export_name, export)| match export {
35
- Export::Global(_) if export_name == method_name => true,
36
- _ => false,
37
- })
38
- }
39
-
40
- /// Call an exported function on the given WebAssembly instance.
41
- pub fn method_missing(
42
- &self,
43
- method_name: &str,
44
- _arguments: Array,
45
- ) -> Result<ExportedGlobal, AnyException> {
46
- let global = self
47
- .instance
48
- .exports()
49
- .find_map(|(export_name, export)| match export {
50
- Export::Global(global) if export_name == method_name => Some(global),
51
- _ => None,
52
- })
53
- .ok_or_else(|| {
54
- AnyException::new(
55
- "RuntimeError",
56
- Some(&format!("Global `{}` does not exist.", method_name)),
57
- )
58
- })?;
59
-
60
- Ok(ExportedGlobal {
61
- global_name: method_name.to_string(),
62
- global: Rc::new(global),
63
- })
64
- }
65
- }
66
-
67
- wrappable_struct!(
68
- ExportedGlobals,
69
- ExportedGlobalsWrapper,
70
- EXPORTED_GLOBALS_WRAPPER
71
- );
72
-
73
- class!(RubyExportedGlobals);
74
-
75
- #[rustfmt::skip]
76
- methods!(
77
- RubyExportedGlobals,
78
- itself,
79
-
80
- // Glue code to call the `Exportedglobals.respond_to` method.
81
- fn ruby_exported_globals_method_exists(symbol: Symbol, _include_private: Boolean) -> Boolean {
82
- unwrap_or_raise(|| {
83
- let symbol = symbol?;
84
- let exported_globals = itself.get_data(&*EXPORTED_GLOBALS_WRAPPER);
85
-
86
- Ok(Boolean::new(exported_globals.respond_to_missing(symbol.to_str())))
87
- })
88
- }
89
- );
90
-
91
- /// Glue code to call the `ExportedGlobals.method_missing` method.
92
- pub extern "C" fn ruby_exported_globals_method_missing(
93
- argc: Argc,
94
- argv: *const AnyObject,
95
- itself: RubyExportedGlobals,
96
- ) -> RubyExportedGlobal {
97
- unwrap_or_raise(|| {
98
- let arguments = Value::from(0);
99
-
100
- unsafe {
101
- let argv_pointer = argv as *const Value;
102
-
103
- class::rb_scan_args(argc, argv_pointer, str_to_cstring("*").as_ptr(), &arguments)
104
- };
105
-
106
- let mut arguments = Array::from(arguments);
107
- let method_name = unsafe { arguments.shift().to::<Symbol>() };
108
- let method_name = method_name.to_str();
109
-
110
- Ok(Module::from_existing("Wasmer")
111
- .get_nested_class("ExportedGlobal")
112
- .wrap_data(
113
- itself
114
- .get_data(&*EXPORTED_GLOBALS_WRAPPER)
115
- .method_missing(method_name, arguments)?,
116
- &*EXPORTED_GLOBAL_WRAPPER,
117
- ))
118
- })
119
- }
120
-
121
- #[allow(unused)]
122
- /// The `ExportedGlobal` Ruby class.
123
- pub struct ExportedGlobal {
124
- /// The exported global name from the WebAssembly instance.
125
- global_name: String,
126
-
127
- /// The exported global from the WebAssembly instance.
128
- global: Rc<Global>,
129
- }
130
-
131
- impl ExportedGlobal {
132
- pub fn get_value(&self) -> WasmValue {
133
- self.global.get()
134
- }
135
-
136
- pub fn set_value(&self, value: WasmValue) {
137
- self.global.set(value);
138
- }
139
-
140
- pub fn mutable(&self) -> bool {
141
- self.global.descriptor().mutable
142
- }
143
-
144
- fn ty(&self) -> WasmType {
145
- self.global.descriptor().ty
146
- }
147
- }
148
-
149
- wrappable_struct!(
150
- ExportedGlobal,
151
- ExportedGlobalWrapper,
152
- EXPORTED_GLOBAL_WRAPPER
153
- );
154
-
155
- class!(RubyExportedGlobal);
156
-
157
- #[rustfmt::skip]
158
- methods!(
159
- RubyExportedGlobal,
160
- itself,
161
-
162
- // Glue code to call the `ExportedGlobal.get_value` method.
163
- fn ruby_exported_global_get_value() -> AnyObject {
164
- unwrap_or_raise(|| {
165
- let exported_global = itself.get_data(&*EXPORTED_GLOBAL_WRAPPER);
166
-
167
- Ok(match exported_global.get_value() {
168
- WasmValue::I32(result) => Fixnum::new(result as i64).to_any_object(),
169
- WasmValue::I64(result) => Fixnum::new(result).to_any_object(),
170
- WasmValue::F32(result) => Float::new(result as f64).to_any_object(),
171
- WasmValue::F64(result) => Float::new(result).to_any_object(),
172
- WasmValue::V128(_result) => {
173
- return Err(AnyException::new(
174
- "RuntimeError",
175
- Some("Type `V128` isn't supported yet."),
176
- ))
177
- }
178
- })
179
- })
180
- }
181
-
182
- // Glue code to call the `ExportedGlobal.set_value` method.
183
- fn ruby_exported_global_set_value(value: AnyObject) -> NilClass {
184
- unwrap_or_raise(|| {
185
- let exported_global = itself.get_data(&*EXPORTED_GLOBAL_WRAPPER);
186
-
187
- if !exported_global.mutable() {
188
- return Err(AnyException::new(
189
- "RuntimeError",
190
- Some(&format!(
191
- "The global variable `{}` is not mutable, cannot set a new value.",
192
- exported_global.global_name
193
- )),
194
- ));
195
- }
196
-
197
- let value = value?;
198
-
199
- let wasm_type = exported_global.ty();
200
- let wasm_value = match wasm_type {
201
- WasmType::I32 if value.is_fixnum() => {
202
- WasmValue::I32(unsafe { value.to::<Fixnum>().to_i32() })
203
- }
204
- WasmType::I64 if value.is_fixnum() => {
205
- WasmValue::I64(unsafe { value.to::<Fixnum>().to_i64() })
206
- }
207
- WasmType::F32 if value.is_flonum() => {
208
- WasmValue::F32(unsafe { value.to::<Float>().to_f64() as f32 })
209
- }
210
- WasmType::F64 if value.is_flonum() => {
211
- WasmValue::F64(unsafe { value.to::<Float>().to_f64() })
212
- }
213
- _ => {
214
- return Err(AnyException::new(
215
- "TypeError",
216
- Some(&format!(
217
- "Failed to set `{:?}` to the global `{}` (with type `{}`).",
218
- value, exported_global.global_name, wasm_type
219
- )),
220
- ))
221
- }
222
- };
223
-
224
- exported_global.set_value(wasm_value);
225
-
226
- Ok(NilClass::new())
227
- })
228
- }
229
-
230
- // Glue code to call the `ExportedGlobal.mutable` getter.
231
- fn ruby_exported_global_mutable() -> Boolean {
232
- Boolean::new(itself.get_data(&*EXPORTED_GLOBAL_WRAPPER).mutable())
233
- }
234
- );
data/src/instance/mod.rs DELETED
@@ -1,141 +0,0 @@
1
- //! The `Instance` WebAssembly class.
2
-
3
- pub mod exports;
4
- pub mod globals;
5
-
6
- use crate::{
7
- error::unwrap_or_raise,
8
- instance::{
9
- exports::{ExportedFunctions, RubyExportedFunctions, EXPORTED_FUNCTIONS_WRAPPER},
10
- globals::{ExportedGlobals, RubyExportedGlobals, EXPORTED_GLOBALS_WRAPPER},
11
- },
12
- memory::{Memory, RubyMemory, MEMORY_WRAPPER},
13
- };
14
- use lazy_static::lazy_static;
15
- use rutie::{
16
- class, methods, wrappable_struct, AnyException, AnyObject, Exception, Module, NilClass, Object,
17
- RString,
18
- };
19
- use std::rc::Rc;
20
- use wasmer_runtime::{self as runtime, imports, Export};
21
-
22
- /// The `Instance` Ruby class.
23
- pub struct Instance {
24
- /// The WebAssembly instance.
25
- instance: Rc<runtime::Instance>,
26
- }
27
-
28
- impl Instance {
29
- /// Create a new instance of the `Instance` Ruby class.
30
- /// The constructor receives bytes from a string.
31
- pub fn new(bytes: &[u8]) -> Result<Self, AnyException> {
32
- let import_object = imports! {};
33
-
34
- Ok(Self {
35
- instance: Rc::new(runtime::instantiate(bytes, &import_object).map_err(|e| {
36
- AnyException::new(
37
- "RuntimeError",
38
- Some(&format!("Failed to instantiate the module:\n {}", e)),
39
- )
40
- })?),
41
- })
42
- }
43
- }
44
-
45
- wrappable_struct!(Instance, InstanceWrapper, INSTANCE_WRAPPER);
46
-
47
- class!(RubyInstance);
48
-
49
- #[rustfmt::skip]
50
- methods!(
51
- RubyInstance,
52
- _itself,
53
-
54
- // Glue code to call the `Instance.new` method.
55
- fn ruby_instance_new(bytes: RString) -> AnyObject {
56
- unwrap_or_raise(|| {
57
- let instance = Instance::new(
58
- bytes
59
- .map_err(|_| {
60
- AnyException::new(
61
- "ArgumentError",
62
- Some("WebAssembly module must be represented by Ruby bytes only."),
63
- )
64
- })?
65
- .to_bytes_unchecked(),
66
- )?;
67
- let exported_functions = ExportedFunctions::new(instance.instance.clone());
68
- let exported_globals = ExportedGlobals::new(instance.instance.clone());
69
- let exported_memory =
70
- instance
71
- .instance
72
- .exports()
73
- .find_map(|(_, export)| match export {
74
- Export::Memory(memory) => Some(Memory::new(Rc::new(memory))),
75
- _ => None,
76
- });
77
-
78
- let wasmer_module = Module::from_existing("Wasmer");
79
-
80
- let mut ruby_instance: AnyObject = wasmer_module
81
- .get_nested_class("Instance")
82
- .wrap_data(instance, &*INSTANCE_WRAPPER);
83
-
84
- let ruby_exported_functions: RubyExportedFunctions = wasmer_module
85
- .get_nested_class("ExportedFunctions")
86
- .wrap_data(exported_functions, &*EXPORTED_FUNCTIONS_WRAPPER);
87
-
88
- let ruby_exported_globals: RubyExportedGlobals = wasmer_module
89
- .get_nested_class("ExportedGlobals")
90
- .wrap_data(exported_globals, &*EXPORTED_GLOBALS_WRAPPER);
91
-
92
- ruby_instance.instance_variable_set("@exports", ruby_exported_functions);
93
- ruby_instance.instance_variable_set("@globals", ruby_exported_globals);
94
-
95
- if let Some(exported_memory) = exported_memory {
96
- let ruby_exported_memory: RubyMemory = wasmer_module
97
- .get_nested_class("Memory")
98
- .wrap_data(exported_memory, &*MEMORY_WRAPPER);
99
- ruby_instance.instance_variable_set("@memory", ruby_exported_memory);
100
- } else {
101
- ruby_instance.instance_variable_set("@memory", NilClass::new());
102
- }
103
-
104
- Ok(ruby_instance)
105
- })
106
- }
107
-
108
- // Glue code to call the `Instance.exports` getter method.
109
- fn ruby_instance_exported_functions() -> RubyExportedFunctions {
110
- unsafe {
111
- _itself
112
- .instance_variable_get("@exports")
113
- .to::<RubyExportedFunctions>()
114
- }
115
- }
116
-
117
- // Glue code to call the `Instance.globals` getter method.
118
- fn ruby_instance_exported_globals() -> RubyExportedGlobals {
119
- unsafe {
120
- _itself
121
- .instance_variable_get("@globals")
122
- .to::<RubyExportedGlobals>()
123
- }
124
- }
125
-
126
- // Glue code to call the `Instance.memory` getter method.
127
- fn ruby_instance_memory() -> RubyMemory {
128
- unwrap_or_raise(|| {
129
- let memory = _itself.instance_variable_get("@memory");
130
-
131
- if !memory.is_nil() {
132
- Ok(unsafe { memory.to::<RubyMemory>() })
133
- } else {
134
- Err(AnyException::new(
135
- "RuntimeError",
136
- Some("The WebAssembly module has no exported memory."),
137
- ))
138
- }
139
- })
140
- }
141
- );
data/src/lib.rs DELETED
@@ -1,162 +0,0 @@
1
- #![deny(warnings)]
2
-
3
- use rutie::{Class, Module, Object};
4
-
5
- pub mod error;
6
- pub mod instance;
7
- pub mod memory;
8
- pub mod module;
9
-
10
- #[allow(non_snake_case)]
11
- #[no_mangle]
12
- pub extern "C" fn Init_wasmer() {
13
- let mut wasmer_module = Module::from_existing("Wasmer");
14
-
15
- let instance_data_class = Class::from_existing("Object");
16
-
17
- // Declare the `Instance` Ruby class.
18
- wasmer_module
19
- .define_nested_class("Instance", Some(&instance_data_class))
20
- .define(|itself| {
21
- // Declare the `self.new` method.
22
- itself.def_self("new", instance::ruby_instance_new);
23
-
24
- // Declare the `exports` getter method.
25
- itself.def("exports", instance::ruby_instance_exported_functions);
26
-
27
- // Declare the `globals` getter method.
28
- itself.def("globals", instance::ruby_instance_exported_globals);
29
-
30
- // Declare the `memory` getter method.
31
- itself.def("memory", instance::ruby_instance_memory);
32
- });
33
-
34
- let exported_functions_data_class = Class::from_existing("Object");
35
-
36
- // Declare the `ExportedFunctions` Ruby class.
37
- wasmer_module
38
- .define_nested_class("ExportedFunctions", Some(&exported_functions_data_class))
39
- .define(|itself| {
40
- // Declare the `respond_to_missing?` method.
41
- itself.def(
42
- "respond_to_missing?",
43
- instance::exports::ruby_exported_functions_method_exists,
44
- );
45
-
46
- // Declare the `method_missing` method.
47
- itself.def(
48
- "method_missing",
49
- instance::exports::ruby_exported_functions_method_missing,
50
- );
51
- });
52
-
53
- let exported_globals_data_class = Class::from_existing("Object");
54
-
55
- // Declare the `ExportedGlobals` Ruby class.
56
- wasmer_module
57
- .define_nested_class("ExportedGlobals", Some(&exported_globals_data_class))
58
- .define(|itself| {
59
- // Declare the `respond_to_missing?` method.
60
- itself.def(
61
- "respond_to_missing?",
62
- instance::globals::ruby_exported_globals_method_exists,
63
- );
64
-
65
- // Declare the `method_missing` method.
66
- itself.def(
67
- "method_missing",
68
- instance::globals::ruby_exported_globals_method_missing,
69
- );
70
- });
71
-
72
- let exported_global_data_class = Class::from_existing("Object");
73
-
74
- // Declare the `ExportedGlobal` Ruby class.
75
- wasmer_module
76
- .define_nested_class("ExportedGlobal", Some(&exported_global_data_class))
77
- .define(|itself| {
78
- // Declare the `value` getter.
79
- itself.def("value", instance::globals::ruby_exported_global_get_value);
80
-
81
- // Declare the `value` setter.
82
- itself.def("value=", instance::globals::ruby_exported_global_set_value);
83
-
84
- // Declare the `mutable` getter.
85
- itself.def("mutable", instance::globals::ruby_exported_global_mutable);
86
- });
87
-
88
- let module_data_class = Class::from_existing("Object");
89
-
90
- // Declare the `Module` Ruby class.
91
- wasmer_module
92
- .define_nested_class("Module", Some(&module_data_class))
93
- .define(|itself| {
94
- // Declare the `self.validate` method.
95
- itself.def_self("validate", module::ruby_module_validate);
96
- });
97
-
98
- let memory_data_class = Class::from_existing("Object");
99
-
100
- // Declare the `Memory` Ruby class.
101
- wasmer_module
102
- .define_nested_class("Memory", Some(&memory_data_class))
103
- .define(|itself| {
104
- // Declare the `grow` method.
105
- itself.def("grow", memory::ruby_memory_grow);
106
-
107
- // Declare the `view` method.
108
- itself.def("uint8_view", memory::ruby_memory_uint8array);
109
-
110
- // Declare the `view` method.
111
- itself.def("int8_view", memory::ruby_memory_int8array);
112
-
113
- // Declare the `view` method.
114
- itself.def("uint16_view", memory::ruby_memory_uint16array);
115
-
116
- // Declare the `view` method.
117
- itself.def("int16_view", memory::ruby_memory_int16array);
118
-
119
- // Declare the `view` method.
120
- itself.def("uint32_view", memory::ruby_memory_uint32array);
121
-
122
- // Declare the `view` method.
123
- itself.def("int32_view", memory::ruby_memory_int32array);
124
- });
125
-
126
- macro_rules! memory_view {
127
- ($class_name:ident in $mod_name:ident) => {
128
- let uint8array_data_class = Class::from_existing("Object");
129
-
130
- // Declare the `MemoryView` Ruby class.
131
- wasmer_module
132
- .define_nested_class(stringify!($class_name), Some(&uint8array_data_class))
133
- .define(|itself| {
134
- // Declare the `bytes_per_element` getter method.
135
- itself.def(
136
- "bytes_per_element",
137
- memory::view::$mod_name::ruby_memory_view_bytes_per_element,
138
- );
139
-
140
- // Declare the `length` method.
141
- itself.def("length", memory::view::$mod_name::ruby_memory_view_length);
142
-
143
- // Declare the `[]=` (set) method.
144
- itself.def("[]=", memory::view::$mod_name::ruby_memory_view_set);
145
-
146
- // Declare the `[]` (get) method.
147
- itself.def("[]", memory::view::$mod_name::ruby_memory_view_get);
148
-
149
- // Declare the `each` method.
150
- itself.def("each", memory::view::$mod_name::ruby_memory_view_each);
151
- })
152
- .include("Enumerable");
153
- };
154
- }
155
-
156
- memory_view!(Uint8Array in uint8array);
157
- memory_view!(Int8Array in int8array);
158
- memory_view!(Uint16Array in uint16array);
159
- memory_view!(Int16Array in int16array);
160
- memory_view!(Uint32Array in uint32array);
161
- memory_view!(Int32Array in int32array);
162
- }