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
@@ -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
- }